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 |