Initialize digested data type in PKCS7_set_type().
[openssl.git] / crypto / pkcs7 / pk7_lib.c
index 3e0a889288bb5d1339f5e4ab8ed4b6ae74de0bc1..3812710618c69905087449bc98d503e374cee0bf 100644 (file)
@@ -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
                        {
@@ -190,6 +197,11 @@ int PKCS7_set_type(PKCS7 *p7, int type)
                break;
 
        case NID_pkcs7_digest:
+               p7->type=obj;
+               if ((p7->d.digest=PKCS7_DIGEST_new())
+                       == NULL) goto err;
+               ASN1_INTEGER_set(p7->d.digest->version,0);
+               break;
        default:
                PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
                goto err;
@@ -307,9 +319,13 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
             const EVP_MD *dgst)
        {
+       int nid;
        char is_dsa;
-       if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_ECDSA) is_dsa = 1;
-       else is_dsa = 0;
+
+       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,
@@ -336,16 +352,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(is_dsa) p7i->digest_enc_alg->parameter = NULL;
-       else {
+       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: