Fix some obvious bugs in the PKCS#7 library handling. It didn't try to
authorDr. Stephen Henson <steve@openssl.org>
Sun, 16 May 1999 00:25:36 +0000 (00:25 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 16 May 1999 00:25:36 +0000 (00:25 +0000)
find the right RecipientInfo based on the recipient certificate (so would
fail a lot of the time) and fixup cipher structures to correctly (maybe)
modify the AlgorithmIdentifiers.  Largely untested at present... this will be
fixed in due course. Well the stuff was broken to begin with so if its broken
now then you haven't lost anything :-)

CHANGES
crypto/evp/evp.h
crypto/evp/evp_err.c
crypto/evp/evp_lib.c
crypto/pkcs7/dec.c
crypto/pkcs7/pk7_doit.c
crypto/pkcs7/pk7_lib.c
crypto/pkcs7/pkcs7.h
crypto/pkcs7/pkcs7err.c

diff --git a/CHANGES b/CHANGES
index 9946a9578525714452c6ce4fe1ca1b46768332d6..a07070573042b04abe17eb5ff3910657138f5677 100644 (file)
--- a/CHANGES
+++ b/CHANGES
                                    [23-Dec-1998] down below; but in later
                                    versions, these hyphens are gone.]
 
+  *) Reorganise the PKCS#7 library and get rid of some of the more obvious
+     problems: find RecipientInfo structure that matches recipient certificate
+     and initialise the ASN1 structures properly based on passed cipher.
+     [Steve Henson]
+
   *) Belatedly make the BN tests actually check the results.
      [Ben Laurie]
 
index ac21717057d2aec97dc462ed917fbfa49d79ff90..39f48610ed8d85205b04178c272ad512b9722151 100644 (file)
@@ -624,7 +624,7 @@ int EVP_PKEY_missing_parameters(EVP_PKEY *pkey);
 int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode);
 int EVP_PKEY_cmp_parameters(EVP_PKEY *a,EVP_PKEY *b);
 
-int EVP_CIPHER_type(EVP_CIPHER *ctx);
+int EVP_CIPHER_type(const EVP_CIPHER *ctx);
 
 /* calls methods */
 int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
index 6a60ca4bccbf46c75177c49cb518d45455ebd079..63ce3ae17d3c7fdfd41bd4c0ee937a87ee0d1e61 100644 (file)
@@ -71,7 +71,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
 {ERR_PACK(0,EVP_F_EVP_OPENINIT,0),     "EVP_OpenInit"},
 {ERR_PACK(0,EVP_F_EVP_PBE_ALGOR_CIPHERINIT,0), "EVP_PBE_ALGOR_CipherInit"},
 {ERR_PACK(0,EVP_F_EVP_PBE_ALG_ADD,0),  "EVP_PBE_alg_add"},
-{ERR_PACK(0,EVP_F_EVP_PBE_CIPHERINIT,0),       "EVP_PBE_CIPHERINIT"},
+{ERR_PACK(0,EVP_F_EVP_PBE_CIPHERINIT,0),       "EVP_PBE_CipherInit"},
 {ERR_PACK(0,EVP_F_EVP_PKCS82PKEY,0),   "EVP_PKCS82PKEY"},
 {ERR_PACK(0,EVP_F_EVP_PKCS8_SET_BROKEN,0),     "EVP_PKCS8_SET_BROKEN"},
 {ERR_PACK(0,EVP_F_EVP_PKEY2PKCS8,0),   "EVP_PKEY2PKCS8"},
index d49ae90c775f47484bcfdb841b27ea2688684c5a..3f9bf55828aaa8000cb6534e0579cc4988bf4a7d 100644 (file)
@@ -112,7 +112,7 @@ int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
        }
 
 /* Convert the various cipher NIDs and dummies to a proper OID NID */
-int EVP_CIPHER_type(EVP_CIPHER *ctx)
+int EVP_CIPHER_type(const EVP_CIPHER *ctx)
 {
        int nid;
        nid = EVP_CIPHER_nid(ctx);
index c485d39d1d831cd272747d3898b694157e91cdf9..7063037bb1da7cdc5edc2b6991e37ddd0301e4f9 100644 (file)
@@ -144,7 +144,7 @@ again:
 
        /* We need to process the data */
        /* We cannot support detached encryption */
-       p7bio=PKCS7_dataDecode(p7,pkey,detached,cert_store);
+       p7bio=PKCS7_dataDecode(p7,pkey,detached,x509);
        
        if (p7bio == NULL)
                {
index 030bc92eeb59a5a7bd3b0a16eb71f878f076bdba..7a537eeb4e8f0ebc77eb370e9337606fbbecdae8 100644 (file)
@@ -88,23 +88,25 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
        case NID_pkcs7_signedAndEnveloped:
                rsk=p7->d.signed_and_enveloped->recipientinfo;
                md_sk=p7->d.signed_and_enveloped->md_algs;
-               evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(p7->d.signed_and_enveloped->enc_data->algorithm->algorithm)));
+               xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
+               evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
                if (evp_cipher == NULL)
                        {
-                       PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+                       PKCS7err(PKCS7_F_PKCS7_DATAINIT,
+                                               PKCS7_R_CIPHER_NOT_INITIALIZED);
                        goto err;
                        }
-               xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
                break;
        case NID_pkcs7_enveloped:
                rsk=p7->d.enveloped->recipientinfo;
-               evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(p7->d.enveloped->enc_data->algorithm->algorithm)));
+               xalg=p7->d.enveloped->enc_data->algorithm;
+               evp_cipher=p7->d.enveloped->enc_data->cipher;
                if (evp_cipher == NULL)
                        {
-                       PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+                       PKCS7err(PKCS7_F_PKCS7_DATAINIT,
+                                               PKCS7_R_CIPHER_NOT_INITIALIZED);
                        goto err;
                        }
-               xalg=p7->d.enveloped->enc_data->algorithm;
                break;
        default:
                PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
@@ -146,24 +148,28 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                int keylen,ivlen;
                int jj,max;
                unsigned char *tmp;
+               EVP_CIPHER_CTX *ctx;
 
                if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
                        {
                        PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
                        goto err;
                        }
+               BIO_get_cipher_ctx(btmp, &ctx);
                keylen=EVP_CIPHER_key_length(evp_cipher);
                ivlen=EVP_CIPHER_iv_length(evp_cipher);
+               RAND_bytes(key,keylen);
+               EVP_CipherInit(ctx, evp_cipher, key, iv, 1);
+               memset(key, 0, keylen);
+               xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
 
                if (ivlen > 0) {
-                       EVP_CIPHER_CTX *ctx;
-                       BIO_get_cipher_ctx(btmp, &ctx);
+                       RAND_bytes(iv,ivlen);
                        if (xalg->parameter == NULL) 
                                                xalg->parameter=ASN1_TYPE_new();
                        if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
                                                                       goto err;
                }
-               RAND_bytes(key,keylen);
 
                /* Lets do the pub key stuff :-) */
                max=0;
@@ -201,8 +207,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
                        }
                Free(tmp);
 
-               BIO_set_cipher(btmp,evp_cipher,key,iv,1);
-
                if (out == NULL)
                        out=btmp;
                else
@@ -249,8 +253,7 @@ err:
        }
 
 /* int */
-BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
-            X509_STORE *xs)
+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;
@@ -286,7 +289,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
                evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
                if (evp_cipher == NULL)
                        {
-                       PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+                       PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
                        goto err;
                        }
                xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
@@ -298,13 +301,13 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
                evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
                if (evp_cipher == NULL)
                        {
-                       PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+                       PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
                        goto err;
                        }
                xalg=p7->d.enveloped->enc_data->algorithm;
                break;
        default:
-               PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+               PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
                goto err;
                }
 
@@ -316,7 +319,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
                        xa=(X509_ALGOR *)sk_value(md_sk,i);
                        if ((btmp=BIO_new(BIO_f_md())) == NULL)
                                {
-                               PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_BIO_LIB);
+                               PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
                                goto err;
                                }
 
@@ -324,7 +327,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
                        evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
                        if (evp_md == NULL)
                                {
-                               PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
+                               PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
                                goto err;
                                }
 
@@ -351,50 +354,36 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
 
                if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
                        {
-                       PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_BIO_LIB);
+                       PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
                        goto err;
                        }
 
                /* It was encrypted, we need to decrypt the secret key
                 * with the private key */
 
-               /* We need to find a private key for one of the people in the
-                * recipentinfo list */
-               if (rsk == NULL)
-                       return(NULL);
-
-               /* FIXME: this assumes that the passed private key
-                * corresponds to the first RecipientInfo. This in
-                * general is not true
+               /* Find the recipientInfo which matches the passed certificate
+                * (if any)
                 */
 
-               ri=(PKCS7_RECIP_INFO *)sk_value(rsk,0);
-#if 0
-               X509_STORE_CTX_init(&s_ctx,xs,NULL,NULL);
-               for (i=0; i<sk_num(rsk); i++)
-                       {
+               for (i=0; i<sk_num(rsk); i++) {
                        ri=(PKCS7_RECIP_INFO *)sk_value(rsk,i);
-                       uf (X509_STORE_get_by_issuer_serial(&s_ctx,
-                               X509_LU_PKEY,
-                               ri->issuer_and_serial->issuer,
-                               ri->issuer_and_serial->serial,
-                               &ret))
-                               break;
+                       if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,
+                                       pcert->cert_info->issuer) &&
+                            !ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
+                                       ri->issuer_and_serial->serial)) break;
                        ri=NULL;
-                       }
-               if (ri == NULL) return(NULL);   
-               pkey=ret.data.pkey;
-#endif
-               if (pkey == NULL)
-                       {
+               }
+               if (ri == NULL) {
+                       PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+                                PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
                        return(NULL);
-                       }
+               }
 
                jj=EVP_PKEY_size(pkey);
                tmp=Malloc(jj+10);
                if (tmp == NULL)
                        {
-                       PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_MALLOC_FAILURE);
+                       PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
                        goto err;
                        }
 
@@ -404,7 +393,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
                        pkey);
                if (jj <= 0)
                        {
-                       PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_EVP_LIB);
+                       PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);
                        goto err;
                        }
 
@@ -416,7 +405,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
 
                if (jj != EVP_CIPHER_CTX_key_length(evp_ctx))
                        {
-                       PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
+                       PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+                                       PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
                        goto err;
                        }
                EVP_CipherInit(evp_ctx,NULL,(unsigned char *)tmp,NULL,0);
index ea3a5a2c76e1a7429e2716d09fa12d3711805413..b931ac7e088d57e0aaed2217a9928c83ae993296 100644 (file)
@@ -422,7 +422,7 @@ X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
                return(NULL);
        }
 
-int PKCS7_set_cipher(PKCS7 *p7, EVP_CIPHER *cipher)
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
        {
        int i;
        PKCS7_ENC_CONTENT *ec;
@@ -441,7 +441,9 @@ int PKCS7_set_cipher(PKCS7 *p7, EVP_CIPHER *cipher)
                return(0);
                }
 
-       ec->algorithm->algorithm=OBJ_nid2obj(EVP_CIPHER_type(cipher));
-       return(ec->algorithm->algorithm != NULL);
+       /* Setup cipher OID */
+
+       ec->cipher = cipher;
+       return 1;
        }
 
index 4afde8274b4279932789d66cf08f6918fcf8d5d8..5d3215ed0bea9b70b7c4e6d377bcf4125dc68bbe 100644 (file)
@@ -120,6 +120,7 @@ typedef struct pkcs7_enc_content_st
        ASN1_OBJECT                     *content_type;
        X509_ALGOR                      *algorithm;
        ASN1_OCTET_STRING               *enc_data;      /* [ 0 ] */
+       const EVP_CIPHER                *cipher;
        } PKCS7_ENC_CONTENT;
 
 typedef struct pkcs7_enveloped_st
@@ -128,7 +129,7 @@ typedef struct pkcs7_enveloped_st
        STACK /* PKCS7_RECIP_INFO */    *recipientinfo;
        PKCS7_ENC_CONTENT               *enc_data;
        } PKCS7_ENVELOPE;
-       
+
 typedef struct pkcs7_signedandenveloped_st
        {
        ASN1_INTEGER                    *version;       /* version 1 */
@@ -324,7 +325,7 @@ int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
 
 BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
 int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
-BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509_STORE *xs);
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
 
 
 PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
@@ -335,7 +336,7 @@ STACK *PKCS7_get_signer_info(PKCS7 *p7);
 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
-int PKCS7_set_cipher(PKCS7 *p7, EVP_CIPHER *cipher);
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
 
 PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
 ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK *sk);
@@ -363,19 +364,21 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK *sk);
 #define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO                102
 #define PKCS7_F_PKCS7_ADD_SIGNER                        103
 #define PKCS7_F_PKCS7_CTRL                              104
+#define PKCS7_F_PKCS7_DATADECODE                        112
 #define PKCS7_F_PKCS7_DATAINIT                          105
 #define PKCS7_F_PKCS7_DATASIGN                          106
 #define PKCS7_F_PKCS7_DATAVERIFY                        107
 #define PKCS7_F_PKCS7_SET_CIPHER                        108
 #define PKCS7_F_PKCS7_SET_CONTENT                       109
 #define PKCS7_F_PKCS7_SET_TYPE                          110
-#define PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT               111
 
 /* Reason codes. */
+#define PKCS7_R_CIPHER_NOT_INITIALIZED                  116
 #define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH           100
 #define PKCS7_R_DIGEST_FAILURE                          101
 #define PKCS7_R_INTERNAL_ERROR                          102
 #define PKCS7_R_MISSING_CERIPEND_INFO                   103
+#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE        115
 #define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE    104
 #define PKCS7_R_SIGNATURE_FAILURE                       105
 #define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE              106
index d0cc96c58aa7b9a1371aa7e5710b2b60286bec07..99e4a44623fdd51cdfbff068b39b2a653a58cc8d 100644 (file)
@@ -70,22 +70,24 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
 {ERR_PACK(0,PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,0),       "PKCS7_add_recipient_info"},
 {ERR_PACK(0,PKCS7_F_PKCS7_ADD_SIGNER,0),       "PKCS7_add_signer"},
 {ERR_PACK(0,PKCS7_F_PKCS7_CTRL,0),     "PKCS7_ctrl"},
+{ERR_PACK(0,PKCS7_F_PKCS7_DATADECODE,0),       "PKCS7_dataDecode"},
 {ERR_PACK(0,PKCS7_F_PKCS7_DATAINIT,0), "PKCS7_dataInit"},
 {ERR_PACK(0,PKCS7_F_PKCS7_DATASIGN,0), "PKCS7_DATASIGN"},
 {ERR_PACK(0,PKCS7_F_PKCS7_DATAVERIFY,0),       "PKCS7_dataVerify"},
 {ERR_PACK(0,PKCS7_F_PKCS7_SET_CIPHER,0),       "PKCS7_set_cipher"},
 {ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0),      "PKCS7_set_content"},
 {ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0), "PKCS7_set_type"},
-{ERR_PACK(0,PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,0),      "PKCS7_SIGNENVELOPEDECRYPT"},
 {0,NULL}
        };
 
 static ERR_STRING_DATA PKCS7_str_reasons[]=
        {
+{PKCS7_R_CIPHER_NOT_INITIALIZED          ,"cipher not initialized"},
 {PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH   ,"decrypted key is wrong length"},
 {PKCS7_R_DIGEST_FAILURE                  ,"digest failure"},
 {PKCS7_R_INTERNAL_ERROR                  ,"internal error"},
 {PKCS7_R_MISSING_CERIPEND_INFO           ,"missing ceripend info"},
+{PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE,"no recipient matches certificate"},
 {PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE,"operation not supported on this type"},
 {PKCS7_R_SIGNATURE_FAILURE               ,"signature failure"},
 {PKCS7_R_UNABLE_TO_FIND_CERTIFICATE      ,"unable to find certificate"},