"make update"
[openssl.git] / crypto / pkcs7 / pk7_doit.c
index 4cc30554c5c18ff2a4eb5182fd011392c87ed778..f589508fdd008581b62c439c57d64ee671ef9f52 100644 (file)
@@ -67,6 +67,38 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
                         void *value);
 static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
 
+static int PKCS7_type_is_other(PKCS7* p7)
+       {
+       int isOther=1;
+       
+       int nid=OBJ_obj2nid(p7->type);
+
+       switch( nid )
+               {
+       case NID_pkcs7_data:
+       case NID_pkcs7_signed:
+       case NID_pkcs7_enveloped:
+       case NID_pkcs7_signedAndEnveloped:
+       case NID_pkcs7_digest:
+       case NID_pkcs7_encrypted:
+               isOther=0;
+               break;
+       default:
+               isOther=1;
+               }
+
+       return isOther;
+
+       }
+
+static int PKCS7_type_is_octet_string(PKCS7* p7)
+       {
+       if ( 0==PKCS7_type_is_other(p7) )
+               return 0;
+
+       return (V_ASN1_OCTET_STRING==p7->d.other->type) ? 1 : 0;
+       }
+
 BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
        {
        int i,j;
@@ -165,7 +197,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                        goto err;
                xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
                if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
-               EVP_CipherInit(ctx, evp_cipher, key, iv, 1);
+               EVP_CipherInit_ex(ctx, evp_cipher, NULL, key, iv, 1);
 
                if (ivlen > 0) {
                        if (xalg->parameter == NULL) 
@@ -222,13 +254,20 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                if (PKCS7_is_detached(p7))
                        bio=BIO_new(BIO_s_null());
                else {
-                       if (PKCS7_type_is_signed(p7) &&
-                               PKCS7_type_is_data(p7->d.sign->contents)) {
-                               ASN1_OCTET_STRING *os;
-                               os=p7->d.sign->contents->d.data;
-                               if (os->length > 0) bio = 
-                                       BIO_new_mem_buf(os->data, os->length);
-                       } 
+                       if (PKCS7_type_is_signed(p7) ) { 
+                               if ( PKCS7_type_is_data(p7->d.sign->contents)) {
+                                       ASN1_OCTET_STRING *os;
+                                       os=p7->d.sign->contents->d.data;
+                                       if (os->length > 0)
+                                               bio = BIO_new_mem_buf(os->data, os->length);
+                               }
+                               else if ( PKCS7_type_is_octet_string(p7->d.sign->contents) ) {
+                                       ASN1_OCTET_STRING *os;
+                                       os=p7->d.sign->contents->d.other->value.octet_string;
+                                       if (os->length > 0)
+                                               bio = BIO_new_mem_buf(os->data, os->length);
+                               }
+                       }
                        if(bio == NULL) {
                                bio=BIO_new(BIO_s_mem());
                                BIO_set_mem_eof_return(bio,0);
@@ -391,7 +430,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
 
                evp_ctx=NULL;
                BIO_get_cipher_ctx(etmp,&evp_ctx);
-               EVP_CipherInit(evp_ctx,evp_cipher,NULL,NULL,0);
+               EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0);
                if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
                        goto err;
 
@@ -407,7 +446,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
                                goto err;
                                }
                } 
-               EVP_CipherInit(evp_ctx,NULL,tmp,NULL,0);
+               EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0);
 
                memset(tmp,0,jj);
 
@@ -473,6 +512,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
        STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
        ASN1_OCTET_STRING *os=NULL;
 
+       EVP_MD_CTX_init(&ctx_tmp);
        i=OBJ_obj2nid(p7->type);
        p7->state=PKCS7_S_HEADER;
 
@@ -537,7 +577,6 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                        
                        /* We now have the EVP_MD_CTX, lets do the
                         * signing. */
-                       EVP_MD_CTX_init(&ctx_tmp);
                        EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
                        if (!BUF_MEM_grow(buf,EVP_PKEY_size(si->pkey)))
                                {
@@ -557,11 +596,15 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                                ASN1_UTCTIME *sign_time;
                                const EVP_MD *md_tmp;
 
-                               /* Add signing time */
-                               sign_time=X509_gmtime_adj(NULL,0);
-                               PKCS7_add_signed_attribute(si,
-                                       NID_pkcs9_signingTime,
-                                       V_ASN1_UTCTIME,sign_time);
+                               /* Add signing time if not already present */
+                               if (!PKCS7_get_signed_attribute(si,
+                                                       NID_pkcs9_signingTime))
+                                       {
+                                       sign_time=X509_gmtime_adj(NULL,0);
+                                       PKCS7_add_signed_attribute(si,
+                                               NID_pkcs9_signingTime,
+                                               V_ASN1_UTCTIME,sign_time);
+                                       }
 
                                /* Add digest */
                                md_tmp=EVP_MD_CTX_md(&ctx_tmp);
@@ -585,6 +628,10 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                        if (si->pkey->type == EVP_PKEY_DSA)
                                ctx_tmp.digest=EVP_dss1();
 #endif
+#ifndef OPENSSL_NO_ECDSA
+                       if (si->pkey->type == EVP_PKEY_ECDSA)
+                               ctx_tmp.digest=EVP_ecdsa();
+#endif
 
                        if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
                                (unsigned int *)&buf->length,si->pkey))
@@ -782,6 +829,9 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
 #ifndef OPENSSL_NO_DSA
        if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
 #endif
+#ifndef OPENSSL_NO_ECDSA
+       if (pkey->type == EVP_PKEY_ECDSA) mdc_tmp.digest=EVP_ecdsa();
+#endif
 
        i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
        EVP_PKEY_free(pkey);