📄 pem_lib.c
字号:
unsigned char key[EVP_MAX_KEY_LENGTH]; char buf[PEM_BUFSIZE]; len= *plen; if (cipher->cipher == NULL) return(1); if (callback == NULL) klen=PEM_def_callback(buf,PEM_BUFSIZE,0,u); else klen=callback(buf,PEM_BUFSIZE,0,u); if (klen <= 0) { PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_PASSWORD_READ); return(0); }#ifdef CHARSET_EBCDIC /* Convert the pass phrase from EBCDIC */ ebcdic2ascii(buf, buf, klen);#endif EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]), (unsigned char *)buf,klen,1,key,NULL); j=(int)len; EVP_CIPHER_CTX_init(&ctx); EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0])); EVP_DecryptUpdate(&ctx,data,&i,data,j); o=EVP_DecryptFinal_ex(&ctx,&(data[i]),&j); EVP_CIPHER_CTX_cleanup(&ctx); OPENSSL_cleanse((char *)buf,sizeof(buf)); OPENSSL_cleanse((char *)key,sizeof(key)); j+=i; if (!o) { PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_DECRYPT); return(0); } *plen=j; return(1); }int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) { int o; const EVP_CIPHER *enc=NULL; char *p,c; char **header_pp = &header; cipher->cipher=NULL; if ((header == NULL) || (*header == '\0') || (*header == '\n')) return(1); if (strncmp(header,"Proc-Type: ",11) != 0) { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_PROC_TYPE); return(0); } header+=11; if (*header != '4') return(0); header++; if (*header != ',') return(0); header++; if (strncmp(header,"ENCRYPTED",9) != 0) { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_ENCRYPTED); return(0); } for (; (*header != '\n') && (*header != '\0'); header++) ; if (*header == '\0') { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_SHORT_HEADER); return(0); } header++; if (strncmp(header,"DEK-Info: ",10) != 0) { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_DEK_INFO); return(0); } header+=10; p=header; for (;;) { c= *header;#ifndef CHARSET_EBCDIC if (!( ((c >= 'A') && (c <= 'Z')) || (c == '-') || ((c >= '0') && (c <= '9')))) break;#else if (!( isupper(c) || (c == '-') || isdigit(c))) break;#endif header++; } *header='\0'; o=OBJ_sn2nid(p); cipher->cipher=enc=EVP_get_cipherbyname(p); *header=c; header++; if (enc == NULL) { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_UNSUPPORTED_ENCRYPTION); return(0); } if (!load_iv(header_pp,&(cipher->iv[0]),enc->iv_len)) return(0); return(1); }static int load_iv(char **fromp, unsigned char *to, int num) { int v,i; char *from; from= *fromp; for (i=0; i<num; i++) to[i]=0; num*=2; for (i=0; i<num; i++) { if ((*from >= '0') && (*from <= '9')) v= *from-'0'; else if ((*from >= 'A') && (*from <= 'F')) v= *from-'A'+10; else if ((*from >= 'a') && (*from <= 'f')) v= *from-'a'+10; else { PEMerr(PEM_F_LOAD_IV,PEM_R_BAD_IV_CHARS); return(0); } from++; to[i/2]|=v<<(long)((!(i&1))*4); } *fromp=from; return(1); }#ifndef OPENSSL_NO_FP_APIint PEM_write(FILE *fp, char *name, char *header, unsigned char *data, long len) { BIO *b; int ret; if ((b=BIO_new(BIO_s_file())) == NULL) { PEMerr(PEM_F_PEM_WRITE,ERR_R_BUF_LIB); return(0); } BIO_set_fp(b,fp,BIO_NOCLOSE); ret=PEM_write_bio(b, name, header, data,len); BIO_free(b); return(ret); }#endifint PEM_write_bio(BIO *bp, const char *name, char *header, unsigned char *data, long len) { int nlen,n,i,j,outl; unsigned char *buf = NULL; EVP_ENCODE_CTX ctx; int reason=ERR_R_BUF_LIB; EVP_EncodeInit(&ctx); nlen=strlen(name); if ( (BIO_write(bp,"-----BEGIN ",11) != 11) || (BIO_write(bp,name,nlen) != nlen) || (BIO_write(bp,"-----\n",6) != 6)) goto err; i=strlen(header); if (i > 0) { if ( (BIO_write(bp,header,i) != i) || (BIO_write(bp,"\n",1) != 1)) goto err; } buf = OPENSSL_malloc(PEM_BUFSIZE*8); if (buf == NULL) { reason=ERR_R_MALLOC_FAILURE; goto err; } i=j=0; while (len > 0) { n=(int)((len>(PEM_BUFSIZE*5))?(PEM_BUFSIZE*5):len); EVP_EncodeUpdate(&ctx,buf,&outl,&(data[j]),n); if ((outl) && (BIO_write(bp,(char *)buf,outl) != outl)) goto err; i+=outl; len-=n; j+=n; } EVP_EncodeFinal(&ctx,buf,&outl); if ((outl > 0) && (BIO_write(bp,(char *)buf,outl) != outl)) goto err; OPENSSL_cleanse(buf, PEM_BUFSIZE*8); OPENSSL_free(buf); buf = NULL; if ( (BIO_write(bp,"-----END ",9) != 9) || (BIO_write(bp,name,nlen) != nlen) || (BIO_write(bp,"-----\n",6) != 6)) goto err; return(i+outl);err: if (buf) { OPENSSL_cleanse(buf, PEM_BUFSIZE*8); OPENSSL_free(buf); } PEMerr(PEM_F_PEM_WRITE_BIO,reason); return(0); }#ifndef OPENSSL_NO_FP_APIint PEM_read(FILE *fp, char **name, char **header, unsigned char **data, long *len) { BIO *b; int ret; if ((b=BIO_new(BIO_s_file())) == NULL) { PEMerr(PEM_F_PEM_READ,ERR_R_BUF_LIB); return(0); } BIO_set_fp(b,fp,BIO_NOCLOSE); ret=PEM_read_bio(b, name, header, data,len); BIO_free(b); return(ret); }#endifint PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, long *len) { EVP_ENCODE_CTX ctx; int end=0,i,k,bl=0,hl=0,nohead=0; char buf[256]; BUF_MEM *nameB; BUF_MEM *headerB; BUF_MEM *dataB,*tmpB; nameB=BUF_MEM_new(); headerB=BUF_MEM_new(); dataB=BUF_MEM_new(); if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) { BUF_MEM_free(nameB); BUF_MEM_free(headerB); BUF_MEM_free(dataB); PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); return(0); } buf[254]='\0'; for (;;) { i=BIO_gets(bp,buf,254); if (i <= 0) { PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE); goto err; } while ((i >= 0) && (buf[i] <= ' ')) i--; buf[++i]='\n'; buf[++i]='\0'; if (strncmp(buf,"-----BEGIN ",11) == 0) { i=strlen(&(buf[11])); if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0) continue; if (!BUF_MEM_grow(nameB,i+9)) { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } memcpy(nameB->data,&(buf[11]),i-6); nameB->data[i-6]='\0'; break; } } hl=0; if (!BUF_MEM_grow(headerB,256)) { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } headerB->data[0]='\0'; for (;;) { i=BIO_gets(bp,buf,254); if (i <= 0) break; while ((i >= 0) && (buf[i] <= ' ')) i--; buf[++i]='\n'; buf[++i]='\0'; if (buf[0] == '\n') break; if (!BUF_MEM_grow(headerB,hl+i+9)) { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } if (strncmp(buf,"-----END ",9) == 0) { nohead=1; break; } memcpy(&(headerB->data[hl]),buf,i); headerB->data[hl+i]='\0'; hl+=i; } bl=0; if (!BUF_MEM_grow(dataB,1024)) { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } dataB->data[0]='\0'; if (!nohead) { for (;;) { i=BIO_gets(bp,buf,254); if (i <= 0) break; while ((i >= 0) && (buf[i] <= ' ')) i--; buf[++i]='\n'; buf[++i]='\0'; if (i != 65) end=1; if (strncmp(buf,"-----END ",9) == 0) break; if (i > 65) break; if (!BUF_MEM_grow_clean(dataB,i+bl+9)) { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } memcpy(&(dataB->data[bl]),buf,i); dataB->data[bl+i]='\0'; bl+=i; if (end) { buf[0]='\0'; i=BIO_gets(bp,buf,254); if (i <= 0) break; while ((i >= 0) && (buf[i] <= ' ')) i--; buf[++i]='\n'; buf[++i]='\0'; break; } } } else { tmpB=headerB; headerB=dataB; dataB=tmpB; bl=hl; } i=strlen(nameB->data); if ( (strncmp(buf,"-----END ",9) != 0) || (strncmp(nameB->data,&(buf[9]),i) != 0) || (strncmp(&(buf[9+i]),"-----\n",6) != 0)) { PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_END_LINE); goto err; } EVP_DecodeInit(&ctx); i=EVP_DecodeUpdate(&ctx, (unsigned char *)dataB->data,&bl, (unsigned char *)dataB->data,bl); if (i < 0) { PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE); goto err; } i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k); if (i < 0) { PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE); goto err; } bl+=k; if (bl == 0) goto err; *name=nameB->data; *header=headerB->data; *data=(unsigned char *)dataB->data; *len=bl; OPENSSL_free(nameB); OPENSSL_free(headerB); OPENSSL_free(dataB); return(1);err: BUF_MEM_free(nameB); BUF_MEM_free(headerB); BUF_MEM_free(dataB); return(0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -