diff options
Diffstat (limited to 'src/lib/libcrypto/pkcs7/pk7_smime.c')
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_smime.c | 109 |
1 files changed, 70 insertions, 39 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c index 99a0d63f38..5c6b0fe24b 100644 --- a/src/lib/libcrypto/pkcs7/pk7_smime.c +++ b/src/lib/libcrypto/pkcs7/pk7_smime.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* pk7_smime.c */ | 1 | /* pk7_smime.c */ |
2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL |
3 | * project 1999. | 3 | * project. |
4 | */ | 4 | */ |
5 | /* ==================================================================== | 5 | /* ==================================================================== |
6 | * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. | 6 | * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. |
7 | * | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions |
@@ -66,10 +66,10 @@ | |||
66 | PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, | 66 | PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, |
67 | BIO *data, int flags) | 67 | BIO *data, int flags) |
68 | { | 68 | { |
69 | PKCS7 *p7; | 69 | PKCS7 *p7 = NULL; |
70 | PKCS7_SIGNER_INFO *si; | 70 | PKCS7_SIGNER_INFO *si; |
71 | BIO *p7bio; | 71 | BIO *p7bio = NULL; |
72 | STACK_OF(X509_ALGOR) *smcap; | 72 | STACK_OF(X509_ALGOR) *smcap = NULL; |
73 | int i; | 73 | int i; |
74 | 74 | ||
75 | if(!X509_check_private_key(signcert, pkey)) { | 75 | if(!X509_check_private_key(signcert, pkey)) { |
@@ -82,66 +82,87 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, | |||
82 | return NULL; | 82 | return NULL; |
83 | } | 83 | } |
84 | 84 | ||
85 | PKCS7_set_type(p7, NID_pkcs7_signed); | 85 | if (!PKCS7_set_type(p7, NID_pkcs7_signed)) |
86 | goto err; | ||
86 | 87 | ||
87 | PKCS7_content_new(p7, NID_pkcs7_data); | 88 | if (!PKCS7_content_new(p7, NID_pkcs7_data)) |
89 | goto err; | ||
88 | 90 | ||
89 | if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) { | 91 | if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) { |
90 | PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); | 92 | PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); |
91 | return NULL; | 93 | goto err; |
92 | } | 94 | } |
93 | 95 | ||
94 | if(!(flags & PKCS7_NOCERTS)) { | 96 | if(!(flags & PKCS7_NOCERTS)) { |
95 | PKCS7_add_certificate(p7, signcert); | 97 | if (!PKCS7_add_certificate(p7, signcert)) |
98 | goto err; | ||
96 | if(certs) for(i = 0; i < sk_X509_num(certs); i++) | 99 | if(certs) for(i = 0; i < sk_X509_num(certs); i++) |
97 | PKCS7_add_certificate(p7, sk_X509_value(certs, i)); | 100 | if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) |
98 | } | 101 | goto err; |
99 | |||
100 | if(!(p7bio = PKCS7_dataInit(p7, NULL))) { | ||
101 | PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); | ||
102 | return NULL; | ||
103 | } | 102 | } |
104 | 103 | ||
105 | |||
106 | SMIME_crlf_copy(data, p7bio, flags); | ||
107 | |||
108 | if(!(flags & PKCS7_NOATTR)) { | 104 | if(!(flags & PKCS7_NOATTR)) { |
109 | PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, | 105 | if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, |
110 | V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)); | 106 | V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) |
107 | goto err; | ||
111 | /* Add SMIMECapabilities */ | 108 | /* Add SMIMECapabilities */ |
112 | if(!(flags & PKCS7_NOSMIMECAP)) | 109 | if(!(flags & PKCS7_NOSMIMECAP)) |
113 | { | 110 | { |
114 | if(!(smcap = sk_X509_ALGOR_new_null())) { | 111 | if(!(smcap = sk_X509_ALGOR_new_null())) { |
115 | PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); | 112 | PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); |
116 | return NULL; | 113 | goto err; |
117 | } | 114 | } |
118 | #ifndef OPENSSL_NO_DES | 115 | #ifndef OPENSSL_NO_DES |
119 | PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1); | 116 | if (!PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1)) |
117 | goto err; | ||
120 | #endif | 118 | #endif |
121 | #ifndef OPENSSL_NO_RC2 | 119 | #ifndef OPENSSL_NO_RC2 |
122 | PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128); | 120 | if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128)) |
123 | PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64); | 121 | goto err; |
122 | if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64)) | ||
123 | goto err; | ||
124 | #endif | 124 | #endif |
125 | #ifndef OPENSSL_NO_DES | 125 | #ifndef OPENSSL_NO_DES |
126 | PKCS7_simple_smimecap (smcap, NID_des_cbc, -1); | 126 | if (!PKCS7_simple_smimecap (smcap, NID_des_cbc, -1)) |
127 | goto err; | ||
127 | #endif | 128 | #endif |
128 | #ifndef OPENSSL_NO_RC2 | 129 | #ifndef OPENSSL_NO_RC2 |
129 | PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40); | 130 | if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40)) |
131 | goto err; | ||
130 | #endif | 132 | #endif |
131 | PKCS7_add_attrib_smimecap (si, smcap); | 133 | if (!PKCS7_add_attrib_smimecap (si, smcap)) |
134 | goto err; | ||
132 | sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); | 135 | sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); |
136 | smcap = NULL; | ||
133 | } | 137 | } |
134 | } | 138 | } |
135 | 139 | ||
136 | if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1); | 140 | if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1); |
137 | 141 | ||
138 | if (!PKCS7_dataFinal(p7,p7bio)) { | 142 | if (flags & PKCS7_STREAM) |
143 | return p7; | ||
144 | |||
145 | |||
146 | if (!(p7bio = PKCS7_dataInit(p7, NULL))) { | ||
147 | PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); | ||
148 | goto err; | ||
149 | } | ||
150 | |||
151 | SMIME_crlf_copy(data, p7bio, flags); | ||
152 | |||
153 | |||
154 | if (!PKCS7_dataFinal(p7,p7bio)) { | ||
139 | PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN); | 155 | PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN); |
140 | return NULL; | 156 | goto err; |
141 | } | 157 | } |
142 | 158 | ||
143 | BIO_free_all(p7bio); | 159 | BIO_free_all(p7bio); |
144 | return p7; | 160 | return p7; |
161 | err: | ||
162 | sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); | ||
163 | BIO_free_all(p7bio); | ||
164 | PKCS7_free(p7); | ||
165 | return NULL; | ||
145 | } | 166 | } |
146 | 167 | ||
147 | int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, | 168 | int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, |
@@ -215,6 +236,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, | |||
215 | sk_X509_free(signers); | 236 | sk_X509_free(signers); |
216 | return 0; | 237 | return 0; |
217 | } | 238 | } |
239 | if (!(flags & PKCS7_NOCRL)) | ||
240 | X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); | ||
218 | i = X509_verify_cert(&cert_ctx); | 241 | i = X509_verify_cert(&cert_ctx); |
219 | if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx); | 242 | if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx); |
220 | X509_STORE_CTX_cleanup(&cert_ctx); | 243 | X509_STORE_CTX_cleanup(&cert_ctx); |
@@ -251,7 +274,8 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, | |||
251 | tmpin = indata; | 274 | tmpin = indata; |
252 | 275 | ||
253 | 276 | ||
254 | p7bio=PKCS7_dataInit(p7,tmpin); | 277 | if (!(p7bio=PKCS7_dataInit(p7,tmpin))) |
278 | goto err; | ||
255 | 279 | ||
256 | if(flags & PKCS7_TEXT) { | 280 | if(flags & PKCS7_TEXT) { |
257 | if(!(tmpout = BIO_new(BIO_s_mem()))) { | 281 | if(!(tmpout = BIO_new(BIO_s_mem()))) { |
@@ -330,7 +354,7 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) | |||
330 | 354 | ||
331 | if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { | 355 | if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { |
332 | PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); | 356 | PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); |
333 | return 0; | 357 | return NULL; |
334 | } | 358 | } |
335 | 359 | ||
336 | if(!(signers = sk_X509_new_null())) { | 360 | if(!(signers = sk_X509_new_null())) { |
@@ -353,10 +377,13 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) | |||
353 | if (!signer) { | 377 | if (!signer) { |
354 | PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); | 378 | PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); |
355 | sk_X509_free(signers); | 379 | sk_X509_free(signers); |
356 | return 0; | 380 | return NULL; |
357 | } | 381 | } |
358 | 382 | ||
359 | sk_X509_push(signers, signer); | 383 | if (!sk_X509_push(signers, signer)) { |
384 | sk_X509_free(signers); | ||
385 | return NULL; | ||
386 | } | ||
360 | } | 387 | } |
361 | return signers; | 388 | return signers; |
362 | } | 389 | } |
@@ -376,7 +403,8 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, | |||
376 | return NULL; | 403 | return NULL; |
377 | } | 404 | } |
378 | 405 | ||
379 | PKCS7_set_type(p7, NID_pkcs7_enveloped); | 406 | if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) |
407 | goto err; | ||
380 | if(!PKCS7_set_cipher(p7, cipher)) { | 408 | if(!PKCS7_set_cipher(p7, cipher)) { |
381 | PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); | 409 | PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); |
382 | goto err; | 410 | goto err; |
@@ -398,7 +426,7 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, | |||
398 | 426 | ||
399 | SMIME_crlf_copy(in, p7bio, flags); | 427 | SMIME_crlf_copy(in, p7bio, flags); |
400 | 428 | ||
401 | BIO_flush(p7bio); | 429 | (void)BIO_flush(p7bio); |
402 | 430 | ||
403 | if (!PKCS7_dataFinal(p7,p7bio)) { | 431 | if (!PKCS7_dataFinal(p7,p7bio)) { |
404 | PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR); | 432 | PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR); |
@@ -410,7 +438,7 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, | |||
410 | 438 | ||
411 | err: | 439 | err: |
412 | 440 | ||
413 | BIO_free(p7bio); | 441 | BIO_free_all(p7bio); |
414 | PKCS7_free(p7); | 442 | PKCS7_free(p7); |
415 | return NULL; | 443 | return NULL; |
416 | 444 | ||
@@ -432,7 +460,7 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) | |||
432 | return 0; | 460 | return 0; |
433 | } | 461 | } |
434 | 462 | ||
435 | if(!X509_check_private_key(cert, pkey)) { | 463 | if(cert && !X509_check_private_key(cert, pkey)) { |
436 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, | 464 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, |
437 | PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | 465 | PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); |
438 | return 0; | 466 | return 0; |
@@ -448,10 +476,13 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) | |||
448 | /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ | 476 | /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ |
449 | if(!(tmpbuf = BIO_new(BIO_f_buffer()))) { | 477 | if(!(tmpbuf = BIO_new(BIO_f_buffer()))) { |
450 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); | 478 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); |
479 | BIO_free_all(tmpmem); | ||
451 | return 0; | 480 | return 0; |
452 | } | 481 | } |
453 | if(!(bread = BIO_push(tmpbuf, tmpmem))) { | 482 | if(!(bread = BIO_push(tmpbuf, tmpmem))) { |
454 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); | 483 | PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); |
484 | BIO_free_all(tmpbuf); | ||
485 | BIO_free_all(tmpmem); | ||
455 | return 0; | 486 | return 0; |
456 | } | 487 | } |
457 | ret = SMIME_text(bread, data); | 488 | ret = SMIME_text(bread, data); |