Commit 4f1aa191 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Initial support for enveloped data decrypt. Extent runex.pl to cover these

examples. All RFC4134 examples can not be processed.
parent e540d1cd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
+28 −1
Original line number Diff line number Diff line
@@ -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
+0 −2
Original line number Diff line number Diff line
@@ -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);
	}
+4 −9
Original line number Diff line number Diff line
@@ -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);
	}
+90 −2
Original line number Diff line number Diff line
@@ -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);
	}
Loading