X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fpkcs7%2Fpk7_lib.c;h=9b647b212182a74eaadb04fc313a97555d439446;hp=89b2e8172ab55e7fe97d912165cf8f5a794f5be1;hb=48921e00fc69060b7b29bab707ebc255a3506aff;hpb=b05b50e67b7f571cea12cc558817c40a0497847f diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c index 89b2e8172a..9b647b2121 100644 --- a/crypto/pkcs7/pk7_lib.c +++ b/crypto/pkcs7/pk7_lib.c @@ -74,6 +74,13 @@ long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) if (nid == NID_pkcs7_signed) { ret=p7->detached=(int)larg; + if (ret && PKCS7_type_is_data(p7->d.sign->contents)) + { + ASN1_OCTET_STRING *os; + os=p7->d.sign->contents->d.data; + ASN1_OCTET_STRING_free(os); + p7->d.sign->contents->d.data = NULL; + } } else { @@ -84,7 +91,11 @@ long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) case PKCS7_OP_GET_DETACHED_SIGNATURE: if (nid == NID_pkcs7_signed) { - ret=p7->detached; + if(!p7->d.sign || !p7->d.sign->contents->d.ptr) + ret = 1; + else ret = 0; + + p7->detached = ret; } else { @@ -123,7 +134,7 @@ int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) { case NID_pkcs7_signed: if (p7->d.sign->contents != NULL) - PKCS7_content_free(p7->d.sign->contents); + PKCS7_free(p7->d.sign->contents); p7->d.sign->contents=p7_data; break; case NID_pkcs7_digest: @@ -144,7 +155,7 @@ int PKCS7_set_type(PKCS7 *p7, int type) { ASN1_OBJECT *obj; - PKCS7_content_free(p7); + /*PKCS7_content_free(p7);*/ obj=OBJ_nid2obj(type); /* will not fail */ switch (type) @@ -157,7 +168,7 @@ int PKCS7_set_type(PKCS7 *p7, int type) break; case NID_pkcs7_data: p7->type=obj; - if ((p7->d.data=ASN1_OCTET_STRING_new()) == NULL) + if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL) goto err; break; case NID_pkcs7_signedAndEnveloped: @@ -165,18 +176,27 @@ int PKCS7_set_type(PKCS7 *p7, int type) if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new()) == NULL) goto err; ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1); -/* p7->d.signed_and_enveloped->enc_data->content_type= - OBJ_nid2obj(NID_pkcs7_encrypted);*/ - + p7->d.signed_and_enveloped->enc_data->content_type + = OBJ_nid2obj(NID_pkcs7_data); break; case NID_pkcs7_enveloped: p7->type=obj; if ((p7->d.enveloped=PKCS7_ENVELOPE_new()) == NULL) goto err; ASN1_INTEGER_set(p7->d.enveloped->version,0); + p7->d.enveloped->enc_data->content_type + = OBJ_nid2obj(NID_pkcs7_data); break; - case NID_pkcs7_digest: case NID_pkcs7_encrypted: + p7->type=obj; + if ((p7->d.encrypted=PKCS7_ENCRYPT_new()) + == NULL) goto err; + ASN1_INTEGER_set(p7->d.encrypted->version,0); + p7->d.encrypted->enc_data->content_type + = OBJ_nid2obj(NID_pkcs7_data); + break; + + case NID_pkcs7_digest: default: PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); goto err; @@ -224,8 +244,13 @@ int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) } if (!j) /* we need to add another algorithm */ { - alg=X509_ALGOR_new(); + if(!(alg=X509_ALGOR_new()) + || !(alg->parameter = ASN1_TYPE_new())) { + PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE); + return(0); + } alg->algorithm=OBJ_nid2obj(nid); + alg->parameter->type = V_ASN1_NULL; sk_X509_ALGOR_push(md_sk,alg); } @@ -287,8 +312,15 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) } int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, - EVP_MD *dgst) + const EVP_MD *dgst) { + int nid; + char is_dsa; + + if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC) + is_dsa = 1; + else + is_dsa = 0; /* We now need to add another PKCS7_SIGNER_INFO entry */ ASN1_INTEGER_set(p7i->version,1); X509_NAME_set(&p7i->issuer_and_serial->issuer, @@ -296,17 +328,16 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, /* because ASN1_INTEGER_set is used to set a 'long' we will do * things the ugly way. */ - ASN1_INTEGER_free(p7i->issuer_and_serial->serial); + M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); p7i->issuer_and_serial->serial= - ASN1_INTEGER_dup(X509_get_serialNumber(x509)); + M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)); /* lets keep the pkey around for a while */ CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); p7i->pkey=pkey; /* Set the algorithms */ - if (pkey->type == EVP_PKEY_DSA) - p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1); + if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1); else p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst)); @@ -316,13 +347,38 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, goto err; p7i->digest_alg->parameter->type=V_ASN1_NULL; - p7i->digest_enc_alg->algorithm=OBJ_nid2obj(EVP_PKEY_type(pkey->type)); - if (p7i->digest_enc_alg->parameter != NULL) ASN1_TYPE_free(p7i->digest_enc_alg->parameter); - if ((p7i->digest_enc_alg->parameter=ASN1_TYPE_new()) == NULL) - goto err; - p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; + nid = EVP_PKEY_type(pkey->type); + if (nid == EVP_PKEY_RSA) + { + p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption); + if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new())) + goto err; + p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; + } + else if (nid == EVP_PKEY_DSA) + { +#if 1 + /* use 'dsaEncryption' OID for compatibility with other software + * (PKCS #7 v1.5 does specify how to handle DSA) ... */ + p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa); +#else + /* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS) + * would make more sense. */ + p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1); +#endif + p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */ + } + else if (nid == EVP_PKEY_EC) + { + p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1); + if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new())) + goto err; + p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; + } + else + return(0); return(1); err: @@ -330,7 +386,7 @@ err: } PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, - EVP_MD *dgst) + const EVP_MD *dgst) { PKCS7_SIGNER_INFO *si; @@ -371,7 +427,7 @@ err: int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) { int i; - STACK *sk; + STACK_OF(PKCS7_RECIP_INFO) *sk; i=OBJ_obj2nid(p7->type); switch (i) @@ -387,7 +443,7 @@ int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) return(0); } - sk_push(sk,(char *)ri); + sk_PKCS7_RECIP_INFO_push(sk,ri); return(1); } @@ -397,14 +453,12 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) X509_NAME_set(&p7i->issuer_and_serial->issuer, X509_get_issuer_name(x509)); - ASN1_INTEGER_free(p7i->issuer_and_serial->serial); + M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); p7i->issuer_and_serial->serial= - ASN1_INTEGER_dup(X509_get_serialNumber(x509)); + M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)); X509_ALGOR_free(p7i->key_enc_algor); - p7i->key_enc_algor=(X509_ALGOR *)ASN1_dup(i2d_X509_ALGOR, - (char *(*)())d2i_X509_ALGOR, - (char *)x509->cert_info->key->algor); + p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor); CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); p7i->cert=x509; @@ -425,6 +479,7 @@ X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) { int i; + ASN1_OBJECT *objtmp; PKCS7_ENC_CONTENT *ec; i=OBJ_obj2nid(p7->type); @@ -441,7 +496,13 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) return(0); } - /* Setup cipher OID */ + /* Check cipher OID exists and has data in it*/ + i = EVP_CIPHER_type(cipher); + if(i == NID_undef) { + PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + return(0); + } + objtmp = OBJ_nid2obj(i); ec->cipher = cipher; return 1;