Copy and paste error... bn_add_part_words() should of course call
[openssl.git] / crypto / pkcs7 / pk7_doit.c
index a4cf9b4021df1209064f12571d9a0b7b8dc8884b..099e9651c1c31eff321a76d49e234cf42758a027 100644 (file)
@@ -61,6 +61,7 @@
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
 
 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
                         void *value);
@@ -160,9 +161,10 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                BIO_get_cipher_ctx(btmp, &ctx);
                keylen=EVP_CIPHER_key_length(evp_cipher);
                ivlen=EVP_CIPHER_iv_length(evp_cipher);
-               RAND_bytes(key,keylen);
+               if (RAND_bytes(key,keylen) <= 0)
+                       goto err;
                xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
-               if (ivlen > 0) RAND_bytes(iv,ivlen);
+               if (ivlen > 0) RAND_pseudo_bytes(iv,ivlen);
                EVP_CipherInit(ctx, evp_cipher, key, iv, 1);
 
                if (ivlen > 0) {
@@ -187,7 +189,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                        EVP_PKEY_free(pkey);
                        if (max < jj) max=jj;
                        }
-               if ((tmp=(unsigned char *)Malloc(max)) == NULL)
+               if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
                        {
                        PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
                        goto err;
@@ -201,12 +203,12 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                        if (jj <= 0)
                                {
                                PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
-                               Free(tmp);
+                               OPENSSL_free(tmp);
                                goto err;
                                }
                        M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj);
                        }
-               Free(tmp);
+               OPENSSL_free(tmp);
                memset(key, 0, keylen);
 
                if (out == NULL)
@@ -226,7 +228,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                                os=p7->d.sign->contents->d.data;
                                if (os->length > 0) bio = 
                                        BIO_new_mem_buf(os->data, os->length);
-                       } else {
+                       } 
+                       if(bio == NULL) {
                                bio=BIO_new(BIO_s_mem());
                                BIO_set_mem_eof_return(bio,0);
                        }
@@ -251,7 +254,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
        {
        int i,j;
        BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
-       char *tmp=NULL;
+       unsigned char *tmp=NULL;
        X509_ALGOR *xa;
        ASN1_OCTET_STRING *data_body=NULL;
        const EVP_MD *evp_md;
@@ -262,10 +265,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
        STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
        X509_ALGOR *xalg=NULL;
        PKCS7_RECIP_INFO *ri=NULL;
-/*     EVP_PKEY *pkey; */
-#if 0
-       X509_STORE_CTX s_ctx;
-#endif
 
        i=OBJ_obj2nid(p7->type);
        p7->state=PKCS7_S_HEADER;
@@ -375,17 +374,15 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
                }
 
                jj=EVP_PKEY_size(pkey);
-               tmp=Malloc(jj+10);
+               tmp=(unsigned char *)OPENSSL_malloc(jj+10);
                if (tmp == NULL)
                        {
                        PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
                        goto err;
                        }
 
-               jj=EVP_PKEY_decrypt((unsigned char *)tmp,
-                       M_ASN1_STRING_data(ri->enc_key),
-                       M_ASN1_STRING_length(ri->enc_key),
-                       pkey);
+               jj=EVP_PKEY_decrypt(tmp, M_ASN1_STRING_data(ri->enc_key),
+                       M_ASN1_STRING_length(ri->enc_key), pkey);
                if (jj <= 0)
                        {
                        PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);
@@ -398,13 +395,19 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
                if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
                        return(NULL);
 
-               if (jj != EVP_CIPHER_CTX_key_length(evp_ctx))
-                       {
-                       PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+               if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) {
+                       /* Some S/MIME clients don't use the same key
+                        * and effective key length. The key length is
+                        * determined by the size of the decrypted RSA key.
+                        */
+                       if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj))
+                               {
+                               PKCS7err(PKCS7_F_PKCS7_DATADECODE,
                                        PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
-                       goto err;
-                       }
-               EVP_CipherInit(evp_ctx,NULL,(unsigned char *)tmp,NULL,0);
+                               goto err;
+                               }
+               } 
+               EVP_CipherInit(evp_ctx,NULL,tmp,NULL,0);
 
                memset(tmp,0,jj);
 
@@ -453,7 +456,7 @@ err:
                out=NULL;
                }
        if (tmp != NULL)
-               Free(tmp);
+               OPENSSL_free(tmp);
        return(out);
        }
 
@@ -528,10 +531,10 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                                        PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR);
                                        goto err;
                                        }
-                               if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == j)
+                               if (EVP_MD_CTX_type(mdc) == j)
                                        break;
                                else
-                                       btmp=btmp->next_bio;
+                                       btmp=BIO_next(btmp);
                                }
                        
                        /* We now have the EVP_MD_CTX, lets do the
@@ -562,7 +565,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                                        V_ASN1_UTCTIME,sign_time);
 
                                /* Add digest */
-                               md_tmp=EVP_MD_CTX_type(&ctx_tmp);
+                               md_tmp=EVP_MD_CTX_md(&ctx_tmp);
                                EVP_DigestFinal(&ctx_tmp,md_data,&md_len);
                                digest=M_ASN1_OCTET_STRING_new();
                                M_ASN1_OCTET_STRING_set(digest,md_data,md_len);
@@ -575,13 +578,13 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                                x=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL,
                                           i2d_X509_ATTRIBUTE,
                                           V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
-                               pp=(unsigned char *)Malloc(x);
+                               pp=(unsigned char *)OPENSSL_malloc(x);
                                p=pp;
                                i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p,
                                           i2d_X509_ATTRIBUTE,
                                           V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
                                EVP_SignUpdate(&ctx_tmp,pp,x);
-                               Free(pp);
+                               OPENSSL_free(pp);
                                pp=NULL;
                                }
 
@@ -624,7 +627,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
                        (unsigned char *)buf_mem->data,buf_mem->length);
 #endif
                }
-       if (pp != NULL) Free(pp);
+       if (pp != NULL) OPENSSL_free(pp);
        pp=NULL;
 
        ret=1;
@@ -668,10 +671,12 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
 
        /* Lets verify */
        X509_STORE_CTX_init(ctx,cert_store,x509,cert);
+       X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
        i=X509_verify_cert(ctx);
        if (i <= 0) 
                {
                PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
+               X509_STORE_CTX_cleanup(ctx);
                goto err;
                }
        X509_STORE_CTX_cleanup(ctx);
@@ -719,9 +724,9 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
                                                        PKCS7_R_INTERNAL_ERROR);
                        goto err;
                        }
-               if (EVP_MD_type(EVP_MD_CTX_type(mdc)) == md_type)
+               if (EVP_MD_CTX_type(mdc) == md_type)
                        break;
-               btmp=btmp->next_bio;    
+               btmp=BIO_next(btmp);
                }
 
        /* mdc is the digest ctx that we want, unless there are attributes,
@@ -767,13 +772,13 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
                 */
                i=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL,i2d_X509_ATTRIBUTE,
                        V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
-               pp=Malloc(i);
+               pp=OPENSSL_malloc(i);
                p=pp;
                i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p,i2d_X509_ATTRIBUTE,
                        V_ASN1_SET,V_ASN1_UNIVERSAL, IS_SEQUENCE);
                EVP_VerifyUpdate(&mdc_tmp,pp,i);
 
-               Free(pp);
+               OPENSSL_free(pp);
                }
 
        os=si->enc_digest;
@@ -904,7 +909,7 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
 
        if (*sk == NULL)
                {
-               *sk = sk_X509_ATTRIBUTE_new(NULL);
+               *sk = sk_X509_ATTRIBUTE_new_null();
 new_attrib:
                attr=X509_ATTRIBUTE_create(nid,atrtype,value);
                sk_X509_ATTRIBUTE_push(*sk,attr);