Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: openssl/crypto/pkcs7/pk7_smime.c

Issue 9254031: Upgrade chrome's OpenSSL to same version Android ships with. (Closed) Base URL: http://src.chromium.org/svn/trunk/deps/third_party/openssl/
Patch Set: '' Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « openssl/crypto/pkcs7/pk7_mime.c ('k') | openssl/crypto/pkcs7/pkcs7.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* pk7_smime.c */ 1 /* pk7_smime.c */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project. 3 * project.
4 */ 4 */
5 /* ==================================================================== 5 /* ====================================================================
6 * Copyright (c) 1999-2004 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
10 * are met: 10 * are met:
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 * 56 *
57 */ 57 */
58 58
59 /* Simple PKCS#7 processing functions */ 59 /* Simple PKCS#7 processing functions */
60 60
61 #include <stdio.h> 61 #include <stdio.h>
62 #include "cryptlib.h" 62 #include "cryptlib.h"
63 #include <openssl/x509.h> 63 #include <openssl/x509.h>
64 #include <openssl/x509v3.h> 64 #include <openssl/x509v3.h>
65 65
66 static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
67
66 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, 68 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
67 BIO *data, int flags) 69 BIO *data, int flags)
68 { 70 {
69 » PKCS7 *p7 = NULL; 71 » PKCS7 *p7;
70 » PKCS7_SIGNER_INFO *si;
71 » BIO *p7bio = NULL;
72 » STACK_OF(X509_ALGOR) *smcap = NULL;
73 int i; 72 int i;
74 73
75 » if(!X509_check_private_key(signcert, pkey)) { 74 » if(!(p7 = PKCS7_new()))
76 » » PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_C ERTIFICATE); 75 » » {
77 return NULL;
78 » }
79
80 » if(!(p7 = PKCS7_new())) {
81 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); 76 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
82 return NULL; 77 return NULL;
83 » } 78 » » }
84 79
85 if (!PKCS7_set_type(p7, NID_pkcs7_signed)) 80 if (!PKCS7_set_type(p7, NID_pkcs7_signed))
86 goto err; 81 goto err;
87 82
88 if (!PKCS7_content_new(p7, NID_pkcs7_data)) 83 if (!PKCS7_content_new(p7, NID_pkcs7_data))
89 goto err; 84 goto err;
90 85
91 » if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) { 86 » if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags))
92 » » PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); 87 » » {
88 » » PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
93 goto err; 89 goto err;
94 » } 90 » » }
95 91
96 » if(!(flags & PKCS7_NOCERTS)) { 92 » if(!(flags & PKCS7_NOCERTS))
97 » » if (!PKCS7_add_certificate(p7, signcert)) 93 » » {
98 » » » goto err; 94 » » for(i = 0; i < sk_X509_num(certs); i++)
99 » » if(certs) for(i = 0; i < sk_X509_num(certs); i++) 95 » » » {
100 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) 96 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
101 goto err; 97 goto err;
102 » } 98 » » » }
99 » » }
103 100
104 » if(!(flags & PKCS7_NOATTR)) { 101 » if(flags & PKCS7_DETACHED)
105 » » if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, 102 » » PKCS7_set_detached(p7, 1);
106 » » » » V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)))
107 » » » goto err;
108 » » /* Add SMIMECapabilities */
109 » » if(!(flags & PKCS7_NOSMIMECAP))
110 » » {
111 » » if(!(smcap = sk_X509_ALGOR_new_null())) {
112 » » » PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
113 » » » goto err;
114 » » }
115 #ifndef OPENSSL_NO_DES
116 » » if (!PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1))
117 » » » goto err;
118 #endif
119 #ifndef OPENSSL_NO_RC2
120 » » if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128))
121 » » » goto err;
122 » » if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64))
123 » » » goto err;
124 #endif
125 #ifndef OPENSSL_NO_DES
126 » » if (!PKCS7_simple_smimecap (smcap, NID_des_cbc, -1))
127 » » » goto err;
128 #endif
129 #ifndef OPENSSL_NO_RC2
130 » » if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40))
131 » » » goto err;
132 #endif
133 » » if (!PKCS7_add_attrib_smimecap (si, smcap))
134 » » » goto err;
135 » » sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
136 » » smcap = NULL;
137 » » }
138 » }
139 103
140 » if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1); 104 » if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
141
142 » if (flags & PKCS7_STREAM)
143 return p7; 105 return p7;
144 106
107 if (PKCS7_final(p7, data, flags))
108 return p7;
145 109
146 » if (!(p7bio = PKCS7_dataInit(p7, NULL))) { 110 » err:
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)) {
155 » » PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN);
156 » » goto err;
157 » }
158
159 » BIO_free_all(p7bio);
160 » return p7;
161 err:
162 » sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
163 » BIO_free_all(p7bio);
164 PKCS7_free(p7); 111 PKCS7_free(p7);
165 return NULL; 112 return NULL;
166 } 113 }
167 114
115 int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
116 {
117 BIO *p7bio;
118 int ret = 0;
119 if (!(p7bio = PKCS7_dataInit(p7, NULL)))
120 {
121 PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE);
122 return 0;
123 }
124
125 SMIME_crlf_copy(data, p7bio, flags);
126
127 (void)BIO_flush(p7bio);
128
129
130 if (!PKCS7_dataFinal(p7,p7bio))
131 {
132 PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN);
133 goto err;
134 }
135
136 ret = 1;
137
138 err:
139 BIO_free_all(p7bio);
140
141 return ret;
142
143 }
144
145 /* Check to see if a cipher exists and if so add S/MIME capabilities */
146
147 static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
148 {
149 if (EVP_get_cipherbynid(nid))
150 return PKCS7_simple_smimecap(sk, nid, arg);
151 return 1;
152 }
153
154 static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
155 {
156 if (EVP_get_digestbynid(nid))
157 return PKCS7_simple_smimecap(sk, nid, arg);
158 return 1;
159 }
160
161 PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
162 EVP_PKEY *pkey, const EVP_MD *md,
163 int flags)
164 {
165 PKCS7_SIGNER_INFO *si = NULL;
166 STACK_OF(X509_ALGOR) *smcap = NULL;
167 if(!X509_check_private_key(signcert, pkey))
168 {
169 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
170 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
171 return NULL;
172 }
173
174 if (!(si = PKCS7_add_signature(p7,signcert,pkey, md)))
175 {
176 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
177 PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
178 return NULL;
179 }
180
181 if(!(flags & PKCS7_NOCERTS))
182 {
183 if (!PKCS7_add_certificate(p7, signcert))
184 goto err;
185 }
186
187 if(!(flags & PKCS7_NOATTR))
188 {
189 if (!PKCS7_add_attrib_content_type(si, NULL))
190 goto err;
191 /* Add SMIMECapabilities */
192 if(!(flags & PKCS7_NOSMIMECAP))
193 {
194 if(!(smcap = sk_X509_ALGOR_new_null()))
195 {
196 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
197 ERR_R_MALLOC_FAILURE);
198 goto err;
199 }
200 if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
201 || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
202 || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
203 || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
204 || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
205 || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
206 || !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
207 || !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
208 || !add_cipher_smcap(smcap, NID_des_cbc, -1)
209 || !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
210 || !PKCS7_add_attrib_smimecap (si, smcap))
211 goto err;
212 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
213 smcap = NULL;
214 }
215 if (flags & PKCS7_REUSE_DIGEST)
216 {
217 if (!pkcs7_copy_existing_digest(p7, si))
218 goto err;
219 if (!(flags & PKCS7_PARTIAL) &&
220 !PKCS7_SIGNER_INFO_sign(si))
221 goto err;
222 }
223 }
224 return si;
225 err:
226 if (smcap)
227 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
228 return NULL;
229 }
230
231 /* Search for a digest matching SignerInfo digest type and if found
232 * copy across.
233 */
234
235 static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
236 {
237 int i;
238 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
239 PKCS7_SIGNER_INFO *sitmp;
240 ASN1_OCTET_STRING *osdig = NULL;
241 sinfos = PKCS7_get_signer_info(p7);
242 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
243 {
244 sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
245 if (si == sitmp)
246 break;
247 if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
248 continue;
249 if (!OBJ_cmp(si->digest_alg->algorithm,
250 sitmp->digest_alg->algorithm))
251 {
252 osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
253 break;
254 }
255
256 }
257
258 if (osdig)
259 return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
260
261 PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
262 PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
263 return 0;
264 }
265
168 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, 266 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
169 BIO *indata, BIO *out, int flags) 267 BIO *indata, BIO *out, int flags)
170 { 268 {
171 STACK_OF(X509) *signers; 269 STACK_OF(X509) *signers;
172 X509 *signer; 270 X509 *signer;
173 STACK_OF(PKCS7_SIGNER_INFO) *sinfos; 271 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
174 PKCS7_SIGNER_INFO *si; 272 PKCS7_SIGNER_INFO *si;
175 X509_STORE_CTX cert_ctx; 273 X509_STORE_CTX cert_ctx;
176 char buf[4096]; 274 char buf[4096];
177 int i, j=0, k, ret = 0; 275 int i, j=0, k, ret = 0;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE); 445 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE);
348 return NULL; 446 return NULL;
349 } 447 }
350 448
351 /* Collect all the signers together */ 449 /* Collect all the signers together */
352 450
353 sinfos = PKCS7_get_signer_info(p7); 451 sinfos = PKCS7_get_signer_info(p7);
354 452
355 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { 453 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
356 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); 454 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
357 » » return NULL; 455 » » return 0;
358 } 456 }
359 457
360 if(!(signers = sk_X509_new_null())) { 458 if(!(signers = sk_X509_new_null())) {
361 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE); 459 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE);
362 return NULL; 460 return NULL;
363 } 461 }
364 462
365 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) 463 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
366 { 464 {
367 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); 465 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
368 ias = si->issuer_and_serial; 466 ias = si->issuer_and_serial;
369 signer = NULL; 467 signer = NULL;
370 /* If any certificates passed they take priority */ 468 /* If any certificates passed they take priority */
371 if (certs) signer = X509_find_by_issuer_and_serial (certs, 469 if (certs) signer = X509_find_by_issuer_and_serial (certs,
372 ias->issuer, ias->serial); 470 ias->issuer, ias->serial);
373 if (!signer && !(flags & PKCS7_NOINTERN) 471 if (!signer && !(flags & PKCS7_NOINTERN)
374 && p7->d.sign->cert) signer = 472 && p7->d.sign->cert) signer =
375 X509_find_by_issuer_and_serial (p7->d.sign->cert, 473 X509_find_by_issuer_and_serial (p7->d.sign->cert,
376 ias->issuer, ias->serial); 474 ias->issuer, ias->serial);
377 if (!signer) { 475 if (!signer) {
378 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTI FICATE_NOT_FOUND); 476 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTI FICATE_NOT_FOUND);
379 sk_X509_free(signers); 477 sk_X509_free(signers);
380 » » » return NULL; 478 » » » return 0;
381 } 479 }
382 480
383 if (!sk_X509_push(signers, signer)) { 481 if (!sk_X509_push(signers, signer)) {
384 » » » sk_X509_free(signers); 482 » » sk_X509_free(signers);
385 » » » return NULL; 483 » » return NULL;
386 } 484 }
387 } 485 }
388 return signers; 486 return signers;
389 } 487 }
390 488
391 489
392 /* Build a complete PKCS#7 enveloped data */ 490 /* Build a complete PKCS#7 enveloped data */
393 491
394 PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, 492 PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
395 int flags) 493 int flags)
396 { 494 {
397 PKCS7 *p7; 495 PKCS7 *p7;
398 BIO *p7bio = NULL; 496 BIO *p7bio = NULL;
399 int i; 497 int i;
400 X509 *x509; 498 X509 *x509;
401 if(!(p7 = PKCS7_new())) { 499 if(!(p7 = PKCS7_new())) {
402 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); 500 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE);
403 return NULL; 501 return NULL;
404 } 502 }
405 503
406 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) 504 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
407 goto err; 505 goto err;
408 » if(!PKCS7_set_cipher(p7, cipher)) { 506 » if (!PKCS7_set_cipher(p7, cipher)) {
409 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); 507 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
410 goto err; 508 goto err;
411 } 509 }
412 510
413 for(i = 0; i < sk_X509_num(certs); i++) { 511 for(i = 0; i < sk_X509_num(certs); i++) {
414 x509 = sk_X509_value(certs, i); 512 x509 = sk_X509_value(certs, i);
415 if(!PKCS7_add_recipient(p7, x509)) { 513 if(!PKCS7_add_recipient(p7, x509)) {
416 PKCS7err(PKCS7_F_PKCS7_ENCRYPT, 514 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,
417 PKCS7_R_ERROR_ADDING_RECIPIENT); 515 PKCS7_R_ERROR_ADDING_RECIPIENT);
418 goto err; 516 goto err;
419 } 517 }
420 } 518 }
421 519
422 » if(!(p7bio = PKCS7_dataInit(p7, NULL))) { 520 » if (flags & PKCS7_STREAM)
423 » » PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); 521 » » return p7;
424 » » goto err;
425 » }
426 522
427 » SMIME_crlf_copy(in, p7bio, flags); 523 » if (PKCS7_final(p7, in, flags))
428 524 » » return p7;
429 » (void)BIO_flush(p7bio);
430
431 if (!PKCS7_dataFinal(p7,p7bio)) {
432 » » PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR);
433 » » goto err;
434 » }
435 BIO_free_all(p7bio);
436
437 » return p7;
438 525
439 err: 526 err:
440 527
441 BIO_free_all(p7bio); 528 BIO_free_all(p7bio);
442 PKCS7_free(p7); 529 PKCS7_free(p7);
443 return NULL; 530 return NULL;
444 531
445 } 532 }
446 533
447 int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) 534 int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 } else { 578 } else {
492 for(;;) { 579 for(;;) {
493 i = BIO_read(tmpmem, buf, sizeof(buf)); 580 i = BIO_read(tmpmem, buf, sizeof(buf));
494 if(i <= 0) break; 581 if(i <= 0) break;
495 BIO_write(data, buf, i); 582 BIO_write(data, buf, i);
496 } 583 }
497 BIO_free_all(tmpmem); 584 BIO_free_all(tmpmem);
498 return 1; 585 return 1;
499 } 586 }
500 } 587 }
OLDNEW
« no previous file with comments | « openssl/crypto/pkcs7/pk7_mime.c ('k') | openssl/crypto/pkcs7/pkcs7.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698