diff options
Diffstat (limited to 'src/lib/libcrypto/pkcs7/pk7_doit.c')
-rw-r--r-- | src/lib/libcrypto/pkcs7/pk7_doit.c | 354 |
1 files changed, 244 insertions, 110 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c index 4ac29ae14d..a03d7ebedf 100644 --- a/src/lib/libcrypto/pkcs7/pk7_doit.c +++ b/src/lib/libcrypto/pkcs7/pk7_doit.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #include <openssl/objects.h> | 62 | #include <openssl/objects.h> |
63 | #include <openssl/x509.h> | 63 | #include <openssl/x509.h> |
64 | #include <openssl/x509v3.h> | 64 | #include <openssl/x509v3.h> |
65 | #include <openssl/err.h> | ||
65 | 66 | ||
66 | static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, | 67 | static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, |
67 | void *value); | 68 | void *value); |
@@ -101,18 +102,54 @@ static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) | |||
101 | return NULL; | 102 | return NULL; |
102 | } | 103 | } |
103 | 104 | ||
105 | static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) | ||
106 | { | ||
107 | BIO *btmp; | ||
108 | const EVP_MD *md; | ||
109 | if ((btmp=BIO_new(BIO_f_md())) == NULL) | ||
110 | { | ||
111 | PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB); | ||
112 | goto err; | ||
113 | } | ||
114 | |||
115 | md=EVP_get_digestbyobj(alg->algorithm); | ||
116 | if (md == NULL) | ||
117 | { | ||
118 | PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,PKCS7_R_UNKNOWN_DIGEST_TYPE); | ||
119 | goto err; | ||
120 | } | ||
121 | |||
122 | BIO_set_md(btmp,md); | ||
123 | if (*pbio == NULL) | ||
124 | *pbio=btmp; | ||
125 | else if (!BIO_push(*pbio,btmp)) | ||
126 | { | ||
127 | PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB); | ||
128 | goto err; | ||
129 | } | ||
130 | btmp=NULL; | ||
131 | |||
132 | return 1; | ||
133 | |||
134 | err: | ||
135 | if (btmp) | ||
136 | BIO_free(btmp); | ||
137 | return 0; | ||
138 | |||
139 | } | ||
140 | |||
104 | BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | 141 | BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) |
105 | { | 142 | { |
106 | int i; | 143 | int i; |
107 | BIO *out=NULL,*btmp=NULL; | 144 | BIO *out=NULL,*btmp=NULL; |
108 | X509_ALGOR *xa; | 145 | X509_ALGOR *xa = NULL; |
109 | const EVP_MD *evp_md; | ||
110 | const EVP_CIPHER *evp_cipher=NULL; | 146 | const EVP_CIPHER *evp_cipher=NULL; |
111 | STACK_OF(X509_ALGOR) *md_sk=NULL; | 147 | STACK_OF(X509_ALGOR) *md_sk=NULL; |
112 | STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; | 148 | STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; |
113 | X509_ALGOR *xalg=NULL; | 149 | X509_ALGOR *xalg=NULL; |
114 | PKCS7_RECIP_INFO *ri=NULL; | 150 | PKCS7_RECIP_INFO *ri=NULL; |
115 | EVP_PKEY *pkey; | 151 | EVP_PKEY *pkey; |
152 | ASN1_OCTET_STRING *os=NULL; | ||
116 | 153 | ||
117 | i=OBJ_obj2nid(p7->type); | 154 | i=OBJ_obj2nid(p7->type); |
118 | p7->state=PKCS7_S_HEADER; | 155 | p7->state=PKCS7_S_HEADER; |
@@ -121,6 +158,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
121 | { | 158 | { |
122 | case NID_pkcs7_signed: | 159 | case NID_pkcs7_signed: |
123 | md_sk=p7->d.sign->md_algs; | 160 | md_sk=p7->d.sign->md_algs; |
161 | os = PKCS7_get_octet_string(p7->d.sign->contents); | ||
124 | break; | 162 | break; |
125 | case NID_pkcs7_signedAndEnveloped: | 163 | case NID_pkcs7_signedAndEnveloped: |
126 | rsk=p7->d.signed_and_enveloped->recipientinfo; | 164 | rsk=p7->d.signed_and_enveloped->recipientinfo; |
@@ -145,37 +183,21 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
145 | goto err; | 183 | goto err; |
146 | } | 184 | } |
147 | break; | 185 | break; |
186 | case NID_pkcs7_digest: | ||
187 | xa = p7->d.digest->md; | ||
188 | os = PKCS7_get_octet_string(p7->d.digest->contents); | ||
189 | break; | ||
148 | default: | 190 | default: |
149 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); | 191 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); |
150 | goto err; | 192 | goto err; |
151 | } | 193 | } |
152 | 194 | ||
153 | if (md_sk != NULL) | 195 | for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) |
154 | { | 196 | if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) |
155 | for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) | 197 | goto err; |
156 | { | ||
157 | xa=sk_X509_ALGOR_value(md_sk,i); | ||
158 | if ((btmp=BIO_new(BIO_f_md())) == NULL) | ||
159 | { | ||
160 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB); | ||
161 | goto err; | ||
162 | } | ||
163 | |||
164 | evp_md=EVP_get_digestbyobj(xa->algorithm); | ||
165 | if (evp_md == NULL) | ||
166 | { | ||
167 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNKNOWN_DIGEST_TYPE); | ||
168 | goto err; | ||
169 | } | ||
170 | 198 | ||
171 | BIO_set_md(btmp,evp_md); | 199 | if (xa && !PKCS7_bio_add_digest(&out, xa)) |
172 | if (out == NULL) | 200 | goto err; |
173 | out=btmp; | ||
174 | else | ||
175 | BIO_push(out,btmp); | ||
176 | btmp=NULL; | ||
177 | } | ||
178 | } | ||
179 | 201 | ||
180 | if (evp_cipher != NULL) | 202 | if (evp_cipher != NULL) |
181 | { | 203 | { |
@@ -194,17 +216,25 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
194 | BIO_get_cipher_ctx(btmp, &ctx); | 216 | BIO_get_cipher_ctx(btmp, &ctx); |
195 | keylen=EVP_CIPHER_key_length(evp_cipher); | 217 | keylen=EVP_CIPHER_key_length(evp_cipher); |
196 | ivlen=EVP_CIPHER_iv_length(evp_cipher); | 218 | ivlen=EVP_CIPHER_iv_length(evp_cipher); |
197 | if (RAND_bytes(key,keylen) <= 0) | ||
198 | goto err; | ||
199 | xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); | 219 | xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); |
200 | if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen); | 220 | if (ivlen > 0) |
201 | EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1); | 221 | if (RAND_pseudo_bytes(iv,ivlen) <= 0) |
222 | goto err; | ||
223 | if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0) | ||
224 | goto err; | ||
225 | if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) | ||
226 | goto err; | ||
227 | if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) | ||
228 | goto err; | ||
202 | 229 | ||
203 | if (ivlen > 0) { | 230 | if (ivlen > 0) { |
204 | if (xalg->parameter == NULL) | 231 | if (xalg->parameter == NULL) { |
205 | xalg->parameter=ASN1_TYPE_new(); | 232 | xalg->parameter = ASN1_TYPE_new(); |
233 | if (xalg->parameter == NULL) | ||
234 | goto err; | ||
235 | } | ||
206 | if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) | 236 | if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) |
207 | goto err; | 237 | goto err; |
208 | } | 238 | } |
209 | 239 | ||
210 | /* Lets do the pub key stuff :-) */ | 240 | /* Lets do the pub key stuff :-) */ |
@@ -217,7 +247,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
217 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); | 247 | PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO); |
218 | goto err; | 248 | goto err; |
219 | } | 249 | } |
220 | pkey=X509_get_pubkey(ri->cert); | 250 | if ((pkey=X509_get_pubkey(ri->cert)) == NULL) |
251 | goto err; | ||
221 | jj=EVP_PKEY_size(pkey); | 252 | jj=EVP_PKEY_size(pkey); |
222 | EVP_PKEY_free(pkey); | 253 | EVP_PKEY_free(pkey); |
223 | if (max < jj) max=jj; | 254 | if (max < jj) max=jj; |
@@ -230,7 +261,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
230 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) | 261 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) |
231 | { | 262 | { |
232 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | 263 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); |
233 | pkey=X509_get_pubkey(ri->cert); | 264 | if ((pkey=X509_get_pubkey(ri->cert)) == NULL) |
265 | goto err; | ||
234 | jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); | 266 | jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey); |
235 | EVP_PKEY_free(pkey); | 267 | EVP_PKEY_free(pkey); |
236 | if (jj <= 0) | 268 | if (jj <= 0) |
@@ -261,24 +293,16 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) | |||
261 | { | 293 | { |
262 | if (PKCS7_is_detached(p7)) | 294 | if (PKCS7_is_detached(p7)) |
263 | bio=BIO_new(BIO_s_null()); | 295 | bio=BIO_new(BIO_s_null()); |
264 | else | 296 | else if (os && os->length > 0) |
297 | bio = BIO_new_mem_buf(os->data, os->length); | ||
298 | if(bio == NULL) | ||
265 | { | 299 | { |
266 | if (PKCS7_type_is_signed(p7)) | 300 | bio=BIO_new(BIO_s_mem()); |
267 | { | 301 | if (bio == NULL) |
268 | ASN1_OCTET_STRING *os; | 302 | goto err; |
269 | os = PKCS7_get_octet_string( | 303 | BIO_set_mem_eof_return(bio,0); |
270 | p7->d.sign->contents); | ||
271 | if (os && os->length > 0) | ||
272 | bio = BIO_new_mem_buf(os->data, | ||
273 | os->length); | ||
274 | } | ||
275 | if(bio == NULL) | ||
276 | { | ||
277 | bio=BIO_new(BIO_s_mem()); | ||
278 | BIO_set_mem_eof_return(bio,0); | ||
279 | } | ||
280 | } | 304 | } |
281 | } | 305 | } |
282 | BIO_push(out,bio); | 306 | BIO_push(out,bio); |
283 | bio=NULL; | 307 | bio=NULL; |
284 | if (0) | 308 | if (0) |
@@ -293,6 +317,17 @@ err: | |||
293 | return(out); | 317 | return(out); |
294 | } | 318 | } |
295 | 319 | ||
320 | static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) | ||
321 | { | ||
322 | int ret; | ||
323 | ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, | ||
324 | pcert->cert_info->issuer); | ||
325 | if (ret) | ||
326 | return ret; | ||
327 | return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, | ||
328 | ri->issuer_and_serial->serial); | ||
329 | } | ||
330 | |||
296 | /* int */ | 331 | /* int */ |
297 | BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | 332 | BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) |
298 | { | 333 | { |
@@ -403,18 +438,18 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
403 | * (if any) | 438 | * (if any) |
404 | */ | 439 | */ |
405 | 440 | ||
406 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { | 441 | if (pcert) { |
407 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | 442 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { |
408 | if(!X509_NAME_cmp(ri->issuer_and_serial->issuer, | 443 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); |
409 | pcert->cert_info->issuer) && | 444 | if (!pkcs7_cmp_ri(ri, pcert)) |
410 | !M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, | 445 | break; |
411 | ri->issuer_and_serial->serial)) break; | 446 | ri=NULL; |
412 | ri=NULL; | 447 | } |
413 | } | 448 | if (ri == NULL) { |
414 | if (ri == NULL) { | 449 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, |
415 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, | 450 | PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); |
416 | PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); | 451 | goto err; |
417 | goto err; | 452 | } |
418 | } | 453 | } |
419 | 454 | ||
420 | jj=EVP_PKEY_size(pkey); | 455 | jj=EVP_PKEY_size(pkey); |
@@ -425,17 +460,46 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
425 | goto err; | 460 | goto err; |
426 | } | 461 | } |
427 | 462 | ||
428 | jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key), | 463 | /* If we haven't got a certificate try each ri in turn */ |
429 | M_ASN1_STRING_length(ri->enc_key), pkey); | 464 | |
430 | if (jj <= 0) | 465 | if (pcert == NULL) |
431 | { | 466 | { |
432 | PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB); | 467 | for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) |
433 | goto err; | 468 | { |
469 | ri=sk_PKCS7_RECIP_INFO_value(rsk,i); | ||
470 | jj=EVP_PKEY_decrypt(tmp, | ||
471 | M_ASN1_STRING_data(ri->enc_key), | ||
472 | M_ASN1_STRING_length(ri->enc_key), | ||
473 | pkey); | ||
474 | if (jj > 0) | ||
475 | break; | ||
476 | ERR_clear_error(); | ||
477 | ri = NULL; | ||
478 | } | ||
479 | if (ri == NULL) | ||
480 | { | ||
481 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, | ||
482 | PKCS7_R_NO_RECIPIENT_MATCHES_KEY); | ||
483 | goto err; | ||
484 | } | ||
485 | } | ||
486 | else | ||
487 | { | ||
488 | jj=EVP_PKEY_decrypt(tmp, | ||
489 | M_ASN1_STRING_data(ri->enc_key), | ||
490 | M_ASN1_STRING_length(ri->enc_key), pkey); | ||
491 | if (jj <= 0) | ||
492 | { | ||
493 | PKCS7err(PKCS7_F_PKCS7_DATADECODE, | ||
494 | ERR_R_EVP_LIB); | ||
495 | goto err; | ||
496 | } | ||
434 | } | 497 | } |
435 | 498 | ||
436 | evp_ctx=NULL; | 499 | evp_ctx=NULL; |
437 | BIO_get_cipher_ctx(etmp,&evp_ctx); | 500 | BIO_get_cipher_ctx(etmp,&evp_ctx); |
438 | EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0); | 501 | if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0) |
502 | goto err; | ||
439 | if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) | 503 | if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) |
440 | goto err; | 504 | goto err; |
441 | 505 | ||
@@ -451,7 +515,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
451 | goto err; | 515 | goto err; |
452 | } | 516 | } |
453 | } | 517 | } |
454 | EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0); | 518 | if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) |
519 | goto err; | ||
455 | 520 | ||
456 | OPENSSL_cleanse(tmp,jj); | 521 | OPENSSL_cleanse(tmp,jj); |
457 | 522 | ||
@@ -485,6 +550,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) | |||
485 | bio=BIO_new(BIO_s_mem()); | 550 | bio=BIO_new(BIO_s_mem()); |
486 | BIO_set_mem_eof_return(bio,0); | 551 | BIO_set_mem_eof_return(bio,0); |
487 | } | 552 | } |
553 | if (bio == NULL) | ||
554 | goto err; | ||
488 | #endif | 555 | #endif |
489 | } | 556 | } |
490 | BIO_push(out,bio); | 557 | BIO_push(out,bio); |
@@ -504,6 +571,29 @@ err: | |||
504 | return(out); | 571 | return(out); |
505 | } | 572 | } |
506 | 573 | ||
574 | static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) | ||
575 | { | ||
576 | for (;;) | ||
577 | { | ||
578 | bio=BIO_find_type(bio,BIO_TYPE_MD); | ||
579 | if (bio == NULL) | ||
580 | { | ||
581 | PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); | ||
582 | return NULL; | ||
583 | } | ||
584 | BIO_get_md_ctx(bio,pmd); | ||
585 | if (*pmd == NULL) | ||
586 | { | ||
587 | PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR); | ||
588 | return NULL; | ||
589 | } | ||
590 | if (EVP_MD_CTX_type(*pmd) == nid) | ||
591 | return bio; | ||
592 | bio=BIO_next(bio); | ||
593 | } | ||
594 | return NULL; | ||
595 | } | ||
596 | |||
507 | int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | 597 | int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) |
508 | { | 598 | { |
509 | int ret=0; | 599 | int ret=0; |
@@ -528,7 +618,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
528 | si_sk=p7->d.signed_and_enveloped->signer_info; | 618 | si_sk=p7->d.signed_and_enveloped->signer_info; |
529 | if (!(os=M_ASN1_OCTET_STRING_new())) | 619 | if (!(os=M_ASN1_OCTET_STRING_new())) |
530 | { | 620 | { |
531 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_MALLOC_FAILURE); | 621 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); |
532 | goto err; | 622 | goto err; |
533 | } | 623 | } |
534 | p7->d.signed_and_enveloped->enc_data->enc_data=os; | 624 | p7->d.signed_and_enveloped->enc_data->enc_data=os; |
@@ -537,7 +627,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
537 | /* XXXXXXXXXXXXXXXX */ | 627 | /* XXXXXXXXXXXXXXXX */ |
538 | if (!(os=M_ASN1_OCTET_STRING_new())) | 628 | if (!(os=M_ASN1_OCTET_STRING_new())) |
539 | { | 629 | { |
540 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_MALLOC_FAILURE); | 630 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); |
541 | goto err; | 631 | goto err; |
542 | } | 632 | } |
543 | p7->d.enveloped->enc_data->enc_data=os; | 633 | p7->d.enveloped->enc_data->enc_data=os; |
@@ -551,13 +641,24 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
551 | p7->d.sign->contents->d.data = NULL; | 641 | p7->d.sign->contents->d.data = NULL; |
552 | } | 642 | } |
553 | break; | 643 | break; |
644 | |||
645 | case NID_pkcs7_digest: | ||
646 | os=PKCS7_get_octet_string(p7->d.digest->contents); | ||
647 | /* If detached data then the content is excluded */ | ||
648 | if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) | ||
649 | { | ||
650 | M_ASN1_OCTET_STRING_free(os); | ||
651 | p7->d.digest->contents->d.data = NULL; | ||
652 | } | ||
653 | break; | ||
654 | |||
554 | } | 655 | } |
555 | 656 | ||
556 | if (si_sk != NULL) | 657 | if (si_sk != NULL) |
557 | { | 658 | { |
558 | if ((buf=BUF_MEM_new()) == NULL) | 659 | if ((buf=BUF_MEM_new()) == NULL) |
559 | { | 660 | { |
560 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB); | 661 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); |
561 | goto err; | 662 | goto err; |
562 | } | 663 | } |
563 | for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) | 664 | for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) |
@@ -568,32 +669,18 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
568 | j=OBJ_obj2nid(si->digest_alg->algorithm); | 669 | j=OBJ_obj2nid(si->digest_alg->algorithm); |
569 | 670 | ||
570 | btmp=bio; | 671 | btmp=bio; |
571 | for (;;) | 672 | |
572 | { | 673 | btmp = PKCS7_find_digest(&mdc, btmp, j); |
573 | if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) | 674 | |
574 | == NULL) | 675 | if (btmp == NULL) |
575 | { | 676 | goto err; |
576 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); | 677 | |
577 | goto err; | ||
578 | } | ||
579 | BIO_get_md_ctx(btmp,&mdc); | ||
580 | if (mdc == NULL) | ||
581 | { | ||
582 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_INTERNAL_ERROR); | ||
583 | goto err; | ||
584 | } | ||
585 | if (EVP_MD_CTX_type(mdc) == j) | ||
586 | break; | ||
587 | else | ||
588 | btmp=BIO_next(btmp); | ||
589 | } | ||
590 | |||
591 | /* We now have the EVP_MD_CTX, lets do the | 678 | /* We now have the EVP_MD_CTX, lets do the |
592 | * signing. */ | 679 | * signing. */ |
593 | EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); | 680 | EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); |
594 | if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) | 681 | if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey))) |
595 | { | 682 | { |
596 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB); | 683 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB); |
597 | goto err; | 684 | goto err; |
598 | } | 685 | } |
599 | 686 | ||
@@ -615,13 +702,17 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
615 | { | 702 | { |
616 | if (!(sign_time=X509_gmtime_adj(NULL,0))) | 703 | if (!(sign_time=X509_gmtime_adj(NULL,0))) |
617 | { | 704 | { |
618 | PKCS7err(PKCS7_F_PKCS7_DATASIGN, | 705 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, |
619 | ERR_R_MALLOC_FAILURE); | 706 | ERR_R_MALLOC_FAILURE); |
620 | goto err; | 707 | goto err; |
621 | } | 708 | } |
622 | PKCS7_add_signed_attribute(si, | 709 | if (!PKCS7_add_signed_attribute(si, |
623 | NID_pkcs9_signingTime, | 710 | NID_pkcs9_signingTime, |
624 | V_ASN1_UTCTIME,sign_time); | 711 | V_ASN1_UTCTIME,sign_time)) |
712 | { | ||
713 | M_ASN1_UTCTIME_free(sign_time); | ||
714 | goto err; | ||
715 | } | ||
625 | } | 716 | } |
626 | 717 | ||
627 | /* Add digest */ | 718 | /* Add digest */ |
@@ -629,20 +720,25 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
629 | EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); | 720 | EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len); |
630 | if (!(digest=M_ASN1_OCTET_STRING_new())) | 721 | if (!(digest=M_ASN1_OCTET_STRING_new())) |
631 | { | 722 | { |
632 | PKCS7err(PKCS7_F_PKCS7_DATASIGN, | 723 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, |
633 | ERR_R_MALLOC_FAILURE); | 724 | ERR_R_MALLOC_FAILURE); |
634 | goto err; | 725 | goto err; |
635 | } | 726 | } |
636 | if (!M_ASN1_OCTET_STRING_set(digest,md_data, | 727 | if (!M_ASN1_OCTET_STRING_set(digest,md_data, |
637 | md_len)) | 728 | md_len)) |
638 | { | 729 | { |
639 | PKCS7err(PKCS7_F_PKCS7_DATASIGN, | 730 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL, |
640 | ERR_R_MALLOC_FAILURE); | 731 | ERR_R_MALLOC_FAILURE); |
732 | M_ASN1_OCTET_STRING_free(digest); | ||
641 | goto err; | 733 | goto err; |
642 | } | 734 | } |
643 | PKCS7_add_signed_attribute(si, | 735 | if (!PKCS7_add_signed_attribute(si, |
644 | NID_pkcs9_messageDigest, | 736 | NID_pkcs9_messageDigest, |
645 | V_ASN1_OCTET_STRING,digest); | 737 | V_ASN1_OCTET_STRING,digest)) |
738 | { | ||
739 | M_ASN1_OCTET_STRING_free(digest); | ||
740 | goto err; | ||
741 | } | ||
646 | 742 | ||
647 | /* Now sign the attributes */ | 743 | /* Now sign the attributes */ |
648 | EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); | 744 | EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL); |
@@ -657,28 +753,42 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) | |||
657 | if (si->pkey->type == EVP_PKEY_DSA) | 753 | if (si->pkey->type == EVP_PKEY_DSA) |
658 | ctx_tmp.digest=EVP_dss1(); | 754 | ctx_tmp.digest=EVP_dss1(); |
659 | #endif | 755 | #endif |
756 | #ifndef OPENSSL_NO_ECDSA | ||
757 | if (si->pkey->type == EVP_PKEY_EC) | ||
758 | ctx_tmp.digest=EVP_ecdsa(); | ||
759 | #endif | ||
660 | 760 | ||
661 | if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, | 761 | if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data, |
662 | (unsigned int *)&buf->length,si->pkey)) | 762 | (unsigned int *)&buf->length,si->pkey)) |
663 | { | 763 | { |
664 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_EVP_LIB); | 764 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB); |
665 | goto err; | 765 | goto err; |
666 | } | 766 | } |
667 | if (!ASN1_STRING_set(si->enc_digest, | 767 | if (!ASN1_STRING_set(si->enc_digest, |
668 | (unsigned char *)buf->data,buf->length)) | 768 | (unsigned char *)buf->data,buf->length)) |
669 | { | 769 | { |
670 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB); | 770 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB); |
671 | goto err; | 771 | goto err; |
672 | } | 772 | } |
673 | } | 773 | } |
674 | } | 774 | } |
775 | else if (i == NID_pkcs7_digest) | ||
776 | { | ||
777 | unsigned char md_data[EVP_MAX_MD_SIZE]; | ||
778 | unsigned int md_len; | ||
779 | if (!PKCS7_find_digest(&mdc, bio, | ||
780 | OBJ_obj2nid(p7->d.digest->md->algorithm))) | ||
781 | goto err; | ||
782 | EVP_DigestFinal_ex(mdc,md_data,&md_len); | ||
783 | M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); | ||
784 | } | ||
675 | 785 | ||
676 | if (!PKCS7_is_detached(p7)) | 786 | if (!PKCS7_is_detached(p7)) |
677 | { | 787 | { |
678 | btmp=BIO_find_type(bio,BIO_TYPE_MEM); | 788 | btmp=BIO_find_type(bio,BIO_TYPE_MEM); |
679 | if (btmp == NULL) | 789 | if (btmp == NULL) |
680 | { | 790 | { |
681 | PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); | 791 | PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); |
682 | goto err; | 792 | goto err; |
683 | } | 793 | } |
684 | BIO_get_mem_ptr(btmp,&buf_mem); | 794 | BIO_get_mem_ptr(btmp,&buf_mem); |
@@ -859,6 +969,9 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n"); | |||
859 | #ifndef OPENSSL_NO_DSA | 969 | #ifndef OPENSSL_NO_DSA |
860 | if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); | 970 | if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1(); |
861 | #endif | 971 | #endif |
972 | #ifndef OPENSSL_NO_ECDSA | ||
973 | if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa(); | ||
974 | #endif | ||
862 | 975 | ||
863 | i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); | 976 | i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); |
864 | EVP_PKEY_free(pkey); | 977 | EVP_PKEY_free(pkey); |
@@ -883,8 +996,13 @@ PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) | |||
883 | int i; | 996 | int i; |
884 | 997 | ||
885 | i=OBJ_obj2nid(p7->type); | 998 | i=OBJ_obj2nid(p7->type); |
886 | if (i != NID_pkcs7_signedAndEnveloped) return(NULL); | 999 | if (i != NID_pkcs7_signedAndEnveloped) |
1000 | return NULL; | ||
1001 | if (p7->d.signed_and_enveloped == NULL) | ||
1002 | return NULL; | ||
887 | rsk=p7->d.signed_and_enveloped->recipientinfo; | 1003 | rsk=p7->d.signed_and_enveloped->recipientinfo; |
1004 | if (rsk == NULL) | ||
1005 | return NULL; | ||
888 | ri=sk_PKCS7_RECIP_INFO_value(rsk,0); | 1006 | ri=sk_PKCS7_RECIP_INFO_value(rsk,0); |
889 | if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL); | 1007 | if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL); |
890 | ri=sk_PKCS7_RECIP_INFO_value(rsk,idx); | 1008 | ri=sk_PKCS7_RECIP_INFO_value(rsk,idx); |
@@ -938,6 +1056,8 @@ int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, | |||
938 | if (p7si->auth_attr != NULL) | 1056 | if (p7si->auth_attr != NULL) |
939 | sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); | 1057 | sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free); |
940 | p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk); | 1058 | p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk); |
1059 | if (p7si->auth_attr == NULL) | ||
1060 | return 0; | ||
941 | for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) | 1061 | for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) |
942 | { | 1062 | { |
943 | if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i, | 1063 | if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i, |
@@ -956,6 +1076,8 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk) | |||
956 | sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, | 1076 | sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, |
957 | X509_ATTRIBUTE_free); | 1077 | X509_ATTRIBUTE_free); |
958 | p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk); | 1078 | p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk); |
1079 | if (p7si->unauth_attr == NULL) | ||
1080 | return 0; | ||
959 | for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) | 1081 | for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++) |
960 | { | 1082 | { |
961 | if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i, | 1083 | if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i, |
@@ -985,10 +1107,16 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, | |||
985 | 1107 | ||
986 | if (*sk == NULL) | 1108 | if (*sk == NULL) |
987 | { | 1109 | { |
988 | *sk = sk_X509_ATTRIBUTE_new_null(); | 1110 | if (!(*sk = sk_X509_ATTRIBUTE_new_null())) |
1111 | return 0; | ||
989 | new_attrib: | 1112 | new_attrib: |
990 | attr=X509_ATTRIBUTE_create(nid,atrtype,value); | 1113 | if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) |
991 | sk_X509_ATTRIBUTE_push(*sk,attr); | 1114 | return 0; |
1115 | if (!sk_X509_ATTRIBUTE_push(*sk,attr)) | ||
1116 | { | ||
1117 | X509_ATTRIBUTE_free(attr); | ||
1118 | return 0; | ||
1119 | } | ||
992 | } | 1120 | } |
993 | else | 1121 | else |
994 | { | 1122 | { |
@@ -1001,7 +1129,13 @@ new_attrib: | |||
1001 | { | 1129 | { |
1002 | X509_ATTRIBUTE_free(attr); | 1130 | X509_ATTRIBUTE_free(attr); |
1003 | attr=X509_ATTRIBUTE_create(nid,atrtype,value); | 1131 | attr=X509_ATTRIBUTE_create(nid,atrtype,value); |
1004 | sk_X509_ATTRIBUTE_set(*sk,i,attr); | 1132 | if (attr == NULL) |
1133 | return 0; | ||
1134 | if (!sk_X509_ATTRIBUTE_set(*sk,i,attr)) | ||
1135 | { | ||
1136 | X509_ATTRIBUTE_free(attr); | ||
1137 | return 0; | ||
1138 | } | ||
1005 | goto end; | 1139 | goto end; |
1006 | } | 1140 | } |
1007 | } | 1141 | } |