Add function CMS_RecipientInfo_encrypt
authorDr. Stephen Henson <steve@openssl.org>
Tue, 26 Feb 2013 16:48:49 +0000 (16:48 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 26 Feb 2013 16:59:56 +0000 (16:59 +0000)
Add CMS_RecipientInfo_encrypt: this function encrypts an existing content
encryption key to match the key in the RecipientInfo structure: this is
useful if a new recpient is added to and existing enveloped data structure.

Add documentation.

crypto/cms/cms.h
crypto/cms/cms_env.c
crypto/cms/cms_err.c
doc/crypto/CMS_get0_RecipientInfos.pod

index 36994fa..198688e 100644 (file)
@@ -233,6 +233,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
                                        const EVP_CIPHER *kekciph);
 
 int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
        
 int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
                                                        unsigned int flags);
@@ -384,6 +385,7 @@ void ERR_load_CMS_strings(void);
 #define CMS_F_CMS_RECEIPTREQUEST_CREATE0                159
 #define CMS_F_CMS_RECEIPT_VERIFY                        160
 #define CMS_F_CMS_RECIPIENTINFO_DECRYPT                         134
+#define CMS_F_CMS_RECIPIENTINFO_ENCRYPT                         169
 #define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT           135
 #define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT           136
 #define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID           137
index be20b1c..632dbae 100644 (file)
@@ -803,12 +803,34 @@ int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
                }
        }
 
+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
+       {
+       switch (ri->type)
+               {
+               case CMS_RECIPINFO_TRANS:
+               return cms_RecipientInfo_ktri_encrypt(cms, ri);
+
+               case CMS_RECIPINFO_KEK:
+               return cms_RecipientInfo_kekri_encrypt(cms, ri);
+               break;
+
+               case CMS_RECIPINFO_PASS:
+               return cms_RecipientInfo_pwri_crypt(cms, ri, 1);
+               break;
+
+               default:
+               CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT,
+                               CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
+               return 0;
+               }
+       }
+
 BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
        {
        CMS_EncryptedContentInfo *ec;
        STACK_OF(CMS_RecipientInfo) *rinfos;
        CMS_RecipientInfo *ri;
-       int i, r, ok = 0;
+       int i, ok = 0;
        BIO *ret;
 
        /* Get BIO first to set up key */
@@ -828,28 +850,7 @@ BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
        for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++)
                {
                ri = sk_CMS_RecipientInfo_value(rinfos, i);
-
-               switch (ri->type)
-                       {
-                       case CMS_RECIPINFO_TRANS:
-                       r = cms_RecipientInfo_ktri_encrypt(cms, ri);
-                       break;
-
-                       case CMS_RECIPINFO_KEK:
-                       r = cms_RecipientInfo_kekri_encrypt(cms, ri);
-                       break;
-
-                       case CMS_RECIPINFO_PASS:
-                       r = cms_RecipientInfo_pwri_crypt(cms, ri, 1);
-                       break;
-
-                       default:
-                       CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
-                               CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
-                       goto err;
-                       }
-
-               if (r <= 0)
+               if (CMS_RecipientInfo_encrypt(cms, ri) <= 0)
                        {
                        CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
                                CMS_R_ERROR_SETTING_RECIPIENTINFO);
index 8330ead..cc58ea5 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/cms/cms_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2009 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2013 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
@@ -114,6 +114,7 @@ static ERR_STRING_DATA CMS_str_functs[]=
 {ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0),   "CMS_ReceiptRequest_create0"},
 {ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY),   "cms_Receipt_verify"},
 {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT),    "CMS_RecipientInfo_decrypt"},
+{ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_ENCRYPT),    "CMS_RecipientInfo_encrypt"},
 {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT),      "CMS_RECIPIENTINFO_KEKRI_DECRYPT"},
 {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT),      "CMS_RECIPIENTINFO_KEKRI_ENCRYPT"},
 {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID),      "CMS_RecipientInfo_kekri_get0_id"},
index e035542..fa6bb16 100644 (file)
@@ -20,6 +20,7 @@
  int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, unsigned char *key, size_t keylen);
 
  int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+ int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
 
 =head1 DESCRIPTION
 
@@ -66,6 +67,11 @@ CMS_RecipientInfo_decrypt() attempts to decrypt CMS_RecipientInfo structure
 B<ri> in structure B<cms>. A key must have been associated with the structure
 first.
 
+CMS_RecipientInfo_encrypt() attempts to encrypt CMS_RecipientInfo structure
+B<ri> in structure B<cms>. A key must have been associated with the structure
+first and the content encryption key must be available: for example by a
+previous call to CMS_RecipientInfo_decrypt().
+
 =head1 NOTES
 
 The main purpose of these functions is to enable an application to lookup
@@ -81,6 +87,13 @@ any appropriate means it can then associated with the structure and
 CMS_RecpientInfo_decrypt() called. If successful CMS_decrypt() can be called
 with a NULL key to decrypt the enveloped content.
 
+The CMS_RecipientInfo_encrypt() can be used to add a new recipient to an
+existing enveloped data structure. Typically an application will first decrypt
+an appropriate CMS_RecipientInfo structure to make the content encrypt key
+available, it will then add a new recipient using a function such as
+CMS_add1_recipient_cert() and finally encrypt the content encryption key
+using CMS_RecipientInfo_encrypt().
+
 =head1 RETURN VALUES
 
 CMS_get0_RecipientInfos() returns all CMS_RecipientInfo structures, or NULL if
@@ -89,6 +102,7 @@ an error occurs.
 CMS_RecipientInfo_ktri_get0_signer_id(), CMS_RecipientInfo_set0_pkey(),
 CMS_RecipientInfo_kekri_get0_id(), CMS_RecipientInfo_set0_key() and
 CMS_RecipientInfo_decrypt() return 1 for success or 0 if an error occurs.
+CMS_RecipientInfo_encrypt() return 1 for success or 0 if an error occurs.
 
 CMS_RecipientInfo_ktri_cert_cmp() and CMS_RecipientInfo_kekri_cmp() return 0
 for a successful comparison and non zero otherwise.