| OLD | NEW |
| 1 /* crypto/pem/pem_lib.c */ | 1 /* crypto/pem/pem_lib.c */ |
| 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
| 6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
| 7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
| 8 * | 8 * |
| 9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
| 10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 51 * SUCH DAMAGE. | 51 * SUCH DAMAGE. |
| 52 * | 52 * |
| 53 * The licence and distribution terms for any publically available version or | 53 * The licence and distribution terms for any publically available version or |
| 54 * derivative of this code cannot be changed. i.e. this code cannot simply be | 54 * derivative of this code cannot be changed. i.e. this code cannot simply be |
| 55 * copied and put under another distribution licence | 55 * copied and put under another distribution licence |
| 56 * [including the GNU Public Licence.] | 56 * [including the GNU Public Licence.] |
| 57 */ | 57 */ |
| 58 | 58 |
| 59 #include <stdio.h> | 59 #include <stdio.h> |
| 60 #include <ctype.h> |
| 60 #include "cryptlib.h" | 61 #include "cryptlib.h" |
| 61 #include <openssl/buffer.h> | 62 #include <openssl/buffer.h> |
| 62 #include <openssl/objects.h> | 63 #include <openssl/objects.h> |
| 63 #include <openssl/evp.h> | 64 #include <openssl/evp.h> |
| 64 #include <openssl/rand.h> | 65 #include <openssl/rand.h> |
| 65 #include <openssl/x509.h> | 66 #include <openssl/x509.h> |
| 66 #include <openssl/pem.h> | 67 #include <openssl/pem.h> |
| 67 #include <openssl/pkcs12.h> | 68 #include <openssl/pkcs12.h> |
| 69 #include "asn1_locl.h" |
| 68 #ifndef OPENSSL_NO_DES | 70 #ifndef OPENSSL_NO_DES |
| 69 #include <openssl/des.h> | 71 #include <openssl/des.h> |
| 70 #endif | 72 #endif |
| 73 #ifndef OPENSSL_NO_ENGINE |
| 74 #include <openssl/engine.h> |
| 75 #endif |
| 71 | 76 |
| 72 const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT; | 77 const char PEM_version[]="PEM" OPENSSL_VERSION_PTEXT; |
| 73 | 78 |
| 74 #define MIN_LENGTH 4 | 79 #define MIN_LENGTH 4 |
| 75 | 80 |
| 76 static int load_iv(char **fromp,unsigned char *to, int num); | 81 static int load_iv(char **fromp,unsigned char *to, int num); |
| 77 static int check_pem(const char *nm, const char *name); | 82 static int check_pem(const char *nm, const char *name); |
| 83 int pem_check_suffix(const char *pem_str, const char *suffix); |
| 78 | 84 |
| 79 int PEM_def_callback(char *buf, int num, int w, void *key) | 85 int PEM_def_callback(char *buf, int num, int w, void *key) |
| 80 { | 86 { |
| 81 #ifdef OPENSSL_NO_FP_API | 87 #ifdef OPENSSL_NO_FP_API |
| 82 /* We should not ever call the default callback routine from | 88 /* We should not ever call the default callback routine from |
| 83 * windows. */ | 89 * windows. */ |
| 84 PEMerr(PEM_F_PEM_DEF_CALLBACK,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); | 90 PEMerr(PEM_F_PEM_DEF_CALLBACK,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); |
| 85 return(-1); | 91 return(-1); |
| 86 #else | 92 #else |
| 87 int i,j; | 93 int i,j; |
| 88 const char *prompt; | 94 const char *prompt; |
| 89 if(key) { | 95 if(key) { |
| 90 i=strlen(key); | 96 i=strlen(key); |
| 91 i=(i > num)?num:i; | 97 i=(i > num)?num:i; |
| 92 memcpy(buf,key,i); | 98 memcpy(buf,key,i); |
| 93 return(i); | 99 return(i); |
| 94 } | 100 } |
| 95 | 101 |
| 96 prompt=EVP_get_pw_prompt(); | 102 prompt=EVP_get_pw_prompt(); |
| 97 if (prompt == NULL) | 103 if (prompt == NULL) |
| 98 prompt="Enter PEM pass phrase:"; | 104 prompt="Enter PEM pass phrase:"; |
| 99 | 105 |
| 100 for (;;) | 106 for (;;) |
| 101 { | 107 { |
| 102 » » i=EVP_read_pw_string(buf,num,prompt,w); | 108 » » i=EVP_read_pw_string_min(buf,MIN_LENGTH,num,prompt,w); |
| 103 if (i != 0) | 109 if (i != 0) |
| 104 { | 110 { |
| 105 PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PAS
SWORD); | 111 PEMerr(PEM_F_PEM_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PAS
SWORD); |
| 106 memset(buf,0,(unsigned int)num); | 112 memset(buf,0,(unsigned int)num); |
| 107 return(-1); | 113 return(-1); |
| 108 } | 114 } |
| 109 j=strlen(buf); | 115 j=strlen(buf); |
| 110 if (j < MIN_LENGTH) | 116 if (j < MIN_LENGTH) |
| 111 { | 117 { |
| 112 fprintf(stderr,"phrase is too short, needs to be at leas
t %d chars\n",MIN_LENGTH); | 118 fprintf(stderr,"phrase is too short, needs to be at leas
t %d chars\n",MIN_LENGTH); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 } | 182 } |
| 177 #endif | 183 #endif |
| 178 | 184 |
| 179 static int check_pem(const char *nm, const char *name) | 185 static int check_pem(const char *nm, const char *name) |
| 180 { | 186 { |
| 181 /* Normal matching nm and name */ | 187 /* Normal matching nm and name */ |
| 182 if (!strcmp(nm,name)) return 1; | 188 if (!strcmp(nm,name)) return 1; |
| 183 | 189 |
| 184 /* Make PEM_STRING_EVP_PKEY match any private key */ | 190 /* Make PEM_STRING_EVP_PKEY match any private key */ |
| 185 | 191 |
| 186 » if(!strcmp(nm,PEM_STRING_PKCS8) && | 192 » if(!strcmp(name,PEM_STRING_EVP_PKEY)) |
| 187 » » !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; | 193 » » { |
| 194 » » int slen; |
| 195 » » const EVP_PKEY_ASN1_METHOD *ameth; |
| 196 » » if(!strcmp(nm,PEM_STRING_PKCS8)) |
| 197 » » » return 1; |
| 198 » » if(!strcmp(nm,PEM_STRING_PKCS8INF)) |
| 199 » » » return 1; |
| 200 » » slen = pem_check_suffix(nm, "PRIVATE KEY"); |
| 201 » » if (slen > 0) |
| 202 » » » { |
| 203 » » » /* NB: ENGINE implementations wont contain |
| 204 » » » * a deprecated old private key decode function |
| 205 » » » * so don't look for them. |
| 206 » » » */ |
| 207 » » » ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); |
| 208 » » » if (ameth && ameth->old_priv_decode) |
| 209 » » » » return 1; |
| 210 » » » } |
| 211 » » return 0; |
| 212 » » } |
| 188 | 213 |
| 189 » if(!strcmp(nm,PEM_STRING_PKCS8INF) && | 214 » if(!strcmp(name,PEM_STRING_PARAMETERS)) |
| 190 » » !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; | 215 » » { |
| 216 » » int slen; |
| 217 » » const EVP_PKEY_ASN1_METHOD *ameth; |
| 218 » » slen = pem_check_suffix(nm, "PARAMETERS"); |
| 219 » » if (slen > 0) |
| 220 » » » { |
| 221 » » » ENGINE *e; |
| 222 » » » ameth = EVP_PKEY_asn1_find_str(&e, nm, slen); |
| 223 » » » if (ameth) |
| 224 » » » » { |
| 225 » » » » int r; |
| 226 » » » » if (ameth->param_decode) |
| 227 » » » » » r = 1; |
| 228 » » » » else |
| 229 » » » » » r = 0; |
| 230 #ifndef OPENSSL_NO_ENGINE |
| 231 » » » » if (e) |
| 232 » » » » » ENGINE_finish(e); |
| 233 #endif |
| 234 » » » » return r; |
| 235 » » » » } |
| 236 » » » } |
| 237 » » return 0; |
| 238 » » } |
| 191 | 239 |
| 192 if(!strcmp(nm,PEM_STRING_RSA) && | |
| 193 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; | |
| 194 | |
| 195 if(!strcmp(nm,PEM_STRING_DSA) && | |
| 196 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; | |
| 197 | |
| 198 if(!strcmp(nm,PEM_STRING_ECPRIVATEKEY) && | |
| 199 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; | |
| 200 /* Permit older strings */ | 240 /* Permit older strings */ |
| 201 | 241 |
| 202 if(!strcmp(nm,PEM_STRING_X509_OLD) && | 242 if(!strcmp(nm,PEM_STRING_X509_OLD) && |
| 203 !strcmp(name,PEM_STRING_X509)) return 1; | 243 !strcmp(name,PEM_STRING_X509)) return 1; |
| 204 | 244 |
| 205 if(!strcmp(nm,PEM_STRING_X509_REQ_OLD) && | 245 if(!strcmp(nm,PEM_STRING_X509_REQ_OLD) && |
| 206 !strcmp(name,PEM_STRING_X509_REQ)) return 1; | 246 !strcmp(name,PEM_STRING_X509_REQ)) return 1; |
| 207 | 247 |
| 208 /* Allow normal certs to be read as trusted certs */ | 248 /* Allow normal certs to be read as trusted certs */ |
| 209 if(!strcmp(nm,PEM_STRING_X509) && | 249 if(!strcmp(nm,PEM_STRING_X509) && |
| 210 !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1; | 250 !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1; |
| 211 | 251 |
| 212 if(!strcmp(nm,PEM_STRING_X509_OLD) && | 252 if(!strcmp(nm,PEM_STRING_X509_OLD) && |
| 213 !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1; | 253 !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1; |
| 214 | 254 |
| 215 /* Some CAs use PKCS#7 with CERTIFICATE headers */ | 255 /* Some CAs use PKCS#7 with CERTIFICATE headers */ |
| 216 if(!strcmp(nm, PEM_STRING_X509) && | 256 if(!strcmp(nm, PEM_STRING_X509) && |
| 217 !strcmp(name, PEM_STRING_PKCS7)) return 1; | 257 !strcmp(name, PEM_STRING_PKCS7)) return 1; |
| 218 | 258 |
| 219 if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && | 259 if(!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && |
| 220 !strcmp(name, PEM_STRING_PKCS7)) return 1; | 260 !strcmp(name, PEM_STRING_PKCS7)) return 1; |
| 221 | 261 |
| 262 #ifndef OPENSSL_NO_CMS |
| 263 if(!strcmp(nm, PEM_STRING_X509) && |
| 264 !strcmp(name, PEM_STRING_CMS)) return 1; |
| 265 /* Allow CMS to be read from PKCS#7 headers */ |
| 266 if(!strcmp(nm, PEM_STRING_PKCS7) && |
| 267 !strcmp(name, PEM_STRING_CMS)) return 1; |
| 268 #endif |
| 269 |
| 222 return 0; | 270 return 0; |
| 223 } | 271 } |
| 224 | 272 |
| 225 int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char
*name, BIO *bp, | 273 int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char
*name, BIO *bp, |
| 226 pem_password_cb *cb, void *u) | 274 pem_password_cb *cb, void *u) |
| 227 { | 275 { |
| 228 EVP_CIPHER_INFO cipher; | 276 EVP_CIPHER_INFO cipher; |
| 229 char *nm=NULL,*header=NULL; | 277 char *nm=NULL,*header=NULL; |
| 230 unsigned char *data=NULL; | 278 unsigned char *data=NULL; |
| 231 long len; | 279 long len; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 257 | 305 |
| 258 err: | 306 err: |
| 259 if (!ret || !pnm) OPENSSL_free(nm); | 307 if (!ret || !pnm) OPENSSL_free(nm); |
| 260 OPENSSL_free(header); | 308 OPENSSL_free(header); |
| 261 if (!ret) OPENSSL_free(data); | 309 if (!ret) OPENSSL_free(data); |
| 262 return ret; | 310 return ret; |
| 263 } | 311 } |
| 264 | 312 |
| 265 #ifndef OPENSSL_NO_FP_API | 313 #ifndef OPENSSL_NO_FP_API |
| 266 int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, | 314 int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, |
| 267 » » char *x, const EVP_CIPHER *enc, unsigned char *kstr, | 315 » » void *x, const EVP_CIPHER *enc, unsigned char *kstr, |
| 268 int klen, pem_password_cb *callback, void *u) | 316 int klen, pem_password_cb *callback, void *u) |
| 269 { | 317 { |
| 270 BIO *b; | 318 BIO *b; |
| 271 int ret; | 319 int ret; |
| 272 | 320 |
| 273 if ((b=BIO_new(BIO_s_file())) == NULL) | 321 if ((b=BIO_new(BIO_s_file())) == NULL) |
| 274 { | 322 { |
| 275 PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB); | 323 PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB); |
| 276 return(0); | 324 return(0); |
| 277 } | 325 } |
| 278 BIO_set_fp(b,fp,BIO_NOCLOSE); | 326 BIO_set_fp(b,fp,BIO_NOCLOSE); |
| 279 ret=PEM_ASN1_write_bio(i2d,name,b,x,enc,kstr,klen,callback,u); | 327 ret=PEM_ASN1_write_bio(i2d,name,b,x,enc,kstr,klen,callback,u); |
| 280 BIO_free(b); | 328 BIO_free(b); |
| 281 return(ret); | 329 return(ret); |
| 282 } | 330 } |
| 283 #endif | 331 #endif |
| 284 | 332 |
| 285 int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, | 333 int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, |
| 286 » » char *x, const EVP_CIPHER *enc, unsigned char *kstr, | 334 » » void *x, const EVP_CIPHER *enc, unsigned char *kstr, |
| 287 int klen, pem_password_cb *callback, void *u) | 335 int klen, pem_password_cb *callback, void *u) |
| 288 { | 336 { |
| 289 EVP_CIPHER_CTX ctx; | 337 EVP_CIPHER_CTX ctx; |
| 290 int dsize=0,i,j,ret=0; | 338 int dsize=0,i,j,ret=0; |
| 291 unsigned char *p,*data=NULL; | 339 unsigned char *p,*data=NULL; |
| 292 const char *objstr=NULL; | 340 const char *objstr=NULL; |
| 293 char buf[PEM_BUFSIZE]; | 341 char buf[PEM_BUFSIZE]; |
| 294 unsigned char key[EVP_MAX_KEY_LENGTH]; | 342 unsigned char key[EVP_MAX_KEY_LENGTH]; |
| 295 unsigned char iv[EVP_MAX_IV_LENGTH]; | 343 unsigned char iv[EVP_MAX_IV_LENGTH]; |
| 296 | 344 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 { | 475 { |
| 428 PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_DECRYPT); | 476 PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_DECRYPT); |
| 429 return(0); | 477 return(0); |
| 430 } | 478 } |
| 431 *plen=j; | 479 *plen=j; |
| 432 return(1); | 480 return(1); |
| 433 } | 481 } |
| 434 | 482 |
| 435 int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) | 483 int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) |
| 436 { | 484 { |
| 437 int o; | |
| 438 const EVP_CIPHER *enc=NULL; | 485 const EVP_CIPHER *enc=NULL; |
| 439 char *p,c; | 486 char *p,c; |
| 440 char **header_pp = &header; | 487 char **header_pp = &header; |
| 441 | 488 |
| 442 cipher->cipher=NULL; | 489 cipher->cipher=NULL; |
| 443 if ((header == NULL) || (*header == '\0') || (*header == '\n')) | 490 if ((header == NULL) || (*header == '\0') || (*header == '\n')) |
| 444 return(1); | 491 return(1); |
| 445 if (strncmp(header,"Proc-Type: ",11) != 0) | 492 if (strncmp(header,"Proc-Type: ",11) != 0) |
| 446 { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_PROC_TYPE); ret
urn(0); } | 493 { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_PROC_TYPE); ret
urn(0); } |
| 447 header+=11; | 494 header+=11; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 467 ((c >= '0') && (c <= '9')))) | 514 ((c >= '0') && (c <= '9')))) |
| 468 break; | 515 break; |
| 469 #else | 516 #else |
| 470 if (!( isupper(c) || (c == '-') || | 517 if (!( isupper(c) || (c == '-') || |
| 471 isdigit(c))) | 518 isdigit(c))) |
| 472 break; | 519 break; |
| 473 #endif | 520 #endif |
| 474 header++; | 521 header++; |
| 475 } | 522 } |
| 476 *header='\0'; | 523 *header='\0'; |
| 477 o=OBJ_sn2nid(p); | |
| 478 cipher->cipher=enc=EVP_get_cipherbyname(p); | 524 cipher->cipher=enc=EVP_get_cipherbyname(p); |
| 479 *header=c; | 525 *header=c; |
| 480 header++; | 526 header++; |
| 481 | 527 |
| 482 if (enc == NULL) | 528 if (enc == NULL) |
| 483 { | 529 { |
| 484 PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_UNSUPPORTED_ENCRYPTIO
N); | 530 PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_UNSUPPORTED_ENCRYPTIO
N); |
| 485 return(0); | 531 return(0); |
| 486 } | 532 } |
| 487 if (!load_iv(header_pp,&(cipher->iv[0]),enc->iv_len)) | 533 if (!load_iv(header_pp,&(cipher->iv[0]),enc->iv_len)) |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 OPENSSL_free(nameB); | 821 OPENSSL_free(nameB); |
| 776 OPENSSL_free(headerB); | 822 OPENSSL_free(headerB); |
| 777 OPENSSL_free(dataB); | 823 OPENSSL_free(dataB); |
| 778 return(1); | 824 return(1); |
| 779 err: | 825 err: |
| 780 BUF_MEM_free(nameB); | 826 BUF_MEM_free(nameB); |
| 781 BUF_MEM_free(headerB); | 827 BUF_MEM_free(headerB); |
| 782 BUF_MEM_free(dataB); | 828 BUF_MEM_free(dataB); |
| 783 return(0); | 829 return(0); |
| 784 } | 830 } |
| 831 |
| 832 /* Check pem string and return prefix length. |
| 833 * If for example the pem_str == "RSA PRIVATE KEY" and suffix = "PRIVATE KEY" |
| 834 * the return value is 3 for the string "RSA". |
| 835 */ |
| 836 |
| 837 int pem_check_suffix(const char *pem_str, const char *suffix) |
| 838 { |
| 839 int pem_len = strlen(pem_str); |
| 840 int suffix_len = strlen(suffix); |
| 841 const char *p; |
| 842 if (suffix_len + 1 >= pem_len) |
| 843 return 0; |
| 844 p = pem_str + pem_len - suffix_len; |
| 845 if (strcmp(p, suffix)) |
| 846 return 0; |
| 847 p--; |
| 848 if (*p != ' ') |
| 849 return 0; |
| 850 return p - pem_str; |
| 851 } |
| 852 |
| OLD | NEW |