Initial support for enveloped data decrypt. Extent runex.pl to cover these
authorDr. Stephen Henson <steve@openssl.org>
Sat, 15 Mar 2008 23:21:33 +0000 (23:21 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sat, 15 Mar 2008 23:21:33 +0000 (23:21 +0000)
examples. All RFC4134 examples can not be processed.

14 files changed:
apps/cms.c
crypto/cms/cms.h
crypto/cms/cms_dd.c
crypto/cms/cms_enc.c
crypto/cms/cms_env.c
crypto/cms/cms_err.c
crypto/cms/cms_lcl.h
crypto/cms/cms_lib.c
crypto/cms/cms_sd.c
crypto/cms/cms_smime.c
crypto/rsa/rsa.h
crypto/rsa/rsa_ameth.c
crypto/rsa/rsa_err.c
crypto/rsa/rsa_pmeth.c

index 29e4399..b757908 100644 (file)
@@ -814,7 +814,7 @@ int MAIN(int argc, char **argv)
        ret = 4;
        if (operation == SMIME_DECRYPT)
                {
-               if (!CMS_decrypt(cms, key, recip, out, flags))
+               if (!CMS_decrypt(cms, key, recip, indata, out, flags))
                        {
                        BIO_printf(bio_err, "Error decrypting CMS structure\n");
                        goto end;
index c9801cf..41f0e86 100644 (file)
@@ -70,6 +70,7 @@ typedef struct CMS_ContentInfo_st CMS_ContentInfo;
 typedef struct CMS_SignerInfo_st CMS_SignerInfo;
 typedef struct CMS_CertificateChoices CMS_CertificateChoices;
 typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
+typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
 
 DECLARE_STACK_OF(CMS_SignerInfo)
 DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
@@ -78,6 +79,12 @@ DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
 #define CMS_SIGNERINFO_ISSUER_SERIAL   0
 #define CMS_SIGNERINFO_KEYIDENTIFIER   1
 
+#define CMS_RECIPINFO_TRANS            0
+#define CMS_RECIPINFO_AGREE            1
+#define CMS_RECIPINFO_KEK              2
+#define CMS_RECIPINFO_PASS             3
+#define CMS_RECIPINFO_OTHER            4
+
 /* S/MIME related flags */
 
 #define CMS_TEXT                       0x1
@@ -157,9 +164,23 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
 CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
                                const EVP_CIPHER *cipher, unsigned int flags);
 
-int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *data,
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
+                               BIO *data, BIO *dcont,
                                unsigned int flags);
 
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+                                       EVP_PKEY **pk, X509 **recip,
+                                       X509_ALGOR **palg);
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+                                       ASN1_OCTET_STRING **keyid,
+                                       X509_NAME **issuer, ASN1_INTEGER **sno);
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+                              EVP_PKEY *pkey);
+       
 int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
                                                        unsigned int flags);
 CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
@@ -249,6 +270,7 @@ void ERR_load_CMS_strings(void);
 /* Error codes for the CMS functions. */
 
 /* Function codes. */
+#define CMS_F_CHECK_CONTENT                             151
 #define CMS_F_CMS_ADD1_RECIPIENT_CERT                   99
 #define CMS_F_CMS_ADD1_SIGNER                           100
 #define CMS_F_CMS_ADD1_SIGNINGTIME                      101
@@ -262,6 +284,7 @@ void ERR_load_CMS_strings(void);
 #define CMS_F_CMS_DATA                                  107
 #define CMS_F_CMS_DATAFINAL                             108
 #define CMS_F_CMS_DATAINIT                              109
+#define CMS_F_CMS_DECRYPT                               152
 #define CMS_F_CMS_DECRYPTEDCONTENT_DECRYPT_BIO          145
 #define CMS_F_CMS_DECRYPTEDCONTENT_ENCRYPT_BIO          143
 #define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX              110
@@ -285,6 +308,7 @@ void ERR_load_CMS_strings(void);
 #define CMS_F_CMS_GET0_ENVELOPED                        119
 #define CMS_F_CMS_GET0_REVOCATION_CHOICES               120
 #define CMS_F_CMS_GET0_SIGNED                           121
+#define CMS_F_CMS_RECIPIENTINFO_DECRYPT                         150
 #define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP           122
 #define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS          123
 #define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID     124
@@ -307,6 +331,7 @@ void ERR_load_CMS_strings(void);
 #define CMS_R_CIPHER_INITIALISATION_ERROR               138
 #define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR     139
 #define CMS_R_CMS_DATAFINAL_ERROR                       101
+#define CMS_R_CMS_LIB                                   145
 #define CMS_R_CONTENT_NOT_FOUND                                 102
 #define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA          103
 #define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA           104
@@ -328,6 +353,7 @@ void ERR_load_CMS_strings(void);
 #define CMS_R_NO_DEFAULT_DIGEST                                 117
 #define CMS_R_NO_DIGEST_SET                             118
 #define CMS_R_NO_MATCHING_DIGEST                        119
+#define CMS_R_NO_MATCHING_RECIPIENT                     147
 #define CMS_R_NO_PRIVATE_KEY                            120
 #define CMS_R_NO_PUBLIC_KEY                             121
 #define CMS_R_NO_SIGNERS                                122
@@ -340,6 +366,7 @@ void ERR_load_CMS_strings(void);
 #define CMS_R_TYPE_NOT_DATA                             129
 #define CMS_R_TYPE_NOT_DIGESTED_DATA                    130
 #define CMS_R_TYPE_NOT_ENCRYPTED_DATA                   142
+#define CMS_R_TYPE_NOT_ENVELOPED_DATA                   146
 #define CMS_R_UNABLE_TO_FINALIZE_CONTEXT                131
 #define CMS_R_UNKNOWN_CIPHER                            141
 #define CMS_R_UNKNOWN_DIGEST_ALGORIHM                   132
index ec7689d..a927caa 100644 (file)
@@ -98,8 +98,6 @@ CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
 BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
        {
        CMS_DigestedData *dd;
-       if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_digest)
-               return NULL;
        dd = cms->d.digestedData;
        return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
        }
index fbf87b6..a99ce1b 100644 (file)
@@ -227,13 +227,8 @@ int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
 
 BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
        {
-       CMS_EncryptedContentInfo *ec;
-       if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted)
-               {
-               CMSerr(CMS_F_CMS_ENCRYPTEDDATA_INIT_BIO,
-                                               CMS_R_NOT_ENCRYPTED_DATA);
-               return NULL;
-               }
-       ec = cms->d.encryptedData->encryptedContentInfo;
-       return cms_EncryptedContent_init_bio(ec);
+       CMS_EncryptedData *enc = cms->d.encryptedData;
+       if (enc->unprotectedAttrs)
+               enc->version = 2;
+       return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
        }
index 3a5991e..39ebe5a 100644 (file)
@@ -101,6 +101,20 @@ static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
        return cms_get0_enveloped(cms);
        }
 
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
+       {
+       CMS_EnvelopedData *env;
+       env = cms_enveloped_data_init(cms);
+       if (!env)
+               return NULL;
+       return env->recipientInfos;
+       }
+
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
+       {
+       return ri->type;
+       }
+
 /* Add a recipient certificate. For now only handle key transport.
  * If we ever handle key agreement will need updating.
  */
@@ -229,6 +243,7 @@ int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
                        CMS_R_NOT_KEY_TRANSPORT);
                return 0;
                }
+       ktri = ri->d.ktri;
 
        return cms_SignerIdentifier_get0_signer_id(ktri->rid,
                                                        keyid, issuer, sno);
@@ -236,13 +251,86 @@ int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
 
 int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
        {
-       CMS_KeyTransRecipientInfo *ktri;
        if (ri->type != CMS_RECIPINFO_TRANS)
                {
                CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
                        CMS_R_NOT_KEY_TRANSPORT);
+               return -2;
+               }
+
+       return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
+       }
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+                              EVP_PKEY *pkey)
+       {
+       CMS_KeyTransRecipientInfo *ktri;
+       EVP_PKEY_CTX *pctx = NULL;
+       unsigned char *ek = NULL;
+       size_t eklen;
+
+       int ret = 0;
+
+       if (ri->type != CMS_RECIPINFO_TRANS)
+               {
+               CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
+                       CMS_R_NOT_KEY_TRANSPORT);
+               return 0;
+               }
+       ktri = ri->d.ktri;
+
+       pctx = EVP_PKEY_CTX_new(pkey, NULL);
+       if (!pctx)
                return 0;
+
+       if (EVP_PKEY_decrypt_init(pctx) <= 0)
+               goto err;
+
+       if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
+                               EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0)
+               {
+               CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, CMS_R_CTRL_ERROR);
+               goto err;
                }
 
-       return cms_SignerIdentifier_cert_cmp(ktri->rid, cert);
+       if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
+                               ktri->encryptedKey->data,
+                               ktri->encryptedKey->length) <= 0)
+               goto err;
+
+       ek = OPENSSL_malloc(eklen);
+
+       if (ek == NULL)
+               {
+               CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, ERR_R_MALLOC_FAILURE);
+               goto err;
+               }
+
+       if (EVP_PKEY_decrypt(pctx, ek, &eklen,
+                               ktri->encryptedKey->data,
+                               ktri->encryptedKey->length) <= 0)
+               {
+               CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, CMS_R_CMS_LIB);
+               goto err;
+               }
+
+       ret = 1;
+
+       cms->d.envelopedData->encryptedContentInfo->key = ek;
+       cms->d.envelopedData->encryptedContentInfo->keylen = eklen;
+
+       err:
+       if (pctx)
+               EVP_PKEY_CTX_free(pctx);
+       if (!ret && ek)
+               OPENSSL_free(ek);
+
+       return ret;
+       }
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
+       {
+       CMS_EncryptedContentInfo *ec;
+       ec = cms->d.envelopedData->encryptedContentInfo;
+       return cms_EncryptedContent_init_bio(ec);
        }
index 0d14268..3baa40e 100644 (file)
@@ -70,6 +70,7 @@
 
 static ERR_STRING_DATA CMS_str_functs[]=
        {
+{ERR_FUNC(CMS_F_CHECK_CONTENT),        "CHECK_CONTENT"},
 {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT),      "CMS_ADD1_RECIPIENT_CERT"},
 {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER),      "CMS_add1_signer"},
 {ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"},
@@ -83,6 +84,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
 {ERR_FUNC(CMS_F_CMS_DATA),     "CMS_data"},
 {ERR_FUNC(CMS_F_CMS_DATAFINAL),        "CMS_dataFinal"},
 {ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"},
+{ERR_FUNC(CMS_F_CMS_DECRYPT),  "CMS_decrypt"},
 {ERR_FUNC(CMS_F_CMS_DECRYPTEDCONTENT_DECRYPT_BIO),     "CMS_DECRYPTEDCONTENT_DECRYPT_BIO"},
 {ERR_FUNC(CMS_F_CMS_DECRYPTEDCONTENT_ENCRYPT_BIO),     "CMS_DECRYPTEDCONTENT_ENCRYPT_BIO"},
 {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX), "CMS_DIGESTALGORITHM_FIND_CTX"},
@@ -106,9 +108,10 @@ static ERR_STRING_DATA CMS_str_functs[]=
 {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED),   "CMS_GET0_ENVELOPED"},
 {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),  "CMS_GET0_REVOCATION_CHOICES"},
 {ERR_FUNC(CMS_F_CMS_GET0_SIGNED),      "CMS_GET0_SIGNED"},
-{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP),      "CMS_RECIPIENTINFO_KTRI_CERT_CMP"},
-{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),     "CMS_RECIPIENTINFO_KTRI_GET0_ALGS"},
-{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),        "CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT),    "CMS_RecipientInfo_decrypt"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP),      "CMS_RecipientInfo_ktri_cert_cmp"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),     "CMS_RecipientInfo_ktri_get0_algs"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),        "CMS_RecipientInfo_ktri_get0_signer_id"},
 {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER),    "CMS_SET1_SIGNERIDENTIFIER"},
 {ERR_FUNC(CMS_F_CMS_SET_DETACHED),     "CMS_set_detached"},
 {ERR_FUNC(CMS_F_CMS_SIGN),     "CMS_sign"},
@@ -131,6 +134,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
 {ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),"cipher initialisation error"},
 {ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),"cipher parameter initialisation error"},
 {ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR)   ,"cms datafinal error"},
+{ERR_REASON(CMS_R_CMS_LIB)               ,"cms lib"},
 {ERR_REASON(CMS_R_CONTENT_NOT_FOUND)     ,"content not found"},
 {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),"content type not compressed data"},
 {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),"content type not enveloped data"},
@@ -152,6 +156,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
 {ERR_REASON(CMS_R_NO_DEFAULT_DIGEST)     ,"no default digest"},
 {ERR_REASON(CMS_R_NO_DIGEST_SET)         ,"no digest set"},
 {ERR_REASON(CMS_R_NO_MATCHING_DIGEST)    ,"no matching digest"},
+{ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT) ,"no matching recipient"},
 {ERR_REASON(CMS_R_NO_PRIVATE_KEY)        ,"no private key"},
 {ERR_REASON(CMS_R_NO_PUBLIC_KEY)         ,"no public key"},
 {ERR_REASON(CMS_R_NO_SIGNERS)            ,"no signers"},
@@ -164,6 +169,7 @@ static ERR_STRING_DATA CMS_str_reasons[]=
 {ERR_REASON(CMS_R_TYPE_NOT_DATA)         ,"type not data"},
 {ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA),"type not digested data"},
 {ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA),"type not encrypted data"},
+{ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA),"type not enveloped data"},
 {ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),"unable to finalize context"},
 {ERR_REASON(CMS_R_UNKNOWN_CIPHER)        ,"unknown cipher"},
 {ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM),"unknown digest algorihm"},
index 06eeea7..774ec10 100644 (file)
@@ -91,7 +91,6 @@ typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
 typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
 typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
 typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
-typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
 
 struct CMS_ContentInfo_st
        {
@@ -187,12 +186,6 @@ struct CMS_RecipientInfo_st
                } d;
        };
 
-#define CMS_RECIPINFO_TRANS            0
-#define CMS_RECIPINFO_AGREE            1
-#define CMS_RECIPINFO_KEK              2
-#define CMS_RECIPINFO_PASS             3
-#define CMS_RECIPINFO_OTHER            4
-
 typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
 
 struct CMS_KeyTransRecipientInfo_st
@@ -416,9 +409,10 @@ BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
 int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
                                        X509_ALGOR *mdalg);
 
-BIO *cms_EncryptedContent_encrypt_bio(CMS_EncryptedContentInfo *ec);
-BIO *cms_EncryptedContent_decrypt_bio(CMS_EncryptedContentInfo *ec);
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
 BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
        
 #ifdef  __cplusplus
 }
index e691ca3..7b118b8 100644 (file)
@@ -137,6 +137,10 @@ BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
                cmsbio = cms_EncryptedData_init_bio(cms);
                break;
 
+               case NID_pkcs7_enveloped:
+               cmsbio = cms_EnvelopedData_init_bio(cms);
+               break;
+
                default:
                CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
                return NULL;
index 5286097..dc8e896 100644 (file)
@@ -798,9 +798,9 @@ BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
        CMS_SignedData *sd;
        BIO *chain = NULL;
        sd = cms_get0_signed(cms);
-       cms_sd_set_version(sd);
        if (!sd)
                return NULL;
+       cms_sd_set_version(sd);
        for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)
                {
                X509_ALGOR *digestAlgorithm;
index d1a1680..7a2498d 100644 (file)
@@ -113,6 +113,17 @@ static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
 
        }
 
+static int check_content(CMS_ContentInfo *cms)
+       {
+       ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+       if (!pos || !*pos)
+               {
+               CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
+               return 0;
+               }
+       return 1;
+       }
+
 int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
        {
        BIO *cont;
@@ -156,15 +167,8 @@ int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
                return 0;
                }
 
-       if (!dcont)
-               {
-               ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
-               if (!pos || !*pos)
-                       {
-                       CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_NO_CONTENT);
-                       return 0;
-                       }
-               }
+       if (!dcont && !check_content(cms))
+               return 0;
 
        cont = CMS_dataInit(cms, dcont);
        if (!cont)
@@ -209,16 +213,8 @@ int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
                return 0;
                }
 
-       if (!dcont)
-               {
-               ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
-               if (!pos || !*pos)
-                       {
-                       CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
-                                       CMS_R_NO_CONTENT);
-                       return 0;
-                       }
-               }
+       if (!dcont && !check_content(cms))
+               return 0;
 
        if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
                return 0;
@@ -304,15 +300,8 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
        int i, scount = 0, ret = 0;
        BIO *cmsbio = NULL, *tmpin = NULL;
 
-       if (!dcont)
-               {
-               ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
-               if (!pos || !*pos)
-                       {
-                       CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_CONTENT);
-                       return 0;
-                       }
-               }
+       if (!dcont && !check_content(cms))
+               return 0;
 
        /* Attempt to find all signer certificates */
 
@@ -470,7 +459,7 @@ CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
        return NULL;
        }
 
-/* Placeholders for now... */
+/* Placeholder for now... */
 
 CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
                                const EVP_CIPHER *cipher, unsigned int flags)
@@ -478,10 +467,50 @@ CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
        return NULL;
        }
        
-int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, BIO *data,
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
+                               BIO *dcont, BIO *out,
                                unsigned int flags)
        {
-       return 0;
+       STACK_OF(CMS_RecipientInfo) *ris;
+       CMS_RecipientInfo *ri;
+       int i, r;
+       BIO *cont;
+       if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped)
+               {
+               CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
+               return 0;
+               }
+       if (!dcont && !check_content(cms))
+               return 0;
+       ris = CMS_get0_RecipientInfos(cms);
+       for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++)
+               {
+               ri = sk_CMS_RecipientInfo_value(ris, i);
+               if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS)
+                       continue;
+               if (cert)
+                       {
+                       if (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0)
+                               {
+                               if (CMS_RecipientInfo_decrypt(cms, ri, pk) <=0)
+                                       return 0;
+                               else
+                                       break;
+                               }
+                       }
+               }
+
+       if (i == sk_CMS_RecipientInfo_num(ris))
+               {
+               CMSerr(CMS_F_CMS_DECRYPT, CMS_R_NO_MATCHING_RECIPIENT);
+               return 0;
+               }
+       cont = CMS_dataInit(cms, dcont);
+       if (!cont)
+               return 0;
+       r = cms_copy_content(out, cont, flags);
+       BIO_free_all(cont);
+       return r;
        }
 
 int CMS_final(CMS_ContentInfo *cms, BIO *data, int flags)
@@ -528,15 +557,8 @@ int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
                return 0;
                }
 
-       if (!dcont)
-               {
-               ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
-               if (!pos || !*pos)
-                       {
-                       CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_NO_CONTENT);
-                       return 0;
-                       }
-               }
+       if (!dcont && !check_content(cms))
+               return 0;
 
        cont = CMS_dataInit(cms, dcont);
        if (!cont)
index 898aaff..94a1666 100644 (file)
@@ -481,6 +481,7 @@ void ERR_load_RSA_strings(void);
 #define RSA_R_NULL_BEFORE_BLOCK_MISSING                         113
 #define RSA_R_N_DOES_NOT_EQUAL_P_Q                      127
 #define RSA_R_OAEP_DECODING_ERROR                       121
+#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE  148
 #define RSA_R_PADDING_CHECK_FAILED                      114
 #define RSA_R_P_NOT_PRIME                               128
 #define RSA_R_Q_NOT_PRIME                               129
index 39fa9ec..e705f16 100644 (file)
@@ -267,38 +267,29 @@ static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
 
 static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
        {
+       X509_ALGOR *alg = NULL;
        switch (op)
                {
 
                case ASN1_PKEY_CTRL_PKCS7_SIGN:
                if (arg1 == 0)
-                       {
-                       X509_ALGOR *alg;
                        PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
-                       X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
-                                                       V_ASN1_NULL, 0);
-                       }
-               return 1;
+               break;
 
                case ASN1_PKEY_CTRL_PKCS7_ENCRYPT:
                if (arg1 == 0)
-                       {
-                       X509_ALGOR *alg;
                        PKCS7_RECIP_INFO_get0_alg(arg2, &alg);
-                       X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
-                                                       V_ASN1_NULL, 0);
-                       }
-               return 1;
+               break;
 #ifndef OPENSSL_NO_CMS
                case ASN1_PKEY_CTRL_CMS_SIGN:
                if (arg1 == 0)
-                       {
-                       X509_ALGOR *alg;
                        CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg);
-                       X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
-                                                       V_ASN1_NULL, 0);
-                       }
-               return 1;
+               break;
+
+               case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+               if (arg1 == 0)
+                       CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg);
+               break;
 #endif
 
                case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
@@ -310,6 +301,12 @@ static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
 
                }
 
+       if (alg)
+               X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
+                                                       V_ASN1_NULL, 0);
+
+       return 1;
+
        }
 
 
index b7ac4d2..0577fbb 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/rsa/rsa_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -159,6 +159,7 @@ static ERR_STRING_DATA RSA_str_reasons[]=
 {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING),"null before block missing"},
 {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q)  ,"n does not equal p q"},
 {ERR_REASON(RSA_R_OAEP_DECODING_ERROR)   ,"oaep decoding error"},
+{ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supported for this keytype"},
 {ERR_REASON(RSA_R_PADDING_CHECK_FAILED)  ,"padding check failed"},
 {ERR_REASON(RSA_R_P_NOT_PRIME)           ,"p not prime"},
 {ERR_REASON(RSA_R_Q_NOT_PRIME)           ,"q not prime"},
index 0580bac..7d6fef8 100644 (file)
@@ -443,7 +443,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
                return 1;
                case EVP_PKEY_CTRL_PEER_KEY:
                        RSAerr(RSA_F_PKEY_RSA_CTRL,
-                       EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+                       RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
                        return -2;      
 
                default: