summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2019-08-10 15:55:20 +0000
committerjsing <>2019-08-10 15:55:20 +0000
commita0845ead6d459f388701fe3fe8fa27635f4885f1 (patch)
treecfa2d4e7280cbfe7b7007556c8dcab6691e87b83
parent38e170324f2dafb68786e79022ddafab241aad3d (diff)
downloadopenbsd-a0845ead6d459f388701fe3fe8fa27635f4885f1.tar.gz
openbsd-a0845ead6d459f388701fe3fe8fa27635f4885f1.tar.bz2
openbsd-a0845ead6d459f388701fe3fe8fa27635f4885f1.zip
Work towards supporting Cryptographic Message Syntax (CMS) in libcrypto.
Cryptographic Message Syntax (CMS) is a standard for cryptographically protecting messages, as defined in RFC 5652. It is derived from PKCS #7 version 1.5 and utilises various ASN.1 structures, making it complex and fairly heavyweight. Various protocols - including RPKI (RFC 6480) - have been built on top of it, which means it is necessary to support CMS, in order to support RPKI. This imports around 6,000 lines of code from OpenSSL 1.1.1, which is still under the original OpenSSL license. Further work will occur in tree. Requested by and discussed with many. ok deraadt@ tb@
-rw-r--r--src/lib/libcrypto/cms/cms_asn1.c403
-rw-r--r--src/lib/libcrypto/cms/cms_att.c152
-rw-r--r--src/lib/libcrypto/cms/cms_cd.c82
-rw-r--r--src/lib/libcrypto/cms/cms_dd.c99
-rw-r--r--src/lib/libcrypto/cms/cms_enc.c213
-rw-r--r--src/lib/libcrypto/cms/cms_env.c903
-rw-r--r--src/lib/libcrypto/cms/cms_err.c294
-rw-r--r--src/lib/libcrypto/cms/cms_ess.c337
-rw-r--r--src/lib/libcrypto/cms/cms_io.c88
-rw-r--r--src/lib/libcrypto/cms/cms_kari.c414
-rw-r--r--src/lib/libcrypto/cms/cms_lcl.h437
-rw-r--r--src/lib/libcrypto/cms/cms_lib.c587
-rw-r--r--src/lib/libcrypto/cms/cms_pwri.c394
-rw-r--r--src/lib/libcrypto/cms/cms_sd.c926
-rw-r--r--src/lib/libcrypto/cms/cms_smime.c843
15 files changed, 6172 insertions, 0 deletions
diff --git a/src/lib/libcrypto/cms/cms_asn1.c b/src/lib/libcrypto/cms/cms_asn1.c
new file mode 100644
index 0000000000..993ea6b219
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_asn1.c
@@ -0,0 +1,403 @@
1/*
2 * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <openssl/asn1t.h>
11#include <openssl/pem.h>
12#include <openssl/x509v3.h>
13#include <openssl/cms.h>
14#include "cms_lcl.h"
15
16
17ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = {
18 ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME),
19 ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER)
20} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber)
21
22ASN1_SEQUENCE(CMS_OtherCertificateFormat) = {
23 ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT),
24 ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY)
25} static_ASN1_SEQUENCE_END(CMS_OtherCertificateFormat)
26
27ASN1_CHOICE(CMS_CertificateChoices) = {
28 ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509),
29 ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0),
30 ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1),
31 ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2),
32 ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3)
33} ASN1_CHOICE_END(CMS_CertificateChoices)
34
35ASN1_CHOICE(CMS_SignerIdentifier) = {
36 ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
37 ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0)
38} static_ASN1_CHOICE_END(CMS_SignerIdentifier)
39
40ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
41 ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT),
42 ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0)
43} static_ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)
44
45/* Minor tweak to operation: free up signer key, cert */
46static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
47 void *exarg)
48{
49 if (operation == ASN1_OP_FREE_POST) {
50 CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
51 EVP_PKEY_free(si->pkey);
52 X509_free(si->signer);
53 EVP_MD_CTX_free(si->mctx);
54 }
55 return 1;
56}
57
58ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = {
59 ASN1_EMBED(CMS_SignerInfo, version, INT32),
60 ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier),
61 ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR),
62 ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0),
63 ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR),
64 ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING),
65 ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1)
66} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo)
67
68ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = {
69 ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT),
70 ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY)
71} static_ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat)
72
73ASN1_CHOICE(CMS_RevocationInfoChoice) = {
74 ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL),
75 ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1)
76} ASN1_CHOICE_END(CMS_RevocationInfoChoice)
77
78ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
79 ASN1_EMBED(CMS_SignedData, version, INT32),
80 ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR),
81 ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo),
82 ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
83 ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
84 ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
85} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
86
87ASN1_SEQUENCE(CMS_OriginatorInfo) = {
88 ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0),
89 ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1)
90} static_ASN1_SEQUENCE_END(CMS_OriginatorInfo)
91
92ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
93 ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
94 ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
95 ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
96} static_ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)
97
98ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
99 ASN1_EMBED(CMS_KeyTransRecipientInfo, version, INT32),
100 ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier),
101 ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
102 ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
103} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo)
104
105ASN1_SEQUENCE(CMS_OtherKeyAttribute) = {
106 ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT),
107 ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY)
108} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute)
109
110ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = {
111 ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING),
112 ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME),
113 ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute)
114} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier)
115
116ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = {
117 ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
118 ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0)
119} static_ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier)
120
121static int cms_rek_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
122 void *exarg)
123{
124 CMS_RecipientEncryptedKey *rek = (CMS_RecipientEncryptedKey *)*pval;
125 if (operation == ASN1_OP_FREE_POST) {
126 EVP_PKEY_free(rek->pkey);
127 }
128 return 1;
129}
130
131ASN1_SEQUENCE_cb(CMS_RecipientEncryptedKey, cms_rek_cb) = {
132 ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier),
133 ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING)
134} ASN1_SEQUENCE_END_cb(CMS_RecipientEncryptedKey, CMS_RecipientEncryptedKey)
135
136ASN1_SEQUENCE(CMS_OriginatorPublicKey) = {
137 ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR),
138 ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING)
139} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey)
140
141ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = {
142 ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
143 ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0),
144 ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1)
145} static_ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey)
146
147static int cms_kari_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
148 void *exarg)
149{
150 CMS_KeyAgreeRecipientInfo *kari = (CMS_KeyAgreeRecipientInfo *)*pval;
151 if (operation == ASN1_OP_NEW_POST) {
152 kari->ctx = EVP_CIPHER_CTX_new();
153 if (kari->ctx == NULL)
154 return 0;
155 EVP_CIPHER_CTX_set_flags(kari->ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
156 kari->pctx = NULL;
157 } else if (operation == ASN1_OP_FREE_POST) {
158 EVP_PKEY_CTX_free(kari->pctx);
159 EVP_CIPHER_CTX_free(kari->ctx);
160 }
161 return 1;
162}
163
164ASN1_SEQUENCE_cb(CMS_KeyAgreeRecipientInfo, cms_kari_cb) = {
165 ASN1_EMBED(CMS_KeyAgreeRecipientInfo, version, INT32),
166 ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0),
167 ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1),
168 ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
169 ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey)
170} ASN1_SEQUENCE_END_cb(CMS_KeyAgreeRecipientInfo, CMS_KeyAgreeRecipientInfo)
171
172ASN1_SEQUENCE(CMS_KEKIdentifier) = {
173 ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING),
174 ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME),
175 ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute)
176} static_ASN1_SEQUENCE_END(CMS_KEKIdentifier)
177
178ASN1_SEQUENCE(CMS_KEKRecipientInfo) = {
179 ASN1_EMBED(CMS_KEKRecipientInfo, version, INT32),
180 ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier),
181 ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
182 ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
183} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo)
184
185ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = {
186 ASN1_EMBED(CMS_PasswordRecipientInfo, version, INT32),
187 ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0),
188 ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
189 ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
190} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo)
191
192ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
193 ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT),
194 ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY)
195} static_ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)
196
197/* Free up RecipientInfo additional data */
198static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
199 void *exarg)
200{
201 if (operation == ASN1_OP_FREE_PRE) {
202 CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval;
203 if (ri->type == CMS_RECIPINFO_TRANS) {
204 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
205 EVP_PKEY_free(ktri->pkey);
206 X509_free(ktri->recip);
207 EVP_PKEY_CTX_free(ktri->pctx);
208 } else if (ri->type == CMS_RECIPINFO_KEK) {
209 CMS_KEKRecipientInfo *kekri = ri->d.kekri;
210 OPENSSL_clear_free(kekri->key, kekri->keylen);
211 } else if (ri->type == CMS_RECIPINFO_PASS) {
212 CMS_PasswordRecipientInfo *pwri = ri->d.pwri;
213 OPENSSL_clear_free(pwri->pass, pwri->passlen);
214 }
215 }
216 return 1;
217}
218
219ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = {
220 ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo),
221 ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1),
222 ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2),
223 ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3),
224 ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4)
225} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type)
226
227ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
228 ASN1_EMBED(CMS_EnvelopedData, version, INT32),
229 ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
230 ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo),
231 ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
232 ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
233} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
234
235ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
236 ASN1_EMBED(CMS_DigestedData, version, INT32),
237 ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR),
238 ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo),
239 ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING)
240} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData)
241
242ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = {
243 ASN1_EMBED(CMS_EncryptedData, version, INT32),
244 ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo),
245 ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
246} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData)
247
248ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
249 ASN1_EMBED(CMS_AuthenticatedData, version, INT32),
250 ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0),
251 ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo),
252 ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
253 ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
254 ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
255 ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
256 ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
257 ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
258} static_ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)
259
260ASN1_NDEF_SEQUENCE(CMS_CompressedData) = {
261 ASN1_EMBED(CMS_CompressedData, version, INT32),
262 ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR),
263 ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo),
264} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData)
265
266/* This is the ANY DEFINED BY table for the top level ContentInfo structure */
267
268ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);
269
270ASN1_ADB(CMS_ContentInfo) = {
271 ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)),
272 ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)),
273 ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)),
274 ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)),
275 ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)),
276 ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)),
277 ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
278} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);
279
280/* CMS streaming support */
281static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
282 void *exarg)
283{
284 ASN1_STREAM_ARG *sarg = exarg;
285 CMS_ContentInfo *cms = NULL;
286 if (pval)
287 cms = (CMS_ContentInfo *)*pval;
288 else
289 return 1;
290 switch (operation) {
291
292 case ASN1_OP_STREAM_PRE:
293 if (CMS_stream(&sarg->boundary, cms) <= 0)
294 return 0;
295 /* fall thru */
296 case ASN1_OP_DETACHED_PRE:
297 sarg->ndef_bio = CMS_dataInit(cms, sarg->out);
298 if (!sarg->ndef_bio)
299 return 0;
300 break;
301
302 case ASN1_OP_STREAM_POST:
303 case ASN1_OP_DETACHED_POST:
304 if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0)
305 return 0;
306 break;
307
308 }
309 return 1;
310}
311
312ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = {
313 ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
314 ASN1_ADB_OBJECT(CMS_ContentInfo)
315} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo)
316
317/* Specials for signed attributes */
318
319/*
320 * When signing attributes we want to reorder them to match the sorted
321 * encoding.
322 */
323
324ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) =
325 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
326ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign)
327
328/*
329 * When verifying attributes we need to use the received order. So we use
330 * SEQUENCE OF and tag it to SET OF
331 */
332
333ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) =
334 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
335 V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE)
336ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)
337
338
339
340ASN1_CHOICE(CMS_ReceiptsFrom) = {
341 ASN1_IMP_EMBED(CMS_ReceiptsFrom, d.allOrFirstTier, INT32, 0),
342 ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1)
343} static_ASN1_CHOICE_END(CMS_ReceiptsFrom)
344
345ASN1_SEQUENCE(CMS_ReceiptRequest) = {
346 ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING),
347 ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom),
348 ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
349} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
350
351ASN1_SEQUENCE(CMS_Receipt) = {
352 ASN1_EMBED(CMS_Receipt, version, INT32),
353 ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
354 ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
355 ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
356} ASN1_SEQUENCE_END(CMS_Receipt)
357
358/*
359 * Utilities to encode the CMS_SharedInfo structure used during key
360 * derivation.
361 */
362
363typedef struct {
364 X509_ALGOR *keyInfo;
365 ASN1_OCTET_STRING *entityUInfo;
366 ASN1_OCTET_STRING *suppPubInfo;
367} CMS_SharedInfo;
368
369ASN1_SEQUENCE(CMS_SharedInfo) = {
370 ASN1_SIMPLE(CMS_SharedInfo, keyInfo, X509_ALGOR),
371 ASN1_EXP_OPT(CMS_SharedInfo, entityUInfo, ASN1_OCTET_STRING, 0),
372 ASN1_EXP_OPT(CMS_SharedInfo, suppPubInfo, ASN1_OCTET_STRING, 2),
373} static_ASN1_SEQUENCE_END(CMS_SharedInfo)
374
375int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg,
376 ASN1_OCTET_STRING *ukm, int keylen)
377{
378 union {
379 CMS_SharedInfo *pecsi;
380 ASN1_VALUE *a;
381 } intsi = {
382 NULL
383 };
384
385 ASN1_OCTET_STRING oklen;
386 unsigned char kl[4];
387 CMS_SharedInfo ecsi;
388
389 keylen <<= 3;
390 kl[0] = (keylen >> 24) & 0xff;
391 kl[1] = (keylen >> 16) & 0xff;
392 kl[2] = (keylen >> 8) & 0xff;
393 kl[3] = keylen & 0xff;
394 oklen.length = 4;
395 oklen.data = kl;
396 oklen.type = V_ASN1_OCTET_STRING;
397 oklen.flags = 0;
398 ecsi.keyInfo = kekalg;
399 ecsi.entityUInfo = ukm;
400 ecsi.suppPubInfo = &oklen;
401 intsi.pecsi = &ecsi;
402 return ASN1_item_i2d(intsi.a, pder, ASN1_ITEM_rptr(CMS_SharedInfo));
403}
diff --git a/src/lib/libcrypto/cms/cms_att.c b/src/lib/libcrypto/cms/cms_att.c
new file mode 100644
index 0000000000..664e64971b
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_att.c
@@ -0,0 +1,152 @@
1/*
2 * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <openssl/asn1t.h>
11#include <openssl/pem.h>
12#include <openssl/x509v3.h>
13#include <openssl/err.h>
14#include <openssl/cms.h>
15#include "cms_lcl.h"
16
17/* CMS SignedData Attribute utilities */
18
19int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
20{
21 return X509at_get_attr_count(si->signedAttrs);
22}
23
24int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos)
25{
26 return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos);
27}
28
29int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, const ASN1_OBJECT *obj,
30 int lastpos)
31{
32 return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos);
33}
34
35X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
36{
37 return X509at_get_attr(si->signedAttrs, loc);
38}
39
40X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
41{
42 return X509at_delete_attr(si->signedAttrs, loc);
43}
44
45int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
46{
47 if (X509at_add1_attr(&si->signedAttrs, attr))
48 return 1;
49 return 0;
50}
51
52int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
53 const ASN1_OBJECT *obj, int type,
54 const void *bytes, int len)
55{
56 if (X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len))
57 return 1;
58 return 0;
59}
60
61int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
62 int nid, int type, const void *bytes, int len)
63{
64 if (X509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len))
65 return 1;
66 return 0;
67}
68
69int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
70 const char *attrname, int type,
71 const void *bytes, int len)
72{
73 if (X509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes, len))
74 return 1;
75 return 0;
76}
77
78void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, const ASN1_OBJECT *oid,
79 int lastpos, int type)
80{
81 return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
82}
83
84int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
85{
86 return X509at_get_attr_count(si->unsignedAttrs);
87}
88
89int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
90 int lastpos)
91{
92 return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos);
93}
94
95int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si,
96 const ASN1_OBJECT *obj, int lastpos)
97{
98 return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos);
99}
100
101X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
102{
103 return X509at_get_attr(si->unsignedAttrs, loc);
104}
105
106X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
107{
108 return X509at_delete_attr(si->unsignedAttrs, loc);
109}
110
111int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
112{
113 if (X509at_add1_attr(&si->unsignedAttrs, attr))
114 return 1;
115 return 0;
116}
117
118int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
119 const ASN1_OBJECT *obj, int type,
120 const void *bytes, int len)
121{
122 if (X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len))
123 return 1;
124 return 0;
125}
126
127int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
128 int nid, int type,
129 const void *bytes, int len)
130{
131 if (X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len))
132 return 1;
133 return 0;
134}
135
136int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
137 const char *attrname, int type,
138 const void *bytes, int len)
139{
140 if (X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
141 type, bytes, len))
142 return 1;
143 return 0;
144}
145
146void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
147 int lastpos, int type)
148{
149 return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
150}
151
152/* Specific attribute cases */
diff --git a/src/lib/libcrypto/cms/cms_cd.c b/src/lib/libcrypto/cms/cms_cd.c
new file mode 100644
index 0000000000..f05e308418
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_cd.c
@@ -0,0 +1,82 @@
1/*
2 * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/pem.h>
13#include <openssl/x509v3.h>
14#include <openssl/err.h>
15#include <openssl/cms.h>
16#include <openssl/bio.h>
17#include <openssl/comp.h>
18#include "cms_lcl.h"
19
20#ifdef ZLIB
21
22/* CMS CompressedData Utilities */
23
24CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
25{
26 CMS_ContentInfo *cms;
27 CMS_CompressedData *cd;
28 /*
29 * Will need something cleverer if there is ever more than one
30 * compression algorithm or parameters have some meaning...
31 */
32 if (comp_nid != NID_zlib_compression) {
33 CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE,
34 CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
35 return NULL;
36 }
37 cms = CMS_ContentInfo_new();
38 if (cms == NULL)
39 return NULL;
40
41 cd = M_ASN1_new_of(CMS_CompressedData);
42
43 if (cd == NULL)
44 goto err;
45
46 cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData);
47 cms->d.compressedData = cd;
48
49 cd->version = 0;
50
51 X509_ALGOR_set0(cd->compressionAlgorithm,
52 OBJ_nid2obj(NID_zlib_compression), V_ASN1_UNDEF, NULL);
53
54 cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
55
56 return cms;
57
58 err:
59 CMS_ContentInfo_free(cms);
60 return NULL;
61}
62
63BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms)
64{
65 CMS_CompressedData *cd;
66 const ASN1_OBJECT *compoid;
67 if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) {
68 CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
69 CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
70 return NULL;
71 }
72 cd = cms->d.compressedData;
73 X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm);
74 if (OBJ_obj2nid(compoid) != NID_zlib_compression) {
75 CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
76 CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
77 return NULL;
78 }
79 return BIO_new(BIO_f_zlib());
80}
81
82#endif
diff --git a/src/lib/libcrypto/cms/cms_dd.c b/src/lib/libcrypto/cms/cms_dd.c
new file mode 100644
index 0000000000..5da6802fcd
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_dd.c
@@ -0,0 +1,99 @@
1/*
2 * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/pem.h>
13#include <openssl/x509v3.h>
14#include <openssl/err.h>
15#include <openssl/cms.h>
16#include "cms_lcl.h"
17
18/* CMS DigestedData Utilities */
19
20CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
21{
22 CMS_ContentInfo *cms;
23 CMS_DigestedData *dd;
24 cms = CMS_ContentInfo_new();
25 if (cms == NULL)
26 return NULL;
27
28 dd = M_ASN1_new_of(CMS_DigestedData);
29
30 if (dd == NULL)
31 goto err;
32
33 cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
34 cms->d.digestedData = dd;
35
36 dd->version = 0;
37 dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
38
39 X509_ALGOR_set_md(dd->digestAlgorithm, md);
40
41 return cms;
42
43 err:
44 CMS_ContentInfo_free(cms);
45 return NULL;
46}
47
48BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
49{
50 CMS_DigestedData *dd;
51 dd = cms->d.digestedData;
52 return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
53}
54
55int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
56{
57 EVP_MD_CTX *mctx = EVP_MD_CTX_new();
58 unsigned char md[EVP_MAX_MD_SIZE];
59 unsigned int mdlen;
60 int r = 0;
61 CMS_DigestedData *dd;
62
63 if (mctx == NULL) {
64 CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, ERR_R_MALLOC_FAILURE);
65 goto err;
66 }
67
68 dd = cms->d.digestedData;
69
70 if (!cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm))
71 goto err;
72
73 if (EVP_DigestFinal_ex(mctx, md, &mdlen) <= 0)
74 goto err;
75
76 if (verify) {
77 if (mdlen != (unsigned int)dd->digest->length) {
78 CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
79 CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
80 goto err;
81 }
82
83 if (memcmp(md, dd->digest->data, mdlen))
84 CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
85 CMS_R_VERIFICATION_FAILURE);
86 else
87 r = 1;
88 } else {
89 if (!ASN1_STRING_set(dd->digest, md, mdlen))
90 goto err;
91 r = 1;
92 }
93
94 err:
95 EVP_MD_CTX_free(mctx);
96
97 return r;
98
99}
diff --git a/src/lib/libcrypto/cms/cms_enc.c b/src/lib/libcrypto/cms/cms_enc.c
new file mode 100644
index 0000000000..a1719830e8
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_enc.c
@@ -0,0 +1,213 @@
1/*
2 * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/pem.h>
13#include <openssl/x509v3.h>
14#include <openssl/err.h>
15#include <openssl/cms.h>
16#include <openssl/rand.h>
17#include "cms_lcl.h"
18
19/* CMS EncryptedData Utilities */
20
21/* Return BIO based on EncryptedContentInfo and key */
22
23BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
24{
25 BIO *b;
26 EVP_CIPHER_CTX *ctx;
27 const EVP_CIPHER *ciph;
28 X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
29 unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
30 unsigned char *tkey = NULL;
31 size_t tkeylen = 0;
32
33 int ok = 0;
34
35 int enc, keep_key = 0;
36
37 enc = ec->cipher ? 1 : 0;
38
39 b = BIO_new(BIO_f_cipher());
40 if (b == NULL) {
41 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
42 return NULL;
43 }
44
45 BIO_get_cipher_ctx(b, &ctx);
46
47 if (enc) {
48 ciph = ec->cipher;
49 /*
50 * If not keeping key set cipher to NULL so subsequent calls decrypt.
51 */
52 if (ec->key)
53 ec->cipher = NULL;
54 } else {
55 ciph = EVP_get_cipherbyobj(calg->algorithm);
56
57 if (!ciph) {
58 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER);
59 goto err;
60 }
61 }
62
63 if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) {
64 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
65 CMS_R_CIPHER_INITIALISATION_ERROR);
66 goto err;
67 }
68
69 if (enc) {
70 int ivlen;
71 calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
72 /* Generate a random IV if we need one */
73 ivlen = EVP_CIPHER_CTX_iv_length(ctx);
74 if (ivlen > 0) {
75 if (RAND_bytes(iv, ivlen) <= 0)
76 goto err;
77 piv = iv;
78 }
79 } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) {
80 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
81 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
82 goto err;
83 }
84 tkeylen = EVP_CIPHER_CTX_key_length(ctx);
85 /* Generate random session key */
86 if (!enc || !ec->key) {
87 tkey = OPENSSL_malloc(tkeylen);
88 if (tkey == NULL) {
89 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
90 goto err;
91 }
92 if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
93 goto err;
94 }
95
96 if (!ec->key) {
97 ec->key = tkey;
98 ec->keylen = tkeylen;
99 tkey = NULL;
100 if (enc)
101 keep_key = 1;
102 else
103 ERR_clear_error();
104
105 }
106
107 if (ec->keylen != tkeylen) {
108 /* If necessary set key length */
109 if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) {
110 /*
111 * Only reveal failure if debugging so we don't leak information
112 * which may be useful in MMA.
113 */
114 if (enc || ec->debug) {
115 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
116 CMS_R_INVALID_KEY_LENGTH);
117 goto err;
118 } else {
119 /* Use random key */
120 OPENSSL_clear_free(ec->key, ec->keylen);
121 ec->key = tkey;
122 ec->keylen = tkeylen;
123 tkey = NULL;
124 ERR_clear_error();
125 }
126 }
127 }
128
129 if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) {
130 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
131 CMS_R_CIPHER_INITIALISATION_ERROR);
132 goto err;
133 }
134 if (enc) {
135 calg->parameter = ASN1_TYPE_new();
136 if (calg->parameter == NULL) {
137 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
138 goto err;
139 }
140 if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) {
141 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
142 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
143 goto err;
144 }
145 /* If parameter type not set omit parameter */
146 if (calg->parameter->type == V_ASN1_UNDEF) {
147 ASN1_TYPE_free(calg->parameter);
148 calg->parameter = NULL;
149 }
150 }
151 ok = 1;
152
153 err:
154 if (!keep_key || !ok) {
155 OPENSSL_clear_free(ec->key, ec->keylen);
156 ec->key = NULL;
157 }
158 OPENSSL_clear_free(tkey, tkeylen);
159 if (ok)
160 return b;
161 BIO_free(b);
162 return NULL;
163}
164
165int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
166 const EVP_CIPHER *cipher,
167 const unsigned char *key, size_t keylen)
168{
169 ec->cipher = cipher;
170 if (key) {
171 if ((ec->key = OPENSSL_malloc(keylen)) == NULL) {
172 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT, ERR_R_MALLOC_FAILURE);
173 return 0;
174 }
175 memcpy(ec->key, key, keylen);
176 }
177 ec->keylen = keylen;
178 if (cipher)
179 ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
180 return 1;
181}
182
183int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
184 const unsigned char *key, size_t keylen)
185{
186 CMS_EncryptedContentInfo *ec;
187 if (!key || !keylen) {
188 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
189 return 0;
190 }
191 if (ciph) {
192 cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
193 if (!cms->d.encryptedData) {
194 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE);
195 return 0;
196 }
197 cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
198 cms->d.encryptedData->version = 0;
199 } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) {
200 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA);
201 return 0;
202 }
203 ec = cms->d.encryptedData->encryptedContentInfo;
204 return cms_EncryptedContent_init(ec, ciph, key, keylen);
205}
206
207BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
208{
209 CMS_EncryptedData *enc = cms->d.encryptedData;
210 if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
211 enc->version = 2;
212 return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
213}
diff --git a/src/lib/libcrypto/cms/cms_env.c b/src/lib/libcrypto/cms/cms_env.c
new file mode 100644
index 0000000000..bb95af75e3
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_env.c
@@ -0,0 +1,903 @@
1/*
2 * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/pem.h>
13#include <openssl/x509v3.h>
14#include <openssl/err.h>
15#include <openssl/cms.h>
16#include <openssl/aes.h>
17#include "cms_lcl.h"
18#include "internal/asn1_int.h"
19#include "internal/evp_int.h"
20
21/* CMS EnvelopedData Utilities */
22
23CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
24{
25 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) {
26 CMSerr(CMS_F_CMS_GET0_ENVELOPED,
27 CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
28 return NULL;
29 }
30 return cms->d.envelopedData;
31}
32
33static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
34{
35 if (cms->d.other == NULL) {
36 cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
37 if (!cms->d.envelopedData) {
38 CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE);
39 return NULL;
40 }
41 cms->d.envelopedData->version = 0;
42 cms->d.envelopedData->encryptedContentInfo->contentType =
43 OBJ_nid2obj(NID_pkcs7_data);
44 ASN1_OBJECT_free(cms->contentType);
45 cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
46 return cms->d.envelopedData;
47 }
48 return cms_get0_enveloped(cms);
49}
50
51int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
52{
53 EVP_PKEY *pkey;
54 int i;
55 if (ri->type == CMS_RECIPINFO_TRANS)
56 pkey = ri->d.ktri->pkey;
57 else if (ri->type == CMS_RECIPINFO_AGREE) {
58 EVP_PKEY_CTX *pctx = ri->d.kari->pctx;
59 if (!pctx)
60 return 0;
61 pkey = EVP_PKEY_CTX_get0_pkey(pctx);
62 if (!pkey)
63 return 0;
64 } else
65 return 0;
66 if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
67 return 1;
68 i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
69 if (i == -2) {
70 CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
71 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
72 return 0;
73 }
74 if (i <= 0) {
75 CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
76 return 0;
77 }
78 return 1;
79}
80
81STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
82{
83 CMS_EnvelopedData *env;
84 env = cms_get0_enveloped(cms);
85 if (!env)
86 return NULL;
87 return env->recipientInfos;
88}
89
90int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
91{
92 return ri->type;
93}
94
95EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
96{
97 if (ri->type == CMS_RECIPINFO_TRANS)
98 return ri->d.ktri->pctx;
99 else if (ri->type == CMS_RECIPINFO_AGREE)
100 return ri->d.kari->pctx;
101 return NULL;
102}
103
104CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
105{
106 CMS_ContentInfo *cms;
107 CMS_EnvelopedData *env;
108 cms = CMS_ContentInfo_new();
109 if (cms == NULL)
110 goto merr;
111 env = cms_enveloped_data_init(cms);
112 if (env == NULL)
113 goto merr;
114 if (!cms_EncryptedContent_init(env->encryptedContentInfo,
115 cipher, NULL, 0))
116 goto merr;
117 return cms;
118 merr:
119 CMS_ContentInfo_free(cms);
120 CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
121 return NULL;
122}
123
124/* Key Transport Recipient Info (KTRI) routines */
125
126/* Initialise a ktri based on passed certificate and key */
127
128static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
129 EVP_PKEY *pk, unsigned int flags)
130{
131 CMS_KeyTransRecipientInfo *ktri;
132 int idtype;
133
134 ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
135 if (!ri->d.ktri)
136 return 0;
137 ri->type = CMS_RECIPINFO_TRANS;
138
139 ktri = ri->d.ktri;
140
141 if (flags & CMS_USE_KEYID) {
142 ktri->version = 2;
143 idtype = CMS_RECIPINFO_KEYIDENTIFIER;
144 } else {
145 ktri->version = 0;
146 idtype = CMS_RECIPINFO_ISSUER_SERIAL;
147 }
148
149 /*
150 * Not a typo: RecipientIdentifier and SignerIdentifier are the same
151 * structure.
152 */
153
154 if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype))
155 return 0;
156
157 X509_up_ref(recip);
158 EVP_PKEY_up_ref(pk);
159
160 ktri->pkey = pk;
161 ktri->recip = recip;
162
163 if (flags & CMS_KEY_PARAM) {
164 ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
165 if (ktri->pctx == NULL)
166 return 0;
167 if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
168 return 0;
169 } else if (!cms_env_asn1_ctrl(ri, 0))
170 return 0;
171 return 1;
172}
173
174/*
175 * Add a recipient certificate using appropriate type of RecipientInfo
176 */
177
178CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
179 X509 *recip, unsigned int flags)
180{
181 CMS_RecipientInfo *ri = NULL;
182 CMS_EnvelopedData *env;
183 EVP_PKEY *pk = NULL;
184 env = cms_get0_enveloped(cms);
185 if (!env)
186 goto err;
187
188 /* Initialize recipient info */
189 ri = M_ASN1_new_of(CMS_RecipientInfo);
190 if (!ri)
191 goto merr;
192
193 pk = X509_get0_pubkey(recip);
194 if (!pk) {
195 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY);
196 goto err;
197 }
198
199 switch (cms_pkey_get_ri_type(pk)) {
200
201 case CMS_RECIPINFO_TRANS:
202 if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags))
203 goto err;
204 break;
205
206 case CMS_RECIPINFO_AGREE:
207 if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags))
208 goto err;
209 break;
210
211 default:
212 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
213 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
214 goto err;
215
216 }
217
218 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
219 goto merr;
220
221 return ri;
222
223 merr:
224 CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
225 err:
226 M_ASN1_free_of(ri, CMS_RecipientInfo);
227 return NULL;
228
229}
230
231int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
232 EVP_PKEY **pk, X509 **recip,
233 X509_ALGOR **palg)
234{
235 CMS_KeyTransRecipientInfo *ktri;
236 if (ri->type != CMS_RECIPINFO_TRANS) {
237 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
238 CMS_R_NOT_KEY_TRANSPORT);
239 return 0;
240 }
241
242 ktri = ri->d.ktri;
243
244 if (pk)
245 *pk = ktri->pkey;
246 if (recip)
247 *recip = ktri->recip;
248 if (palg)
249 *palg = ktri->keyEncryptionAlgorithm;
250 return 1;
251}
252
253int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
254 ASN1_OCTET_STRING **keyid,
255 X509_NAME **issuer,
256 ASN1_INTEGER **sno)
257{
258 CMS_KeyTransRecipientInfo *ktri;
259 if (ri->type != CMS_RECIPINFO_TRANS) {
260 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
261 CMS_R_NOT_KEY_TRANSPORT);
262 return 0;
263 }
264 ktri = ri->d.ktri;
265
266 return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno);
267}
268
269int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
270{
271 if (ri->type != CMS_RECIPINFO_TRANS) {
272 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
273 CMS_R_NOT_KEY_TRANSPORT);
274 return -2;
275 }
276 return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
277}
278
279int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
280{
281 if (ri->type != CMS_RECIPINFO_TRANS) {
282 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT);
283 return 0;
284 }
285 EVP_PKEY_free(ri->d.ktri->pkey);
286 ri->d.ktri->pkey = pkey;
287 return 1;
288}
289
290/* Encrypt content key in key transport recipient info */
291
292static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
293 CMS_RecipientInfo *ri)
294{
295 CMS_KeyTransRecipientInfo *ktri;
296 CMS_EncryptedContentInfo *ec;
297 EVP_PKEY_CTX *pctx;
298 unsigned char *ek = NULL;
299 size_t eklen;
300
301 int ret = 0;
302
303 if (ri->type != CMS_RECIPINFO_TRANS) {
304 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT);
305 return 0;
306 }
307 ktri = ri->d.ktri;
308 ec = cms->d.envelopedData->encryptedContentInfo;
309
310 pctx = ktri->pctx;
311
312 if (pctx) {
313 if (!cms_env_asn1_ctrl(ri, 0))
314 goto err;
315 } else {
316 pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
317 if (pctx == NULL)
318 return 0;
319
320 if (EVP_PKEY_encrypt_init(pctx) <= 0)
321 goto err;
322 }
323
324 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
325 EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) {
326 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
327 goto err;
328 }
329
330 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
331 goto err;
332
333 ek = OPENSSL_malloc(eklen);
334
335 if (ek == NULL) {
336 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
337 goto err;
338 }
339
340 if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
341 goto err;
342
343 ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
344 ek = NULL;
345
346 ret = 1;
347
348 err:
349 EVP_PKEY_CTX_free(pctx);
350 ktri->pctx = NULL;
351 OPENSSL_free(ek);
352 return ret;
353
354}
355
356/* Decrypt content key from KTRI */
357
358static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
359 CMS_RecipientInfo *ri)
360{
361 CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
362 EVP_PKEY *pkey = ktri->pkey;
363 unsigned char *ek = NULL;
364 size_t eklen;
365 int ret = 0;
366 CMS_EncryptedContentInfo *ec;
367 ec = cms->d.envelopedData->encryptedContentInfo;
368
369 if (ktri->pkey == NULL) {
370 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY);
371 return 0;
372 }
373
374 ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
375 if (ktri->pctx == NULL)
376 return 0;
377
378 if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
379 goto err;
380
381 if (!cms_env_asn1_ctrl(ri, 1))
382 goto err;
383
384 if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
385 EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) {
386 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
387 goto err;
388 }
389
390 if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
391 ktri->encryptedKey->data,
392 ktri->encryptedKey->length) <= 0)
393 goto err;
394
395 ek = OPENSSL_malloc(eklen);
396
397 if (ek == NULL) {
398 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE);
399 goto err;
400 }
401
402 if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
403 ktri->encryptedKey->data,
404 ktri->encryptedKey->length) <= 0) {
405 CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
406 goto err;
407 }
408
409 ret = 1;
410
411 OPENSSL_clear_free(ec->key, ec->keylen);
412 ec->key = ek;
413 ec->keylen = eklen;
414
415 err:
416 EVP_PKEY_CTX_free(ktri->pctx);
417 ktri->pctx = NULL;
418 if (!ret)
419 OPENSSL_free(ek);
420
421 return ret;
422}
423
424/* Key Encrypted Key (KEK) RecipientInfo routines */
425
426int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
427 const unsigned char *id, size_t idlen)
428{
429 ASN1_OCTET_STRING tmp_os;
430 CMS_KEKRecipientInfo *kekri;
431 if (ri->type != CMS_RECIPINFO_KEK) {
432 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
433 return -2;
434 }
435 kekri = ri->d.kekri;
436 tmp_os.type = V_ASN1_OCTET_STRING;
437 tmp_os.flags = 0;
438 tmp_os.data = (unsigned char *)id;
439 tmp_os.length = (int)idlen;
440 return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
441}
442
443/* For now hard code AES key wrap info */
444
445static size_t aes_wrap_keylen(int nid)
446{
447 switch (nid) {
448 case NID_id_aes128_wrap:
449 return 16;
450
451 case NID_id_aes192_wrap:
452 return 24;
453
454 case NID_id_aes256_wrap:
455 return 32;
456
457 default:
458 return 0;
459 }
460}
461
462CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
463 unsigned char *key, size_t keylen,
464 unsigned char *id, size_t idlen,
465 ASN1_GENERALIZEDTIME *date,
466 ASN1_OBJECT *otherTypeId,
467 ASN1_TYPE *otherType)
468{
469 CMS_RecipientInfo *ri = NULL;
470 CMS_EnvelopedData *env;
471 CMS_KEKRecipientInfo *kekri;
472 env = cms_get0_enveloped(cms);
473 if (!env)
474 goto err;
475
476 if (nid == NID_undef) {
477 switch (keylen) {
478 case 16:
479 nid = NID_id_aes128_wrap;
480 break;
481
482 case 24:
483 nid = NID_id_aes192_wrap;
484 break;
485
486 case 32:
487 nid = NID_id_aes256_wrap;
488 break;
489
490 default:
491 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
492 goto err;
493 }
494
495 } else {
496
497 size_t exp_keylen = aes_wrap_keylen(nid);
498
499 if (!exp_keylen) {
500 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
501 CMS_R_UNSUPPORTED_KEK_ALGORITHM);
502 goto err;
503 }
504
505 if (keylen != exp_keylen) {
506 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
507 goto err;
508 }
509
510 }
511
512 /* Initialize recipient info */
513 ri = M_ASN1_new_of(CMS_RecipientInfo);
514 if (!ri)
515 goto merr;
516
517 ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
518 if (!ri->d.kekri)
519 goto merr;
520 ri->type = CMS_RECIPINFO_KEK;
521
522 kekri = ri->d.kekri;
523
524 if (otherTypeId) {
525 kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
526 if (kekri->kekid->other == NULL)
527 goto merr;
528 }
529
530 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
531 goto merr;
532
533 /* After this point no calls can fail */
534
535 kekri->version = 4;
536
537 kekri->key = key;
538 kekri->keylen = keylen;
539
540 ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
541
542 kekri->kekid->date = date;
543
544 if (kekri->kekid->other) {
545 kekri->kekid->other->keyAttrId = otherTypeId;
546 kekri->kekid->other->keyAttr = otherType;
547 }
548
549 X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
550 OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
551
552 return ri;
553
554 merr:
555 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
556 err:
557 M_ASN1_free_of(ri, CMS_RecipientInfo);
558 return NULL;
559
560}
561
562int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
563 X509_ALGOR **palg,
564 ASN1_OCTET_STRING **pid,
565 ASN1_GENERALIZEDTIME **pdate,
566 ASN1_OBJECT **potherid,
567 ASN1_TYPE **pothertype)
568{
569 CMS_KEKIdentifier *rkid;
570 if (ri->type != CMS_RECIPINFO_KEK) {
571 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
572 return 0;
573 }
574 rkid = ri->d.kekri->kekid;
575 if (palg)
576 *palg = ri->d.kekri->keyEncryptionAlgorithm;
577 if (pid)
578 *pid = rkid->keyIdentifier;
579 if (pdate)
580 *pdate = rkid->date;
581 if (potherid) {
582 if (rkid->other)
583 *potherid = rkid->other->keyAttrId;
584 else
585 *potherid = NULL;
586 }
587 if (pothertype) {
588 if (rkid->other)
589 *pothertype = rkid->other->keyAttr;
590 else
591 *pothertype = NULL;
592 }
593 return 1;
594}
595
596int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
597 unsigned char *key, size_t keylen)
598{
599 CMS_KEKRecipientInfo *kekri;
600 if (ri->type != CMS_RECIPINFO_KEK) {
601 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
602 return 0;
603 }
604
605 kekri = ri->d.kekri;
606 kekri->key = key;
607 kekri->keylen = keylen;
608 return 1;
609}
610
611/* Encrypt content key in KEK recipient info */
612
613static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
614 CMS_RecipientInfo *ri)
615{
616 CMS_EncryptedContentInfo *ec;
617 CMS_KEKRecipientInfo *kekri;
618 AES_KEY actx;
619 unsigned char *wkey = NULL;
620 int wkeylen;
621 int r = 0;
622
623 ec = cms->d.envelopedData->encryptedContentInfo;
624
625 kekri = ri->d.kekri;
626
627 if (!kekri->key) {
628 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
629 return 0;
630 }
631
632 if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
633 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
634 CMS_R_ERROR_SETTING_KEY);
635 goto err;
636 }
637
638 wkey = OPENSSL_malloc(ec->keylen + 8);
639
640 if (wkey == NULL) {
641 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
642 goto err;
643 }
644
645 wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
646
647 if (wkeylen <= 0) {
648 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
649 goto err;
650 }
651
652 ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
653
654 r = 1;
655
656 err:
657
658 if (!r)
659 OPENSSL_free(wkey);
660 OPENSSL_cleanse(&actx, sizeof(actx));
661
662 return r;
663
664}
665
666/* Decrypt content key in KEK recipient info */
667
668static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
669 CMS_RecipientInfo *ri)
670{
671 CMS_EncryptedContentInfo *ec;
672 CMS_KEKRecipientInfo *kekri;
673 AES_KEY actx;
674 unsigned char *ukey = NULL;
675 int ukeylen;
676 int r = 0, wrap_nid;
677
678 ec = cms->d.envelopedData->encryptedContentInfo;
679
680 kekri = ri->d.kekri;
681
682 if (!kekri->key) {
683 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
684 return 0;
685 }
686
687 wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
688 if (aes_wrap_keylen(wrap_nid) != kekri->keylen) {
689 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
690 CMS_R_INVALID_KEY_LENGTH);
691 return 0;
692 }
693
694 /* If encrypted key length is invalid don't bother */
695
696 if (kekri->encryptedKey->length < 16) {
697 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
698 CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
699 goto err;
700 }
701
702 if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
703 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
704 CMS_R_ERROR_SETTING_KEY);
705 goto err;
706 }
707
708 ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
709
710 if (ukey == NULL) {
711 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE);
712 goto err;
713 }
714
715 ukeylen = AES_unwrap_key(&actx, NULL, ukey,
716 kekri->encryptedKey->data,
717 kekri->encryptedKey->length);
718
719 if (ukeylen <= 0) {
720 CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR);
721 goto err;
722 }
723
724 ec->key = ukey;
725 ec->keylen = ukeylen;
726
727 r = 1;
728
729 err:
730
731 if (!r)
732 OPENSSL_free(ukey);
733 OPENSSL_cleanse(&actx, sizeof(actx));
734
735 return r;
736
737}
738
739int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
740{
741 switch (ri->type) {
742 case CMS_RECIPINFO_TRANS:
743 return cms_RecipientInfo_ktri_decrypt(cms, ri);
744
745 case CMS_RECIPINFO_KEK:
746 return cms_RecipientInfo_kekri_decrypt(cms, ri);
747
748 case CMS_RECIPINFO_PASS:
749 return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
750
751 default:
752 CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
753 CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE);
754 return 0;
755 }
756}
757
758int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
759{
760 switch (ri->type) {
761 case CMS_RECIPINFO_TRANS:
762 return cms_RecipientInfo_ktri_encrypt(cms, ri);
763
764 case CMS_RECIPINFO_AGREE:
765 return cms_RecipientInfo_kari_encrypt(cms, ri);
766
767 case CMS_RECIPINFO_KEK:
768 return cms_RecipientInfo_kekri_encrypt(cms, ri);
769
770 case CMS_RECIPINFO_PASS:
771 return cms_RecipientInfo_pwri_crypt(cms, ri, 1);
772
773 default:
774 CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT,
775 CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
776 return 0;
777 }
778}
779
780/* Check structures and fixup version numbers (if necessary) */
781
782static void cms_env_set_originfo_version(CMS_EnvelopedData *env)
783{
784 CMS_OriginatorInfo *org = env->originatorInfo;
785 int i;
786 if (org == NULL)
787 return;
788 for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) {
789 CMS_CertificateChoices *cch;
790 cch = sk_CMS_CertificateChoices_value(org->certificates, i);
791 if (cch->type == CMS_CERTCHOICE_OTHER) {
792 env->version = 4;
793 return;
794 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
795 if (env->version < 3)
796 env->version = 3;
797 }
798 }
799
800 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) {
801 CMS_RevocationInfoChoice *rch;
802 rch = sk_CMS_RevocationInfoChoice_value(org->crls, i);
803 if (rch->type == CMS_REVCHOICE_OTHER) {
804 env->version = 4;
805 return;
806 }
807 }
808}
809
810static void cms_env_set_version(CMS_EnvelopedData *env)
811{
812 int i;
813 CMS_RecipientInfo *ri;
814
815 /*
816 * Can't set version higher than 4 so if 4 or more already nothing to do.
817 */
818 if (env->version >= 4)
819 return;
820
821 cms_env_set_originfo_version(env);
822
823 if (env->version >= 3)
824 return;
825
826 for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) {
827 ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i);
828 if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) {
829 env->version = 3;
830 return;
831 } else if (ri->type != CMS_RECIPINFO_TRANS
832 || ri->d.ktri->version != 0) {
833 env->version = 2;
834 }
835 }
836 if (env->originatorInfo || env->unprotectedAttrs)
837 env->version = 2;
838 if (env->version == 2)
839 return;
840 env->version = 0;
841}
842
843BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
844{
845 CMS_EncryptedContentInfo *ec;
846 STACK_OF(CMS_RecipientInfo) *rinfos;
847 CMS_RecipientInfo *ri;
848 int i, ok = 0;
849 BIO *ret;
850
851 /* Get BIO first to set up key */
852
853 ec = cms->d.envelopedData->encryptedContentInfo;
854 ret = cms_EncryptedContent_init_bio(ec);
855
856 /* If error or no cipher end of processing */
857
858 if (!ret || !ec->cipher)
859 return ret;
860
861 /* Now encrypt content key according to each RecipientInfo type */
862
863 rinfos = cms->d.envelopedData->recipientInfos;
864
865 for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
866 ri = sk_CMS_RecipientInfo_value(rinfos, i);
867 if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) {
868 CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
869 CMS_R_ERROR_SETTING_RECIPIENTINFO);
870 goto err;
871 }
872 }
873 cms_env_set_version(cms->d.envelopedData);
874
875 ok = 1;
876
877 err:
878 ec->cipher = NULL;
879 OPENSSL_clear_free(ec->key, ec->keylen);
880 ec->key = NULL;
881 ec->keylen = 0;
882 if (ok)
883 return ret;
884 BIO_free(ret);
885 return NULL;
886
887}
888
889/*
890 * Get RecipientInfo type (if any) supported by a key (public or private). To
891 * retain compatibility with previous behaviour if the ctrl value isn't
892 * supported we assume key transport.
893 */
894int cms_pkey_get_ri_type(EVP_PKEY *pk)
895{
896 if (pk->ameth && pk->ameth->pkey_ctrl) {
897 int i, r;
898 i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r);
899 if (i > 0)
900 return r;
901 }
902 return CMS_RECIPINFO_TRANS;
903}
diff --git a/src/lib/libcrypto/cms/cms_err.c b/src/lib/libcrypto/cms/cms_err.c
new file mode 100644
index 0000000000..4432b471ee
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_err.c
@@ -0,0 +1,294 @@
1/*
2 * Generated by util/mkerr.pl DO NOT EDIT
3 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
4 *
5 * Licensed under the OpenSSL license (the "License"). You may not use
6 * this file except in compliance with the License. You can obtain a copy
7 * in the file LICENSE in the source distribution or at
8 * https://www.openssl.org/source/license.html
9 */
10
11#include <openssl/err.h>
12#include <openssl/cmserr.h>
13
14#ifndef OPENSSL_NO_ERR
15
16static const ERR_STRING_DATA CMS_str_functs[] = {
17 {ERR_PACK(ERR_LIB_CMS, CMS_F_CHECK_CONTENT, 0), "check_content"},
18 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD0_CERT, 0), "CMS_add0_cert"},
19 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD0_RECIPIENT_KEY, 0),
20 "CMS_add0_recipient_key"},
21 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, 0),
22 "CMS_add0_recipient_password"},
23 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECEIPTREQUEST, 0),
24 "CMS_add1_ReceiptRequest"},
25 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_RECIPIENT_CERT, 0),
26 "CMS_add1_recipient_cert"},
27 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNER, 0), "CMS_add1_signer"},
28 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNINGTIME, 0),
29 "cms_add1_signingTime"},
30 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESS, 0), "CMS_compress"},
31 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESSEDDATA_CREATE, 0),
32 "cms_CompressedData_create"},
33 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, 0),
34 "cms_CompressedData_init_bio"},
35 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COPY_CONTENT, 0), "cms_copy_content"},
36 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COPY_MESSAGEDIGEST, 0),
37 "cms_copy_messageDigest"},
38 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DATA, 0), "CMS_data"},
39 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DATAFINAL, 0), "CMS_dataFinal"},
40 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DATAINIT, 0), "CMS_dataInit"},
41 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT, 0), "CMS_decrypt"},
42 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_KEY, 0),
43 "CMS_decrypt_set1_key"},
44 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PASSWORD, 0),
45 "CMS_decrypt_set1_password"},
46 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DECRYPT_SET1_PKEY, 0),
47 "CMS_decrypt_set1_pkey"},
48 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, 0),
49 "cms_DigestAlgorithm_find_ctx"},
50 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, 0),
51 "cms_DigestAlgorithm_init_bio"},
52 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGESTEDDATA_DO_FINAL, 0),
53 "cms_DigestedData_do_final"},
54 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_DIGEST_VERIFY, 0), "CMS_digest_verify"},
55 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCODE_RECEIPT, 0), "cms_encode_Receipt"},
56 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPT, 0), "CMS_encrypt"},
57 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDCONTENT_INIT, 0),
58 "cms_EncryptedContent_init"},
59 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, 0),
60 "cms_EncryptedContent_init_bio"},
61 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, 0),
62 "CMS_EncryptedData_decrypt"},
63 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, 0),
64 "CMS_EncryptedData_encrypt"},
65 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, 0),
66 "CMS_EncryptedData_set1_key"},
67 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_CREATE, 0),
68 "CMS_EnvelopedData_create"},
69 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, 0),
70 "cms_EnvelopedData_init_bio"},
71 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENVELOPED_DATA_INIT, 0),
72 "cms_enveloped_data_init"},
73 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ENV_ASN1_CTRL, 0), "cms_env_asn1_ctrl"},
74 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_FINAL, 0), "CMS_final"},
75 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_CERTIFICATE_CHOICES, 0),
76 "cms_get0_certificate_choices"},
77 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_CONTENT, 0), "CMS_get0_content"},
78 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_ECONTENT_TYPE, 0),
79 "cms_get0_econtent_type"},
80 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_ENVELOPED, 0), "cms_get0_enveloped"},
81 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_REVOCATION_CHOICES, 0),
82 "cms_get0_revocation_choices"},
83 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_GET0_SIGNED, 0), "cms_get0_signed"},
84 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_MSGSIGDIGEST_ADD1, 0),
85 "cms_msgSigDigest_add1"},
86 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECEIPTREQUEST_CREATE0, 0),
87 "CMS_ReceiptRequest_create0"},
88 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECEIPT_VERIFY, 0), "cms_Receipt_verify"},
89 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_DECRYPT, 0),
90 "CMS_RecipientInfo_decrypt"},
91 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_ENCRYPT, 0),
92 "CMS_RecipientInfo_encrypt"},
93 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, 0),
94 "cms_RecipientInfo_kari_encrypt"},
95 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG, 0),
96 "CMS_RecipientInfo_kari_get0_alg"},
97 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID, 0),
98 "CMS_RecipientInfo_kari_get0_orig_id"},
99 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS, 0),
100 "CMS_RecipientInfo_kari_get0_reks"},
101 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP, 0),
102 "CMS_RecipientInfo_kari_orig_id_cmp"},
103 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, 0),
104 "cms_RecipientInfo_kekri_decrypt"},
105 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, 0),
106 "cms_RecipientInfo_kekri_encrypt"},
107 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, 0),
108 "CMS_RecipientInfo_kekri_get0_id"},
109 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, 0),
110 "CMS_RecipientInfo_kekri_id_cmp"},
111 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, 0),
112 "CMS_RecipientInfo_ktri_cert_cmp"},
113 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, 0),
114 "cms_RecipientInfo_ktri_decrypt"},
115 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, 0),
116 "cms_RecipientInfo_ktri_encrypt"},
117 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, 0),
118 "CMS_RecipientInfo_ktri_get0_algs"},
119 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, 0),
120 "CMS_RecipientInfo_ktri_get0_signer_id"},
121 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, 0),
122 "cms_RecipientInfo_pwri_crypt"},
123 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_SET0_KEY, 0),
124 "CMS_RecipientInfo_set0_key"},
125 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, 0),
126 "CMS_RecipientInfo_set0_password"},
127 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, 0),
128 "CMS_RecipientInfo_set0_pkey"},
129 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SD_ASN1_CTRL, 0), "cms_sd_asn1_ctrl"},
130 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET1_IAS, 0), "cms_set1_ias"},
131 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET1_KEYID, 0), "cms_set1_keyid"},
132 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET1_SIGNERIDENTIFIER, 0),
133 "cms_set1_SignerIdentifier"},
134 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SET_DETACHED, 0), "CMS_set_detached"},
135 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGN, 0), "CMS_sign"},
136 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNED_DATA_INIT, 0),
137 "cms_signed_data_init"},
138 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, 0),
139 "cms_SignerInfo_content_sign"},
140 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_SIGN, 0),
141 "CMS_SignerInfo_sign"},
142 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY, 0),
143 "CMS_SignerInfo_verify"},
144 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY_CERT, 0),
145 "cms_signerinfo_verify_cert"},
146 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, 0),
147 "CMS_SignerInfo_verify_content"},
148 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_SIGN_RECEIPT, 0), "CMS_sign_receipt"},
149 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_STREAM, 0), "CMS_stream"},
150 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_UNCOMPRESS, 0), "CMS_uncompress"},
151 {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_VERIFY, 0), "CMS_verify"},
152 {ERR_PACK(ERR_LIB_CMS, CMS_F_KEK_UNWRAP_KEY, 0), "kek_unwrap_key"},
153 {0, NULL}
154};
155
156static const ERR_STRING_DATA CMS_str_reasons[] = {
157 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ADD_SIGNER_ERROR), "add signer error"},
158 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_ALREADY_PRESENT),
159 "certificate already present"},
160 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_HAS_NO_KEYID),
161 "certificate has no keyid"},
162 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_VERIFY_ERROR),
163 "certificate verify error"},
164 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_INITIALISATION_ERROR),
165 "cipher initialisation error"},
166 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),
167 "cipher parameter initialisation error"},
168 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CMS_DATAFINAL_ERROR),
169 "cms datafinal error"},
170 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CMS_LIB), "cms lib"},
171 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENTIDENTIFIER_MISMATCH),
172 "contentidentifier mismatch"},
173 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_NOT_FOUND), "content not found"},
174 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_MISMATCH),
175 "content type mismatch"},
176 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),
177 "content type not compressed data"},
178 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),
179 "content type not enveloped data"},
180 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),
181 "content type not signed data"},
182 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_VERIFY_ERROR),
183 "content verify error"},
184 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_ERROR), "ctrl error"},
185 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_FAILURE), "ctrl failure"},
186 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECRYPT_ERROR), "decrypt error"},
187 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_GETTING_PUBLIC_KEY),
188 "error getting public key"},
189 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),
190 "error reading messagedigest attribute"},
191 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_KEY), "error setting key"},
192 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_RECIPIENTINFO),
193 "error setting recipientinfo"},
194 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),
195 "invalid encrypted key length"},
196 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),
197 "invalid key encryption parameter"},
198 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_LENGTH), "invalid key length"},
199 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MD_BIO_INIT_ERROR), "md bio init error"},
200 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),
201 "messagedigest attribute wrong length"},
202 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_WRONG_LENGTH),
203 "messagedigest wrong length"},
204 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error"},
205 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),
206 "msgsigdigest verification failure"},
207 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_WRONG_LENGTH),
208 "msgsigdigest wrong length"},
209 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NEED_ONE_SIGNER), "need one signer"},
210 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_A_SIGNED_RECEIPT),
211 "not a signed receipt"},
212 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data"},
213 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEK), "not kek"},
214 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEY_AGREEMENT), "not key agreement"},
215 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEY_TRANSPORT), "not key transport"},
216 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_PWRI), "not pwri"},
217 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),
218 "not supported for this key type"},
219 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CIPHER), "no cipher"},
220 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CONTENT), "no content"},
221 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CONTENT_TYPE), "no content type"},
222 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_DEFAULT_DIGEST), "no default digest"},
223 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_DIGEST_SET), "no digest set"},
224 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_KEY), "no key"},
225 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_KEY_OR_CERT), "no key or cert"},
226 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_DIGEST), "no matching digest"},
227 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_RECIPIENT),
228 "no matching recipient"},
229 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_SIGNATURE),
230 "no matching signature"},
231 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest"},
232 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PASSWORD), "no password"},
233 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PRIVATE_KEY), "no private key"},
234 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key"},
235 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request"},
236 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers"},
237 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
238 "private key does not match certificate"},
239 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECEIPT_DECODE_ERROR),
240 "receipt decode error"},
241 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECIPIENT_ERROR), "recipient error"},
242 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),
243 "signer certificate not found"},
244 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNFINAL_ERROR), "signfinal error"},
245 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SMIME_TEXT_ERROR), "smime text error"},
246 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_STORE_INIT_ERROR), "store init error"},
247 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_COMPRESSED_DATA),
248 "type not compressed data"},
249 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_DATA), "type not data"},
250 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_DIGESTED_DATA),
251 "type not digested data"},
252 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_ENCRYPTED_DATA),
253 "type not encrypted data"},
254 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_ENVELOPED_DATA),
255 "type not enveloped data"},
256 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNABLE_TO_FINALIZE_CONTEXT),
257 "unable to finalize context"},
258 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_CIPHER), "unknown cipher"},
259 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_DIGEST_ALGORITHM),
260 "unknown digest algorithm"},
261 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_ID), "unknown id"},
262 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),
263 "unsupported compression algorithm"},
264 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_TYPE),
265 "unsupported content type"},
266 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEK_ALGORITHM),
267 "unsupported kek algorithm"},
268 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),
269 "unsupported key encryption algorithm"},
270 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE),
271 "unsupported recipientinfo type"},
272 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENT_TYPE),
273 "unsupported recipient type"},
274 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_TYPE), "unsupported type"},
275 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNWRAP_ERROR), "unwrap error"},
276 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNWRAP_FAILURE), "unwrap failure"},
277 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_VERIFICATION_FAILURE),
278 "verification failure"},
279 {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_WRAP_ERROR), "wrap error"},
280 {0, NULL}
281};
282
283#endif
284
285int ERR_load_CMS_strings(void)
286{
287#ifndef OPENSSL_NO_ERR
288 if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) {
289 ERR_load_strings_const(CMS_str_functs);
290 ERR_load_strings_const(CMS_str_reasons);
291 }
292#endif
293 return 1;
294}
diff --git a/src/lib/libcrypto/cms/cms_ess.c b/src/lib/libcrypto/cms/cms_ess.c
new file mode 100644
index 0000000000..4780231c22
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_ess.c
@@ -0,0 +1,337 @@
1/*
2 * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/pem.h>
13#include <openssl/rand.h>
14#include <openssl/x509v3.h>
15#include <openssl/err.h>
16#include <openssl/cms.h>
17#include "cms_lcl.h"
18
19IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
20
21/* ESS services: for now just Signed Receipt related */
22
23int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
24{
25 ASN1_STRING *str;
26 CMS_ReceiptRequest *rr = NULL;
27 if (prr)
28 *prr = NULL;
29 str = CMS_signed_get0_data_by_OBJ(si,
30 OBJ_nid2obj
31 (NID_id_smime_aa_receiptRequest), -3,
32 V_ASN1_SEQUENCE);
33 if (!str)
34 return 0;
35
36 rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
37 if (!rr)
38 return -1;
39 if (prr)
40 *prr = rr;
41 else
42 CMS_ReceiptRequest_free(rr);
43 return 1;
44}
45
46CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
47 int allorfirst,
48 STACK_OF(GENERAL_NAMES)
49 *receiptList, STACK_OF(GENERAL_NAMES)
50 *receiptsTo)
51{
52 CMS_ReceiptRequest *rr = NULL;
53
54 rr = CMS_ReceiptRequest_new();
55 if (rr == NULL)
56 goto merr;
57 if (id)
58 ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
59 else {
60 if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
61 goto merr;
62 if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0)
63 goto err;
64 }
65
66 sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
67 rr->receiptsTo = receiptsTo;
68
69 if (receiptList) {
70 rr->receiptsFrom->type = 1;
71 rr->receiptsFrom->d.receiptList = receiptList;
72 } else {
73 rr->receiptsFrom->type = 0;
74 rr->receiptsFrom->d.allOrFirstTier = allorfirst;
75 }
76
77 return rr;
78
79 merr:
80 CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
81
82 err:
83 CMS_ReceiptRequest_free(rr);
84 return NULL;
85
86}
87
88int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
89{
90 unsigned char *rrder = NULL;
91 int rrderlen, r = 0;
92
93 rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
94 if (rrderlen < 0)
95 goto merr;
96
97 if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
98 V_ASN1_SEQUENCE, rrder, rrderlen))
99 goto merr;
100
101 r = 1;
102
103 merr:
104 if (!r)
105 CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);
106
107 OPENSSL_free(rrder);
108
109 return r;
110
111}
112
113void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
114 ASN1_STRING **pcid,
115 int *pallorfirst,
116 STACK_OF(GENERAL_NAMES) **plist,
117 STACK_OF(GENERAL_NAMES) **prto)
118{
119 if (pcid)
120 *pcid = rr->signedContentIdentifier;
121 if (rr->receiptsFrom->type == 0) {
122 if (pallorfirst)
123 *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
124 if (plist)
125 *plist = NULL;
126 } else {
127 if (pallorfirst)
128 *pallorfirst = -1;
129 if (plist)
130 *plist = rr->receiptsFrom->d.receiptList;
131 }
132 if (prto)
133 *prto = rr->receiptsTo;
134}
135
136/* Digest a SignerInfo structure for msgSigDigest attribute processing */
137
138static int cms_msgSigDigest(CMS_SignerInfo *si,
139 unsigned char *dig, unsigned int *diglen)
140{
141 const EVP_MD *md;
142 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
143 if (md == NULL)
144 return 0;
145 if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
146 si->signedAttrs, dig, diglen))
147 return 0;
148 return 1;
149}
150
151/* Add a msgSigDigest attribute to a SignerInfo */
152
153int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
154{
155 unsigned char dig[EVP_MAX_MD_SIZE];
156 unsigned int diglen;
157 if (!cms_msgSigDigest(src, dig, &diglen)) {
158 CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
159 return 0;
160 }
161 if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
162 V_ASN1_OCTET_STRING, dig, diglen)) {
163 CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
164 return 0;
165 }
166 return 1;
167}
168
169/* Verify signed receipt after it has already passed normal CMS verify */
170
171int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
172{
173 int r = 0, i;
174 CMS_ReceiptRequest *rr = NULL;
175 CMS_Receipt *rct = NULL;
176 STACK_OF(CMS_SignerInfo) *sis, *osis;
177 CMS_SignerInfo *si, *osi = NULL;
178 ASN1_OCTET_STRING *msig, **pcont;
179 ASN1_OBJECT *octype;
180 unsigned char dig[EVP_MAX_MD_SIZE];
181 unsigned int diglen;
182
183 /* Get SignerInfos, also checks SignedData content type */
184 osis = CMS_get0_SignerInfos(req_cms);
185 sis = CMS_get0_SignerInfos(cms);
186 if (!osis || !sis)
187 goto err;
188
189 if (sk_CMS_SignerInfo_num(sis) != 1) {
190 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
191 goto err;
192 }
193
194 /* Check receipt content type */
195 if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) {
196 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
197 goto err;
198 }
199
200 /* Extract and decode receipt content */
201 pcont = CMS_get0_content(cms);
202 if (!pcont || !*pcont) {
203 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
204 goto err;
205 }
206
207 rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
208
209 if (!rct) {
210 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
211 goto err;
212 }
213
214 /* Locate original request */
215
216 for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) {
217 osi = sk_CMS_SignerInfo_value(osis, i);
218 if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue))
219 break;
220 }
221
222 if (i == sk_CMS_SignerInfo_num(osis)) {
223 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
224 goto err;
225 }
226
227 si = sk_CMS_SignerInfo_value(sis, 0);
228
229 /* Get msgSigDigest value and compare */
230
231 msig = CMS_signed_get0_data_by_OBJ(si,
232 OBJ_nid2obj
233 (NID_id_smime_aa_msgSigDigest), -3,
234 V_ASN1_OCTET_STRING);
235
236 if (!msig) {
237 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
238 goto err;
239 }
240
241 if (!cms_msgSigDigest(osi, dig, &diglen)) {
242 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
243 goto err;
244 }
245
246 if (diglen != (unsigned int)msig->length) {
247 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
248 goto err;
249 }
250
251 if (memcmp(dig, msig->data, diglen)) {
252 CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
253 CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
254 goto err;
255 }
256
257 /* Compare content types */
258
259 octype = CMS_signed_get0_data_by_OBJ(osi,
260 OBJ_nid2obj(NID_pkcs9_contentType),
261 -3, V_ASN1_OBJECT);
262 if (!octype) {
263 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
264 goto err;
265 }
266
267 /* Compare details in receipt request */
268
269 if (OBJ_cmp(octype, rct->contentType)) {
270 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
271 goto err;
272 }
273
274 /* Get original receipt request details */
275
276 if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) {
277 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
278 goto err;
279 }
280
281 if (ASN1_STRING_cmp(rr->signedContentIdentifier,
282 rct->signedContentIdentifier)) {
283 CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH);
284 goto err;
285 }
286
287 r = 1;
288
289 err:
290 CMS_ReceiptRequest_free(rr);
291 M_ASN1_free_of(rct, CMS_Receipt);
292 return r;
293
294}
295
296/*
297 * Encode a Receipt into an OCTET STRING read for including into content of a
298 * SignedData ContentInfo.
299 */
300
301ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
302{
303 CMS_Receipt rct;
304 CMS_ReceiptRequest *rr = NULL;
305 ASN1_OBJECT *ctype;
306 ASN1_OCTET_STRING *os = NULL;
307
308 /* Get original receipt request */
309
310 /* Get original receipt request details */
311
312 if (CMS_get1_ReceiptRequest(si, &rr) <= 0) {
313 CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
314 goto err;
315 }
316
317 /* Get original content type */
318
319 ctype = CMS_signed_get0_data_by_OBJ(si,
320 OBJ_nid2obj(NID_pkcs9_contentType),
321 -3, V_ASN1_OBJECT);
322 if (!ctype) {
323 CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
324 goto err;
325 }
326
327 rct.version = 1;
328 rct.contentType = ctype;
329 rct.signedContentIdentifier = rr->signedContentIdentifier;
330 rct.originatorSignatureValue = si->signature;
331
332 os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);
333
334 err:
335 CMS_ReceiptRequest_free(rr);
336 return os;
337}
diff --git a/src/lib/libcrypto/cms/cms_io.c b/src/lib/libcrypto/cms/cms_io.c
new file mode 100644
index 0000000000..d18f980a97
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_io.c
@@ -0,0 +1,88 @@
1/*
2 * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <openssl/asn1t.h>
11#include <openssl/x509.h>
12#include <openssl/err.h>
13#include <openssl/pem.h>
14#include <openssl/cms.h>
15#include "cms_lcl.h"
16
17int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
18{
19 ASN1_OCTET_STRING **pos;
20 pos = CMS_get0_content(cms);
21 if (pos == NULL)
22 return 0;
23 if (*pos == NULL)
24 *pos = ASN1_OCTET_STRING_new();
25 if (*pos != NULL) {
26 (*pos)->flags |= ASN1_STRING_FLAG_NDEF;
27 (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
28 *boundary = &(*pos)->data;
29 return 1;
30 }
31 CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE);
32 return 0;
33}
34
35CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
36{
37 return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
38}
39
40int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
41{
42 return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
43}
44
45IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
46
47BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms)
48{
49 return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
50 ASN1_ITEM_rptr(CMS_ContentInfo));
51}
52
53/* CMS wrappers round generalised stream and MIME routines */
54
55int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
56{
57 return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
58 ASN1_ITEM_rptr(CMS_ContentInfo));
59}
60
61int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
62 int flags)
63{
64 return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)cms, in, flags,
65 "CMS", ASN1_ITEM_rptr(CMS_ContentInfo));
66}
67
68int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
69{
70 STACK_OF(X509_ALGOR) *mdalgs;
71 int ctype_nid = OBJ_obj2nid(cms->contentType);
72 int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
73 if (ctype_nid == NID_pkcs7_signed)
74 mdalgs = cms->d.signedData->digestAlgorithms;
75 else
76 mdalgs = NULL;
77
78 return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
79 ctype_nid, econt_nid, mdalgs,
80 ASN1_ITEM_rptr(CMS_ContentInfo));
81}
82
83CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
84{
85 return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
86 ASN1_ITEM_rptr
87 (CMS_ContentInfo));
88}
diff --git a/src/lib/libcrypto/cms/cms_kari.c b/src/lib/libcrypto/cms/cms_kari.c
new file mode 100644
index 0000000000..5e83814d0f
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_kari.c
@@ -0,0 +1,414 @@
1/*
2 * Copyright 2013-2019 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/pem.h>
13#include <openssl/x509v3.h>
14#include <openssl/err.h>
15#include <openssl/cms.h>
16#include <openssl/aes.h>
17#include "cms_lcl.h"
18#include "internal/asn1_int.h"
19
20/* Key Agreement Recipient Info (KARI) routines */
21
22int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
23 X509_ALGOR **palg,
24 ASN1_OCTET_STRING **pukm)
25{
26 if (ri->type != CMS_RECIPINFO_AGREE) {
27 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG,
28 CMS_R_NOT_KEY_AGREEMENT);
29 return 0;
30 }
31 if (palg)
32 *palg = ri->d.kari->keyEncryptionAlgorithm;
33 if (pukm)
34 *pukm = ri->d.kari->ukm;
35 return 1;
36}
37
38/* Retrieve recipient encrypted keys from a kari */
39
40STACK_OF(CMS_RecipientEncryptedKey)
41*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
42{
43 if (ri->type != CMS_RECIPINFO_AGREE) {
44 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS,
45 CMS_R_NOT_KEY_AGREEMENT);
46 return NULL;
47 }
48 return ri->d.kari->recipientEncryptedKeys;
49}
50
51int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
52 X509_ALGOR **pubalg,
53 ASN1_BIT_STRING **pubkey,
54 ASN1_OCTET_STRING **keyid,
55 X509_NAME **issuer,
56 ASN1_INTEGER **sno)
57{
58 CMS_OriginatorIdentifierOrKey *oik;
59 if (ri->type != CMS_RECIPINFO_AGREE) {
60 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID,
61 CMS_R_NOT_KEY_AGREEMENT);
62 return 0;
63 }
64 oik = ri->d.kari->originator;
65 if (issuer)
66 *issuer = NULL;
67 if (sno)
68 *sno = NULL;
69 if (keyid)
70 *keyid = NULL;
71 if (pubalg)
72 *pubalg = NULL;
73 if (pubkey)
74 *pubkey = NULL;
75 if (oik->type == CMS_OIK_ISSUER_SERIAL) {
76 if (issuer)
77 *issuer = oik->d.issuerAndSerialNumber->issuer;
78 if (sno)
79 *sno = oik->d.issuerAndSerialNumber->serialNumber;
80 } else if (oik->type == CMS_OIK_KEYIDENTIFIER) {
81 if (keyid)
82 *keyid = oik->d.subjectKeyIdentifier;
83 } else if (oik->type == CMS_OIK_PUBKEY) {
84 if (pubalg)
85 *pubalg = oik->d.originatorKey->algorithm;
86 if (pubkey)
87 *pubkey = oik->d.originatorKey->publicKey;
88 } else
89 return 0;
90 return 1;
91}
92
93int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
94{
95 CMS_OriginatorIdentifierOrKey *oik;
96 if (ri->type != CMS_RECIPINFO_AGREE) {
97 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP,
98 CMS_R_NOT_KEY_AGREEMENT);
99 return -2;
100 }
101 oik = ri->d.kari->originator;
102 if (oik->type == CMS_OIK_ISSUER_SERIAL)
103 return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
104 else if (oik->type == CMS_OIK_KEYIDENTIFIER)
105 return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
106 return -1;
107}
108
109int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
110 ASN1_OCTET_STRING **keyid,
111 ASN1_GENERALIZEDTIME **tm,
112 CMS_OtherKeyAttribute **other,
113 X509_NAME **issuer, ASN1_INTEGER **sno)
114{
115 CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
116 if (rid->type == CMS_REK_ISSUER_SERIAL) {
117 if (issuer)
118 *issuer = rid->d.issuerAndSerialNumber->issuer;
119 if (sno)
120 *sno = rid->d.issuerAndSerialNumber->serialNumber;
121 if (keyid)
122 *keyid = NULL;
123 if (tm)
124 *tm = NULL;
125 if (other)
126 *other = NULL;
127 } else if (rid->type == CMS_REK_KEYIDENTIFIER) {
128 if (keyid)
129 *keyid = rid->d.rKeyId->subjectKeyIdentifier;
130 if (tm)
131 *tm = rid->d.rKeyId->date;
132 if (other)
133 *other = rid->d.rKeyId->other;
134 if (issuer)
135 *issuer = NULL;
136 if (sno)
137 *sno = NULL;
138 } else
139 return 0;
140 return 1;
141}
142
143int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
144 X509 *cert)
145{
146 CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
147 if (rid->type == CMS_REK_ISSUER_SERIAL)
148 return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
149 else if (rid->type == CMS_REK_KEYIDENTIFIER)
150 return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert);
151 else
152 return -1;
153}
154
155int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
156{
157 EVP_PKEY_CTX *pctx;
158 CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
159
160 EVP_PKEY_CTX_free(kari->pctx);
161 kari->pctx = NULL;
162 if (!pk)
163 return 1;
164 pctx = EVP_PKEY_CTX_new(pk, NULL);
165 if (!pctx || !EVP_PKEY_derive_init(pctx))
166 goto err;
167 kari->pctx = pctx;
168 return 1;
169 err:
170 EVP_PKEY_CTX_free(pctx);
171 return 0;
172}
173
174EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
175{
176 if (ri->type == CMS_RECIPINFO_AGREE)
177 return ri->d.kari->ctx;
178 return NULL;
179}
180
181/*
182 * Derive KEK and decrypt/encrypt with it to produce either the original CEK
183 * or the encrypted CEK.
184 */
185
186static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
187 const unsigned char *in, size_t inlen,
188 CMS_KeyAgreeRecipientInfo *kari, int enc)
189{
190 /* Key encryption key */
191 unsigned char kek[EVP_MAX_KEY_LENGTH];
192 size_t keklen;
193 int rv = 0;
194 unsigned char *out = NULL;
195 int outlen;
196 keklen = EVP_CIPHER_CTX_key_length(kari->ctx);
197 if (keklen > EVP_MAX_KEY_LENGTH)
198 return 0;
199 /* Derive KEK */
200 if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
201 goto err;
202 /* Set KEK in context */
203 if (!EVP_CipherInit_ex(kari->ctx, NULL, NULL, kek, NULL, enc))
204 goto err;
205 /* obtain output length of ciphered key */
206 if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, inlen))
207 goto err;
208 out = OPENSSL_malloc(outlen);
209 if (out == NULL)
210 goto err;
211 if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, inlen))
212 goto err;
213 *pout = out;
214 *poutlen = (size_t)outlen;
215 rv = 1;
216
217 err:
218 OPENSSL_cleanse(kek, keklen);
219 if (!rv)
220 OPENSSL_free(out);
221 EVP_CIPHER_CTX_reset(kari->ctx);
222 /* FIXME: WHY IS kari->pctx freed here? /RL */
223 EVP_PKEY_CTX_free(kari->pctx);
224 kari->pctx = NULL;
225 return rv;
226}
227
228int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
229 CMS_RecipientInfo *ri,
230 CMS_RecipientEncryptedKey *rek)
231{
232 int rv = 0;
233 unsigned char *enckey = NULL, *cek = NULL;
234 size_t enckeylen;
235 size_t ceklen;
236 CMS_EncryptedContentInfo *ec;
237 enckeylen = rek->encryptedKey->length;
238 enckey = rek->encryptedKey->data;
239 /* Setup all parameters to derive KEK */
240 if (!cms_env_asn1_ctrl(ri, 1))
241 goto err;
242 /* Attempt to decrypt CEK */
243 if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
244 goto err;
245 ec = cms->d.envelopedData->encryptedContentInfo;
246 OPENSSL_clear_free(ec->key, ec->keylen);
247 ec->key = cek;
248 ec->keylen = ceklen;
249 cek = NULL;
250 rv = 1;
251 err:
252 OPENSSL_free(cek);
253 return rv;
254}
255
256/* Create ephemeral key and initialise context based on it */
257static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
258 EVP_PKEY *pk)
259{
260 EVP_PKEY_CTX *pctx = NULL;
261 EVP_PKEY *ekey = NULL;
262 int rv = 0;
263 pctx = EVP_PKEY_CTX_new(pk, NULL);
264 if (!pctx)
265 goto err;
266 if (EVP_PKEY_keygen_init(pctx) <= 0)
267 goto err;
268 if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
269 goto err;
270 EVP_PKEY_CTX_free(pctx);
271 pctx = EVP_PKEY_CTX_new(ekey, NULL);
272 if (!pctx)
273 goto err;
274 if (EVP_PKEY_derive_init(pctx) <= 0)
275 goto err;
276 kari->pctx = pctx;
277 rv = 1;
278 err:
279 if (!rv)
280 EVP_PKEY_CTX_free(pctx);
281 EVP_PKEY_free(ekey);
282 return rv;
283}
284
285/* Initialise a kari based on passed certificate and key */
286
287int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
288 EVP_PKEY *pk, unsigned int flags)
289{
290 CMS_KeyAgreeRecipientInfo *kari;
291 CMS_RecipientEncryptedKey *rek = NULL;
292
293 ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
294 if (!ri->d.kari)
295 return 0;
296 ri->type = CMS_RECIPINFO_AGREE;
297
298 kari = ri->d.kari;
299 kari->version = 3;
300
301 rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
302 if (rek == NULL)
303 return 0;
304
305 if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
306 M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
307 return 0;
308 }
309
310 if (flags & CMS_USE_KEYID) {
311 rek->rid->type = CMS_REK_KEYIDENTIFIER;
312 rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier);
313 if (rek->rid->d.rKeyId == NULL)
314 return 0;
315 if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
316 return 0;
317 } else {
318 rek->rid->type = CMS_REK_ISSUER_SERIAL;
319 if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
320 return 0;
321 }
322
323 /* Create ephemeral key */
324 if (!cms_kari_create_ephemeral_key(kari, pk))
325 return 0;
326
327 EVP_PKEY_up_ref(pk);
328 rek->pkey = pk;
329 return 1;
330}
331
332static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
333 const EVP_CIPHER *cipher)
334{
335 EVP_CIPHER_CTX *ctx = kari->ctx;
336 const EVP_CIPHER *kekcipher;
337 int keylen = EVP_CIPHER_key_length(cipher);
338 /* If a suitable wrap algorithm is already set nothing to do */
339 kekcipher = EVP_CIPHER_CTX_cipher(ctx);
340
341 if (kekcipher) {
342 if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE)
343 return 0;
344 return 1;
345 }
346 /*
347 * Pick a cipher based on content encryption cipher. If it is DES3 use
348 * DES3 wrap otherwise use AES wrap similar to key size.
349 */
350#ifndef OPENSSL_NO_DES
351 if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
352 kekcipher = EVP_des_ede3_wrap();
353 else
354#endif
355 if (keylen <= 16)
356 kekcipher = EVP_aes_128_wrap();
357 else if (keylen <= 24)
358 kekcipher = EVP_aes_192_wrap();
359 else
360 kekcipher = EVP_aes_256_wrap();
361 return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);
362}
363
364/* Encrypt content key in key agreement recipient info */
365
366int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
367 CMS_RecipientInfo *ri)
368{
369 CMS_KeyAgreeRecipientInfo *kari;
370 CMS_EncryptedContentInfo *ec;
371 CMS_RecipientEncryptedKey *rek;
372 STACK_OF(CMS_RecipientEncryptedKey) *reks;
373 int i;
374
375 if (ri->type != CMS_RECIPINFO_AGREE) {
376 CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT);
377 return 0;
378 }
379 kari = ri->d.kari;
380 reks = kari->recipientEncryptedKeys;
381 ec = cms->d.envelopedData->encryptedContentInfo;
382 /* Initialise wrap algorithm parameters */
383 if (!cms_wrap_init(kari, ec->cipher))
384 return 0;
385 /*
386 * If no originator key set up initialise for ephemeral key the public key
387 * ASN1 structure will set the actual public key value.
388 */
389 if (kari->originator->type == -1) {
390 CMS_OriginatorIdentifierOrKey *oik = kari->originator;
391 oik->type = CMS_OIK_PUBKEY;
392 oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
393 if (!oik->d.originatorKey)
394 return 0;
395 }
396 /* Initialise KDF algorithm */
397 if (!cms_env_asn1_ctrl(ri, 0))
398 return 0;
399 /* For each rek, derive KEK, encrypt CEK */
400 for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
401 unsigned char *enckey;
402 size_t enckeylen;
403 rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
404 if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
405 return 0;
406 if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
407 kari, 1))
408 return 0;
409 ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen);
410 }
411
412 return 1;
413
414}
diff --git a/src/lib/libcrypto/cms/cms_lcl.h b/src/lib/libcrypto/cms/cms_lcl.h
new file mode 100644
index 0000000000..916fcbfbe1
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_lcl.h
@@ -0,0 +1,437 @@
1/*
2 * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#ifndef HEADER_CMS_LCL_H
11# define HEADER_CMS_LCL_H
12
13# include <openssl/x509.h>
14
15/*
16 * Cryptographic message syntax (CMS) structures: taken from RFC3852
17 */
18
19/* Forward references */
20
21typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
22typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
23typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
24typedef struct CMS_SignedData_st CMS_SignedData;
25typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
26typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
27typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
28typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
29typedef struct CMS_DigestedData_st CMS_DigestedData;
30typedef struct CMS_EncryptedData_st CMS_EncryptedData;
31typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
32typedef struct CMS_CompressedData_st CMS_CompressedData;
33typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
34typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
35typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
36typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
37typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
38typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
39typedef struct CMS_KeyAgreeRecipientIdentifier_st
40 CMS_KeyAgreeRecipientIdentifier;
41typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
42typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
43typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
44typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
45typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
46
47struct CMS_ContentInfo_st {
48 ASN1_OBJECT *contentType;
49 union {
50 ASN1_OCTET_STRING *data;
51 CMS_SignedData *signedData;
52 CMS_EnvelopedData *envelopedData;
53 CMS_DigestedData *digestedData;
54 CMS_EncryptedData *encryptedData;
55 CMS_AuthenticatedData *authenticatedData;
56 CMS_CompressedData *compressedData;
57 ASN1_TYPE *other;
58 /* Other types ... */
59 void *otherData;
60 } d;
61};
62
63DEFINE_STACK_OF(CMS_CertificateChoices)
64
65struct CMS_SignedData_st {
66 int32_t version;
67 STACK_OF(X509_ALGOR) *digestAlgorithms;
68 CMS_EncapsulatedContentInfo *encapContentInfo;
69 STACK_OF(CMS_CertificateChoices) *certificates;
70 STACK_OF(CMS_RevocationInfoChoice) *crls;
71 STACK_OF(CMS_SignerInfo) *signerInfos;
72};
73
74struct CMS_EncapsulatedContentInfo_st {
75 ASN1_OBJECT *eContentType;
76 ASN1_OCTET_STRING *eContent;
77 /* Set to 1 if incomplete structure only part set up */
78 int partial;
79};
80
81struct CMS_SignerInfo_st {
82 int32_t version;
83 CMS_SignerIdentifier *sid;
84 X509_ALGOR *digestAlgorithm;
85 STACK_OF(X509_ATTRIBUTE) *signedAttrs;
86 X509_ALGOR *signatureAlgorithm;
87 ASN1_OCTET_STRING *signature;
88 STACK_OF(X509_ATTRIBUTE) *unsignedAttrs;
89 /* Signing certificate and key */
90 X509 *signer;
91 EVP_PKEY *pkey;
92 /* Digest and public key context for alternative parameters */
93 EVP_MD_CTX *mctx;
94 EVP_PKEY_CTX *pctx;
95};
96
97struct CMS_SignerIdentifier_st {
98 int type;
99 union {
100 CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
101 ASN1_OCTET_STRING *subjectKeyIdentifier;
102 } d;
103};
104
105struct CMS_EnvelopedData_st {
106 int32_t version;
107 CMS_OriginatorInfo *originatorInfo;
108 STACK_OF(CMS_RecipientInfo) *recipientInfos;
109 CMS_EncryptedContentInfo *encryptedContentInfo;
110 STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
111};
112
113struct CMS_OriginatorInfo_st {
114 STACK_OF(CMS_CertificateChoices) *certificates;
115 STACK_OF(CMS_RevocationInfoChoice) *crls;
116};
117
118struct CMS_EncryptedContentInfo_st {
119 ASN1_OBJECT *contentType;
120 X509_ALGOR *contentEncryptionAlgorithm;
121 ASN1_OCTET_STRING *encryptedContent;
122 /* Content encryption algorithm and key */
123 const EVP_CIPHER *cipher;
124 unsigned char *key;
125 size_t keylen;
126 /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
127 int debug;
128};
129
130struct CMS_RecipientInfo_st {
131 int type;
132 union {
133 CMS_KeyTransRecipientInfo *ktri;
134 CMS_KeyAgreeRecipientInfo *kari;
135 CMS_KEKRecipientInfo *kekri;
136 CMS_PasswordRecipientInfo *pwri;
137 CMS_OtherRecipientInfo *ori;
138 } d;
139};
140
141typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
142
143struct CMS_KeyTransRecipientInfo_st {
144 int32_t version;
145 CMS_RecipientIdentifier *rid;
146 X509_ALGOR *keyEncryptionAlgorithm;
147 ASN1_OCTET_STRING *encryptedKey;
148 /* Recipient Key and cert */
149 X509 *recip;
150 EVP_PKEY *pkey;
151 /* Public key context for this operation */
152 EVP_PKEY_CTX *pctx;
153};
154
155struct CMS_KeyAgreeRecipientInfo_st {
156 int32_t version;
157 CMS_OriginatorIdentifierOrKey *originator;
158 ASN1_OCTET_STRING *ukm;
159 X509_ALGOR *keyEncryptionAlgorithm;
160 STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys;
161 /* Public key context associated with current operation */
162 EVP_PKEY_CTX *pctx;
163 /* Cipher context for CEK wrapping */
164 EVP_CIPHER_CTX *ctx;
165};
166
167struct CMS_OriginatorIdentifierOrKey_st {
168 int type;
169 union {
170 CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
171 ASN1_OCTET_STRING *subjectKeyIdentifier;
172 CMS_OriginatorPublicKey *originatorKey;
173 } d;
174};
175
176struct CMS_OriginatorPublicKey_st {
177 X509_ALGOR *algorithm;
178 ASN1_BIT_STRING *publicKey;
179};
180
181struct CMS_RecipientEncryptedKey_st {
182 CMS_KeyAgreeRecipientIdentifier *rid;
183 ASN1_OCTET_STRING *encryptedKey;
184 /* Public key associated with this recipient */
185 EVP_PKEY *pkey;
186};
187
188struct CMS_KeyAgreeRecipientIdentifier_st {
189 int type;
190 union {
191 CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
192 CMS_RecipientKeyIdentifier *rKeyId;
193 } d;
194};
195
196struct CMS_RecipientKeyIdentifier_st {
197 ASN1_OCTET_STRING *subjectKeyIdentifier;
198 ASN1_GENERALIZEDTIME *date;
199 CMS_OtherKeyAttribute *other;
200};
201
202struct CMS_KEKRecipientInfo_st {
203 int32_t version;
204 CMS_KEKIdentifier *kekid;
205 X509_ALGOR *keyEncryptionAlgorithm;
206 ASN1_OCTET_STRING *encryptedKey;
207 /* Extra info: symmetric key to use */
208 unsigned char *key;
209 size_t keylen;
210};
211
212struct CMS_KEKIdentifier_st {
213 ASN1_OCTET_STRING *keyIdentifier;
214 ASN1_GENERALIZEDTIME *date;
215 CMS_OtherKeyAttribute *other;
216};
217
218struct CMS_PasswordRecipientInfo_st {
219 int32_t version;
220 X509_ALGOR *keyDerivationAlgorithm;
221 X509_ALGOR *keyEncryptionAlgorithm;
222 ASN1_OCTET_STRING *encryptedKey;
223 /* Extra info: password to use */
224 unsigned char *pass;
225 size_t passlen;
226};
227
228struct CMS_OtherRecipientInfo_st {
229 ASN1_OBJECT *oriType;
230 ASN1_TYPE *oriValue;
231};
232
233struct CMS_DigestedData_st {
234 int32_t version;
235 X509_ALGOR *digestAlgorithm;
236 CMS_EncapsulatedContentInfo *encapContentInfo;
237 ASN1_OCTET_STRING *digest;
238};
239
240struct CMS_EncryptedData_st {
241 int32_t version;
242 CMS_EncryptedContentInfo *encryptedContentInfo;
243 STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
244};
245
246struct CMS_AuthenticatedData_st {
247 int32_t version;
248 CMS_OriginatorInfo *originatorInfo;
249 STACK_OF(CMS_RecipientInfo) *recipientInfos;
250 X509_ALGOR *macAlgorithm;
251 X509_ALGOR *digestAlgorithm;
252 CMS_EncapsulatedContentInfo *encapContentInfo;
253 STACK_OF(X509_ATTRIBUTE) *authAttrs;
254 ASN1_OCTET_STRING *mac;
255 STACK_OF(X509_ATTRIBUTE) *unauthAttrs;
256};
257
258struct CMS_CompressedData_st {
259 int32_t version;
260 X509_ALGOR *compressionAlgorithm;
261 STACK_OF(CMS_RecipientInfo) *recipientInfos;
262 CMS_EncapsulatedContentInfo *encapContentInfo;
263};
264
265struct CMS_RevocationInfoChoice_st {
266 int type;
267 union {
268 X509_CRL *crl;
269 CMS_OtherRevocationInfoFormat *other;
270 } d;
271};
272
273# define CMS_REVCHOICE_CRL 0
274# define CMS_REVCHOICE_OTHER 1
275
276struct CMS_OtherRevocationInfoFormat_st {
277 ASN1_OBJECT *otherRevInfoFormat;
278 ASN1_TYPE *otherRevInfo;
279};
280
281struct CMS_CertificateChoices {
282 int type;
283 union {
284 X509 *certificate;
285 ASN1_STRING *extendedCertificate; /* Obsolete */
286 ASN1_STRING *v1AttrCert; /* Left encoded for now */
287 ASN1_STRING *v2AttrCert; /* Left encoded for now */
288 CMS_OtherCertificateFormat *other;
289 } d;
290};
291
292# define CMS_CERTCHOICE_CERT 0
293# define CMS_CERTCHOICE_EXCERT 1
294# define CMS_CERTCHOICE_V1ACERT 2
295# define CMS_CERTCHOICE_V2ACERT 3
296# define CMS_CERTCHOICE_OTHER 4
297
298struct CMS_OtherCertificateFormat_st {
299 ASN1_OBJECT *otherCertFormat;
300 ASN1_TYPE *otherCert;
301};
302
303/*
304 * This is also defined in pkcs7.h but we duplicate it to allow the CMS code
305 * to be independent of PKCS#7
306 */
307
308struct CMS_IssuerAndSerialNumber_st {
309 X509_NAME *issuer;
310 ASN1_INTEGER *serialNumber;
311};
312
313struct CMS_OtherKeyAttribute_st {
314 ASN1_OBJECT *keyAttrId;
315 ASN1_TYPE *keyAttr;
316};
317
318/* ESS structures */
319
320# ifdef HEADER_X509V3_H
321
322struct CMS_ReceiptRequest_st {
323 ASN1_OCTET_STRING *signedContentIdentifier;
324 CMS_ReceiptsFrom *receiptsFrom;
325 STACK_OF(GENERAL_NAMES) *receiptsTo;
326};
327
328struct CMS_ReceiptsFrom_st {
329 int type;
330 union {
331 int32_t allOrFirstTier;
332 STACK_OF(GENERAL_NAMES) *receiptList;
333 } d;
334};
335# endif
336
337struct CMS_Receipt_st {
338 int32_t version;
339 ASN1_OBJECT *contentType;
340 ASN1_OCTET_STRING *signedContentIdentifier;
341 ASN1_OCTET_STRING *originatorSignatureValue;
342};
343
344DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
345DECLARE_ASN1_ITEM(CMS_SignerInfo)
346DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
347DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
348DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
349DECLARE_ASN1_ITEM(CMS_RecipientInfo)
350DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo)
351DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
352
353# define CMS_SIGNERINFO_ISSUER_SERIAL 0
354# define CMS_SIGNERINFO_KEYIDENTIFIER 1
355
356# define CMS_RECIPINFO_ISSUER_SERIAL 0
357# define CMS_RECIPINFO_KEYIDENTIFIER 1
358
359# define CMS_REK_ISSUER_SERIAL 0
360# define CMS_REK_KEYIDENTIFIER 1
361
362# define CMS_OIK_ISSUER_SERIAL 0
363# define CMS_OIK_KEYIDENTIFIER 1
364# define CMS_OIK_PUBKEY 2
365
366BIO *cms_content_bio(CMS_ContentInfo *cms);
367
368CMS_ContentInfo *cms_Data_create(void);
369
370CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
371BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
372int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
373
374BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
375int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
376int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert,
377 int type);
378int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
379 ASN1_OCTET_STRING **keyid,
380 X509_NAME **issuer,
381 ASN1_INTEGER **sno);
382int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
383
384CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
385BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
386
387BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
388int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
389 X509_ALGOR *mdalg);
390
391int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert);
392int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert);
393int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert);
394int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert);
395
396BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
397BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
398int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
399 const EVP_CIPHER *cipher,
400 const unsigned char *key, size_t keylen);
401
402int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
403int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
404ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
405
406BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
407CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
408int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
409int cms_pkey_get_ri_type(EVP_PKEY *pk);
410/* KARI routines */
411int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
412 EVP_PKEY *pk, unsigned int flags);
413int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
414 CMS_RecipientInfo *ri);
415
416/* PWRI routines */
417int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
418 int en_de);
419
420DECLARE_ASN1_ITEM(CMS_CertificateChoices)
421DECLARE_ASN1_ITEM(CMS_DigestedData)
422DECLARE_ASN1_ITEM(CMS_EncryptedData)
423DECLARE_ASN1_ITEM(CMS_EnvelopedData)
424DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
425DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo)
426DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
427DECLARE_ASN1_ITEM(CMS_OriginatorPublicKey)
428DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
429DECLARE_ASN1_ITEM(CMS_Receipt)
430DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
431DECLARE_ASN1_ITEM(CMS_RecipientEncryptedKey)
432DECLARE_ASN1_ITEM(CMS_RecipientKeyIdentifier)
433DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
434DECLARE_ASN1_ITEM(CMS_SignedData)
435DECLARE_ASN1_ITEM(CMS_CompressedData)
436
437#endif
diff --git a/src/lib/libcrypto/cms/cms_lib.c b/src/lib/libcrypto/cms/cms_lib.c
new file mode 100644
index 0000000000..c2cac26010
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_lib.c
@@ -0,0 +1,587 @@
1/*
2 * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <openssl/asn1t.h>
11#include <openssl/x509v3.h>
12#include <openssl/err.h>
13#include <openssl/pem.h>
14#include <openssl/bio.h>
15#include <openssl/asn1.h>
16#include <openssl/cms.h>
17#include "cms_lcl.h"
18
19IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
20IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
21
22const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms)
23{
24 return cms->contentType;
25}
26
27CMS_ContentInfo *cms_Data_create(void)
28{
29 CMS_ContentInfo *cms;
30 cms = CMS_ContentInfo_new();
31 if (cms != NULL) {
32 cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
33 /* Never detached */
34 CMS_set_detached(cms, 0);
35 }
36 return cms;
37}
38
39BIO *cms_content_bio(CMS_ContentInfo *cms)
40{
41 ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
42 if (!pos)
43 return NULL;
44 /* If content detached data goes nowhere: create NULL BIO */
45 if (!*pos)
46 return BIO_new(BIO_s_null());
47 /*
48 * If content not detached and created return memory BIO
49 */
50 if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
51 return BIO_new(BIO_s_mem());
52 /* Else content was read in: return read only BIO for it */
53 return BIO_new_mem_buf((*pos)->data, (*pos)->length);
54}
55
56BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
57{
58 BIO *cmsbio, *cont;
59 if (icont)
60 cont = icont;
61 else
62 cont = cms_content_bio(cms);
63 if (!cont) {
64 CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
65 return NULL;
66 }
67 switch (OBJ_obj2nid(cms->contentType)) {
68
69 case NID_pkcs7_data:
70 return cont;
71
72 case NID_pkcs7_signed:
73 cmsbio = cms_SignedData_init_bio(cms);
74 break;
75
76 case NID_pkcs7_digest:
77 cmsbio = cms_DigestedData_init_bio(cms);
78 break;
79#ifdef ZLIB
80 case NID_id_smime_ct_compressedData:
81 cmsbio = cms_CompressedData_init_bio(cms);
82 break;
83#endif
84
85 case NID_pkcs7_encrypted:
86 cmsbio = cms_EncryptedData_init_bio(cms);
87 break;
88
89 case NID_pkcs7_enveloped:
90 cmsbio = cms_EnvelopedData_init_bio(cms);
91 break;
92
93 default:
94 CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
95 return NULL;
96 }
97
98 if (cmsbio)
99 return BIO_push(cmsbio, cont);
100
101 if (!icont)
102 BIO_free(cont);
103 return NULL;
104
105}
106
107int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
108{
109 ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
110 if (!pos)
111 return 0;
112 /* If embedded content find memory BIO and set content */
113 if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) {
114 BIO *mbio;
115 unsigned char *cont;
116 long contlen;
117 mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
118 if (!mbio) {
119 CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
120 return 0;
121 }
122 contlen = BIO_get_mem_data(mbio, &cont);
123 /* Set bio as read only so its content can't be clobbered */
124 BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
125 BIO_set_mem_eof_return(mbio, 0);
126 ASN1_STRING_set0(*pos, cont, contlen);
127 (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
128 }
129
130 switch (OBJ_obj2nid(cms->contentType)) {
131
132 case NID_pkcs7_data:
133 case NID_pkcs7_enveloped:
134 case NID_pkcs7_encrypted:
135 case NID_id_smime_ct_compressedData:
136 /* Nothing to do */
137 return 1;
138
139 case NID_pkcs7_signed:
140 return cms_SignedData_final(cms, cmsbio);
141
142 case NID_pkcs7_digest:
143 return cms_DigestedData_do_final(cms, cmsbio, 0);
144
145 default:
146 CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
147 return 0;
148 }
149}
150
151/*
152 * Return an OCTET STRING pointer to content. This allows it to be accessed
153 * or set later.
154 */
155
156ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
157{
158 switch (OBJ_obj2nid(cms->contentType)) {
159
160 case NID_pkcs7_data:
161 return &cms->d.data;
162
163 case NID_pkcs7_signed:
164 return &cms->d.signedData->encapContentInfo->eContent;
165
166 case NID_pkcs7_enveloped:
167 return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
168
169 case NID_pkcs7_digest:
170 return &cms->d.digestedData->encapContentInfo->eContent;
171
172 case NID_pkcs7_encrypted:
173 return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
174
175 case NID_id_smime_ct_authData:
176 return &cms->d.authenticatedData->encapContentInfo->eContent;
177
178 case NID_id_smime_ct_compressedData:
179 return &cms->d.compressedData->encapContentInfo->eContent;
180
181 default:
182 if (cms->d.other->type == V_ASN1_OCTET_STRING)
183 return &cms->d.other->value.octet_string;
184 CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
185 return NULL;
186
187 }
188}
189
190/*
191 * Return an ASN1_OBJECT pointer to content type. This allows it to be
192 * accessed or set later.
193 */
194
195static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
196{
197 switch (OBJ_obj2nid(cms->contentType)) {
198
199 case NID_pkcs7_signed:
200 return &cms->d.signedData->encapContentInfo->eContentType;
201
202 case NID_pkcs7_enveloped:
203 return &cms->d.envelopedData->encryptedContentInfo->contentType;
204
205 case NID_pkcs7_digest:
206 return &cms->d.digestedData->encapContentInfo->eContentType;
207
208 case NID_pkcs7_encrypted:
209 return &cms->d.encryptedData->encryptedContentInfo->contentType;
210
211 case NID_id_smime_ct_authData:
212 return &cms->d.authenticatedData->encapContentInfo->eContentType;
213
214 case NID_id_smime_ct_compressedData:
215 return &cms->d.compressedData->encapContentInfo->eContentType;
216
217 default:
218 CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, CMS_R_UNSUPPORTED_CONTENT_TYPE);
219 return NULL;
220
221 }
222}
223
224const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
225{
226 ASN1_OBJECT **petype;
227 petype = cms_get0_econtent_type(cms);
228 if (petype)
229 return *petype;
230 return NULL;
231}
232
233int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
234{
235 ASN1_OBJECT **petype, *etype;
236 petype = cms_get0_econtent_type(cms);
237 if (!petype)
238 return 0;
239 if (!oid)
240 return 1;
241 etype = OBJ_dup(oid);
242 if (!etype)
243 return 0;
244 ASN1_OBJECT_free(*petype);
245 *petype = etype;
246 return 1;
247}
248
249int CMS_is_detached(CMS_ContentInfo *cms)
250{
251 ASN1_OCTET_STRING **pos;
252 pos = CMS_get0_content(cms);
253 if (!pos)
254 return -1;
255 if (*pos)
256 return 0;
257 return 1;
258}
259
260int CMS_set_detached(CMS_ContentInfo *cms, int detached)
261{
262 ASN1_OCTET_STRING **pos;
263 pos = CMS_get0_content(cms);
264 if (!pos)
265 return 0;
266 if (detached) {
267 ASN1_OCTET_STRING_free(*pos);
268 *pos = NULL;
269 return 1;
270 }
271 if (*pos == NULL)
272 *pos = ASN1_OCTET_STRING_new();
273 if (*pos != NULL) {
274 /*
275 * NB: special flag to show content is created and not read in.
276 */
277 (*pos)->flags |= ASN1_STRING_FLAG_CONT;
278 return 1;
279 }
280 CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
281 return 0;
282}
283
284/* Create a digest BIO from an X509_ALGOR structure */
285
286BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
287{
288 BIO *mdbio = NULL;
289 const ASN1_OBJECT *digestoid;
290 const EVP_MD *digest;
291 X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
292 digest = EVP_get_digestbyobj(digestoid);
293 if (!digest) {
294 CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
295 CMS_R_UNKNOWN_DIGEST_ALGORITHM);
296 goto err;
297 }
298 mdbio = BIO_new(BIO_f_md());
299 if (mdbio == NULL || !BIO_set_md(mdbio, digest)) {
300 CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR);
301 goto err;
302 }
303 return mdbio;
304 err:
305 BIO_free(mdbio);
306 return NULL;
307}
308
309/* Locate a message digest content from a BIO chain based on SignerInfo */
310
311int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
312 X509_ALGOR *mdalg)
313{
314 int nid;
315 const ASN1_OBJECT *mdoid;
316 X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
317 nid = OBJ_obj2nid(mdoid);
318 /* Look for digest type to match signature */
319 for (;;) {
320 EVP_MD_CTX *mtmp;
321 chain = BIO_find_type(chain, BIO_TYPE_MD);
322 if (chain == NULL) {
323 CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
324 CMS_R_NO_MATCHING_DIGEST);
325 return 0;
326 }
327 BIO_get_md_ctx(chain, &mtmp);
328 if (EVP_MD_CTX_type(mtmp) == nid
329 /*
330 * Workaround for broken implementations that use signature
331 * algorithm OID instead of digest.
332 */
333 || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
334 return EVP_MD_CTX_copy_ex(mctx, mtmp);
335 chain = BIO_next(chain);
336 }
337}
338
339static STACK_OF(CMS_CertificateChoices)
340**cms_get0_certificate_choices(CMS_ContentInfo *cms)
341{
342 switch (OBJ_obj2nid(cms->contentType)) {
343
344 case NID_pkcs7_signed:
345 return &cms->d.signedData->certificates;
346
347 case NID_pkcs7_enveloped:
348 if (cms->d.envelopedData->originatorInfo == NULL)
349 return NULL;
350 return &cms->d.envelopedData->originatorInfo->certificates;
351
352 default:
353 CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
354 CMS_R_UNSUPPORTED_CONTENT_TYPE);
355 return NULL;
356
357 }
358}
359
360CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
361{
362 STACK_OF(CMS_CertificateChoices) **pcerts;
363 CMS_CertificateChoices *cch;
364 pcerts = cms_get0_certificate_choices(cms);
365 if (!pcerts)
366 return NULL;
367 if (!*pcerts)
368 *pcerts = sk_CMS_CertificateChoices_new_null();
369 if (!*pcerts)
370 return NULL;
371 cch = M_ASN1_new_of(CMS_CertificateChoices);
372 if (!cch)
373 return NULL;
374 if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) {
375 M_ASN1_free_of(cch, CMS_CertificateChoices);
376 return NULL;
377 }
378 return cch;
379}
380
381int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
382{
383 CMS_CertificateChoices *cch;
384 STACK_OF(CMS_CertificateChoices) **pcerts;
385 int i;
386 pcerts = cms_get0_certificate_choices(cms);
387 if (!pcerts)
388 return 0;
389 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
390 cch = sk_CMS_CertificateChoices_value(*pcerts, i);
391 if (cch->type == CMS_CERTCHOICE_CERT) {
392 if (!X509_cmp(cch->d.certificate, cert)) {
393 CMSerr(CMS_F_CMS_ADD0_CERT,
394 CMS_R_CERTIFICATE_ALREADY_PRESENT);
395 return 0;
396 }
397 }
398 }
399 cch = CMS_add0_CertificateChoices(cms);
400 if (!cch)
401 return 0;
402 cch->type = CMS_CERTCHOICE_CERT;
403 cch->d.certificate = cert;
404 return 1;
405}
406
407int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
408{
409 int r;
410 r = CMS_add0_cert(cms, cert);
411 if (r > 0)
412 X509_up_ref(cert);
413 return r;
414}
415
416static STACK_OF(CMS_RevocationInfoChoice)
417**cms_get0_revocation_choices(CMS_ContentInfo *cms)
418{
419 switch (OBJ_obj2nid(cms->contentType)) {
420
421 case NID_pkcs7_signed:
422 return &cms->d.signedData->crls;
423
424 case NID_pkcs7_enveloped:
425 if (cms->d.envelopedData->originatorInfo == NULL)
426 return NULL;
427 return &cms->d.envelopedData->originatorInfo->crls;
428
429 default:
430 CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
431 CMS_R_UNSUPPORTED_CONTENT_TYPE);
432 return NULL;
433
434 }
435}
436
437CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
438{
439 STACK_OF(CMS_RevocationInfoChoice) **pcrls;
440 CMS_RevocationInfoChoice *rch;
441 pcrls = cms_get0_revocation_choices(cms);
442 if (!pcrls)
443 return NULL;
444 if (!*pcrls)
445 *pcrls = sk_CMS_RevocationInfoChoice_new_null();
446 if (!*pcrls)
447 return NULL;
448 rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
449 if (!rch)
450 return NULL;
451 if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) {
452 M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
453 return NULL;
454 }
455 return rch;
456}
457
458int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
459{
460 CMS_RevocationInfoChoice *rch;
461 rch = CMS_add0_RevocationInfoChoice(cms);
462 if (!rch)
463 return 0;
464 rch->type = CMS_REVCHOICE_CRL;
465 rch->d.crl = crl;
466 return 1;
467}
468
469int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
470{
471 int r;
472 r = CMS_add0_crl(cms, crl);
473 if (r > 0)
474 X509_CRL_up_ref(crl);
475 return r;
476}
477
478STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
479{
480 STACK_OF(X509) *certs = NULL;
481 CMS_CertificateChoices *cch;
482 STACK_OF(CMS_CertificateChoices) **pcerts;
483 int i;
484 pcerts = cms_get0_certificate_choices(cms);
485 if (!pcerts)
486 return NULL;
487 for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
488 cch = sk_CMS_CertificateChoices_value(*pcerts, i);
489 if (cch->type == 0) {
490 if (!certs) {
491 certs = sk_X509_new_null();
492 if (!certs)
493 return NULL;
494 }
495 if (!sk_X509_push(certs, cch->d.certificate)) {
496 sk_X509_pop_free(certs, X509_free);
497 return NULL;
498 }
499 X509_up_ref(cch->d.certificate);
500 }
501 }
502 return certs;
503
504}
505
506STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
507{
508 STACK_OF(X509_CRL) *crls = NULL;
509 STACK_OF(CMS_RevocationInfoChoice) **pcrls;
510 CMS_RevocationInfoChoice *rch;
511 int i;
512 pcrls = cms_get0_revocation_choices(cms);
513 if (!pcrls)
514 return NULL;
515 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) {
516 rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
517 if (rch->type == 0) {
518 if (!crls) {
519 crls = sk_X509_CRL_new_null();
520 if (!crls)
521 return NULL;
522 }
523 if (!sk_X509_CRL_push(crls, rch->d.crl)) {
524 sk_X509_CRL_pop_free(crls, X509_CRL_free);
525 return NULL;
526 }
527 X509_CRL_up_ref(rch->d.crl);
528 }
529 }
530 return crls;
531}
532
533int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)
534{
535 int ret;
536 ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert));
537 if (ret)
538 return ret;
539 return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert));
540}
541
542int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert)
543{
544 const ASN1_OCTET_STRING *cert_keyid = X509_get0_subject_key_id(cert);
545
546 if (cert_keyid == NULL)
547 return -1;
548 return ASN1_OCTET_STRING_cmp(keyid, cert_keyid);
549}
550
551int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert)
552{
553 CMS_IssuerAndSerialNumber *ias;
554 ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber);
555 if (!ias)
556 goto err;
557 if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert)))
558 goto err;
559 if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert)))
560 goto err;
561 M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber);
562 *pias = ias;
563 return 1;
564 err:
565 M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber);
566 CMSerr(CMS_F_CMS_SET1_IAS, ERR_R_MALLOC_FAILURE);
567 return 0;
568}
569
570int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
571{
572 ASN1_OCTET_STRING *keyid = NULL;
573 const ASN1_OCTET_STRING *cert_keyid;
574 cert_keyid = X509_get0_subject_key_id(cert);
575 if (cert_keyid == NULL) {
576 CMSerr(CMS_F_CMS_SET1_KEYID, CMS_R_CERTIFICATE_HAS_NO_KEYID);
577 return 0;
578 }
579 keyid = ASN1_STRING_dup(cert_keyid);
580 if (!keyid) {
581 CMSerr(CMS_F_CMS_SET1_KEYID, ERR_R_MALLOC_FAILURE);
582 return 0;
583 }
584 ASN1_OCTET_STRING_free(*pkeyid);
585 *pkeyid = keyid;
586 return 1;
587}
diff --git a/src/lib/libcrypto/cms/cms_pwri.c b/src/lib/libcrypto/cms/cms_pwri.c
new file mode 100644
index 0000000000..26e3bdcf9e
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_pwri.c
@@ -0,0 +1,394 @@
1/*
2 * Copyright 2009-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/pem.h>
13#include <openssl/x509v3.h>
14#include <openssl/err.h>
15#include <openssl/cms.h>
16#include <openssl/rand.h>
17#include <openssl/aes.h>
18#include "cms_lcl.h"
19#include "internal/asn1_int.h"
20
21int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
22 unsigned char *pass, ossl_ssize_t passlen)
23{
24 CMS_PasswordRecipientInfo *pwri;
25 if (ri->type != CMS_RECIPINFO_PASS) {
26 CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
27 return 0;
28 }
29
30 pwri = ri->d.pwri;
31 pwri->pass = pass;
32 if (pass && passlen < 0)
33 passlen = strlen((char *)pass);
34 pwri->passlen = passlen;
35 return 1;
36}
37
38CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
39 int iter, int wrap_nid,
40 int pbe_nid,
41 unsigned char *pass,
42 ossl_ssize_t passlen,
43 const EVP_CIPHER *kekciph)
44{
45 CMS_RecipientInfo *ri = NULL;
46 CMS_EnvelopedData *env;
47 CMS_PasswordRecipientInfo *pwri;
48 EVP_CIPHER_CTX *ctx = NULL;
49 X509_ALGOR *encalg = NULL;
50 unsigned char iv[EVP_MAX_IV_LENGTH];
51 int ivlen;
52
53 env = cms_get0_enveloped(cms);
54 if (!env)
55 return NULL;
56
57 if (wrap_nid <= 0)
58 wrap_nid = NID_id_alg_PWRI_KEK;
59
60 if (pbe_nid <= 0)
61 pbe_nid = NID_id_pbkdf2;
62
63 /* Get from enveloped data */
64 if (kekciph == NULL)
65 kekciph = env->encryptedContentInfo->cipher;
66
67 if (kekciph == NULL) {
68 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
69 return NULL;
70 }
71 if (wrap_nid != NID_id_alg_PWRI_KEK) {
72 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
73 CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
74 return NULL;
75 }
76
77 /* Setup algorithm identifier for cipher */
78 encalg = X509_ALGOR_new();
79 if (encalg == NULL) {
80 goto merr;
81 }
82 ctx = EVP_CIPHER_CTX_new();
83
84 if (EVP_EncryptInit_ex(ctx, kekciph, NULL, NULL, NULL) <= 0) {
85 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
86 goto err;
87 }
88
89 ivlen = EVP_CIPHER_CTX_iv_length(ctx);
90
91 if (ivlen > 0) {
92 if (RAND_bytes(iv, ivlen) <= 0)
93 goto err;
94 if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0) {
95 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
96 goto err;
97 }
98 encalg->parameter = ASN1_TYPE_new();
99 if (!encalg->parameter) {
100 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
101 goto err;
102 }
103 if (EVP_CIPHER_param_to_asn1(ctx, encalg->parameter) <= 0) {
104 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
105 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
106 goto err;
107 }
108 }
109
110 encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
111
112 EVP_CIPHER_CTX_free(ctx);
113 ctx = NULL;
114
115 /* Initialize recipient info */
116 ri = M_ASN1_new_of(CMS_RecipientInfo);
117 if (ri == NULL)
118 goto merr;
119
120 ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
121 if (ri->d.pwri == NULL)
122 goto merr;
123 ri->type = CMS_RECIPINFO_PASS;
124
125 pwri = ri->d.pwri;
126 /* Since this is overwritten, free up empty structure already there */
127 X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
128 pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
129 if (pwri->keyEncryptionAlgorithm == NULL)
130 goto merr;
131 pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
132 pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
133 if (pwri->keyEncryptionAlgorithm->parameter == NULL)
134 goto merr;
135
136 if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
137 &pwri->keyEncryptionAlgorithm->parameter->
138 value.sequence))
139 goto merr;
140 pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
141
142 X509_ALGOR_free(encalg);
143 encalg = NULL;
144
145 /* Setup PBE algorithm */
146
147 pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);
148
149 if (!pwri->keyDerivationAlgorithm)
150 goto err;
151
152 CMS_RecipientInfo_set0_password(ri, pass, passlen);
153 pwri->version = 0;
154
155 if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
156 goto merr;
157
158 return ri;
159
160 merr:
161 CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
162 err:
163 EVP_CIPHER_CTX_free(ctx);
164 if (ri)
165 M_ASN1_free_of(ri, CMS_RecipientInfo);
166 X509_ALGOR_free(encalg);
167 return NULL;
168
169}
170
171/*
172 * This is an implementation of the key wrapping mechanism in RFC3211, at
173 * some point this should go into EVP.
174 */
175
176static int kek_unwrap_key(unsigned char *out, size_t *outlen,
177 const unsigned char *in, size_t inlen,
178 EVP_CIPHER_CTX *ctx)
179{
180 size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
181 unsigned char *tmp;
182 int outl, rv = 0;
183 if (inlen < 2 * blocklen) {
184 /* too small */
185 return 0;
186 }
187 if (inlen % blocklen) {
188 /* Invalid size */
189 return 0;
190 }
191 if ((tmp = OPENSSL_malloc(inlen)) == NULL) {
192 CMSerr(CMS_F_KEK_UNWRAP_KEY, ERR_R_MALLOC_FAILURE);
193 return 0;
194 }
195 /* setup IV by decrypting last two blocks */
196 if (!EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
197 in + inlen - 2 * blocklen, blocklen * 2)
198 /*
199 * Do a decrypt of last decrypted block to set IV to correct value
200 * output it to start of buffer so we don't corrupt decrypted block
201 * this works because buffer is at least two block lengths long.
202 */
203 || !EVP_DecryptUpdate(ctx, tmp, &outl,
204 tmp + inlen - blocklen, blocklen)
205 /* Can now decrypt first n - 1 blocks */
206 || !EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen)
207
208 /* Reset IV to original value */
209 || !EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL)
210 /* Decrypt again */
211 || !EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen))
212 goto err;
213 /* Check check bytes */
214 if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) {
215 /* Check byte failure */
216 goto err;
217 }
218 if (inlen < (size_t)(tmp[0] - 4)) {
219 /* Invalid length value */
220 goto err;
221 }
222 *outlen = (size_t)tmp[0];
223 memcpy(out, tmp + 4, *outlen);
224 rv = 1;
225 err:
226 OPENSSL_clear_free(tmp, inlen);
227 return rv;
228
229}
230
231static int kek_wrap_key(unsigned char *out, size_t *outlen,
232 const unsigned char *in, size_t inlen,
233 EVP_CIPHER_CTX *ctx)
234{
235 size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
236 size_t olen;
237 int dummy;
238 /*
239 * First decide length of output buffer: need header and round up to
240 * multiple of block length.
241 */
242 olen = (inlen + 4 + blocklen - 1) / blocklen;
243 olen *= blocklen;
244 if (olen < 2 * blocklen) {
245 /* Key too small */
246 return 0;
247 }
248 if (inlen > 0xFF) {
249 /* Key too large */
250 return 0;
251 }
252 if (out) {
253 /* Set header */
254 out[0] = (unsigned char)inlen;
255 out[1] = in[0] ^ 0xFF;
256 out[2] = in[1] ^ 0xFF;
257 out[3] = in[2] ^ 0xFF;
258 memcpy(out + 4, in, inlen);
259 /* Add random padding to end */
260 if (olen > inlen + 4
261 && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
262 return 0;
263 /* Encrypt twice */
264 if (!EVP_EncryptUpdate(ctx, out, &dummy, out, olen)
265 || !EVP_EncryptUpdate(ctx, out, &dummy, out, olen))
266 return 0;
267 }
268
269 *outlen = olen;
270
271 return 1;
272}
273
274/* Encrypt/Decrypt content key in PWRI recipient info */
275
276int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
277 int en_de)
278{
279 CMS_EncryptedContentInfo *ec;
280 CMS_PasswordRecipientInfo *pwri;
281 int r = 0;
282 X509_ALGOR *algtmp, *kekalg = NULL;
283 EVP_CIPHER_CTX *kekctx = NULL;
284 const EVP_CIPHER *kekcipher;
285 unsigned char *key = NULL;
286 size_t keylen;
287
288 ec = cms->d.envelopedData->encryptedContentInfo;
289
290 pwri = ri->d.pwri;
291
292 if (!pwri->pass) {
293 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
294 return 0;
295 }
296 algtmp = pwri->keyEncryptionAlgorithm;
297
298 if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
299 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
300 CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
301 return 0;
302 }
303
304 kekalg = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
305 algtmp->parameter);
306
307 if (kekalg == NULL) {
308 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
309 CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
310 return 0;
311 }
312
313 kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
314
315 if (!kekcipher) {
316 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER);
317 return 0;
318 }
319
320 kekctx = EVP_CIPHER_CTX_new();
321 if (kekctx == NULL) {
322 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
323 return 0;
324 }
325 /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
326 if (!EVP_CipherInit_ex(kekctx, kekcipher, NULL, NULL, NULL, en_de))
327 goto err;
328 EVP_CIPHER_CTX_set_padding(kekctx, 0);
329 if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) {
330 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
331 CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
332 goto err;
333 }
334
335 algtmp = pwri->keyDerivationAlgorithm;
336
337 /* Finish password based key derivation to setup key in "ctx" */
338
339 if (EVP_PBE_CipherInit(algtmp->algorithm,
340 (char *)pwri->pass, pwri->passlen,
341 algtmp->parameter, kekctx, en_de) < 0) {
342 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
343 goto err;
344 }
345
346 /* Finally wrap/unwrap the key */
347
348 if (en_de) {
349
350 if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, kekctx))
351 goto err;
352
353 key = OPENSSL_malloc(keylen);
354
355 if (key == NULL)
356 goto err;
357
358 if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx))
359 goto err;
360 pwri->encryptedKey->data = key;
361 pwri->encryptedKey->length = keylen;
362 } else {
363 key = OPENSSL_malloc(pwri->encryptedKey->length);
364
365 if (key == NULL) {
366 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
367 goto err;
368 }
369 if (!kek_unwrap_key(key, &keylen,
370 pwri->encryptedKey->data,
371 pwri->encryptedKey->length, kekctx)) {
372 CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE);
373 goto err;
374 }
375
376 OPENSSL_clear_free(ec->key, ec->keylen);
377 ec->key = key;
378 ec->keylen = keylen;
379
380 }
381
382 r = 1;
383
384 err:
385
386 EVP_CIPHER_CTX_free(kekctx);
387
388 if (!r)
389 OPENSSL_free(key);
390 X509_ALGOR_free(kekalg);
391
392 return r;
393
394}
diff --git a/src/lib/libcrypto/cms/cms_sd.c b/src/lib/libcrypto/cms/cms_sd.c
new file mode 100644
index 0000000000..ff2d540b6a
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_sd.c
@@ -0,0 +1,926 @@
1/*
2 * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/pem.h>
13#include <openssl/x509.h>
14#include <openssl/x509v3.h>
15#include <openssl/err.h>
16#include <openssl/cms.h>
17#include "cms_lcl.h"
18#include "internal/asn1_int.h"
19#include "internal/evp_int.h"
20
21/* CMS SignedData Utilities */
22
23static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
24{
25 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) {
26 CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
27 return NULL;
28 }
29 return cms->d.signedData;
30}
31
32static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
33{
34 if (cms->d.other == NULL) {
35 cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
36 if (!cms->d.signedData) {
37 CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
38 return NULL;
39 }
40 cms->d.signedData->version = 1;
41 cms->d.signedData->encapContentInfo->eContentType =
42 OBJ_nid2obj(NID_pkcs7_data);
43 cms->d.signedData->encapContentInfo->partial = 1;
44 ASN1_OBJECT_free(cms->contentType);
45 cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
46 return cms->d.signedData;
47 }
48 return cms_get0_signed(cms);
49}
50
51/* Just initialise SignedData e.g. for certs only structure */
52
53int CMS_SignedData_init(CMS_ContentInfo *cms)
54{
55 if (cms_signed_data_init(cms))
56 return 1;
57 else
58 return 0;
59}
60
61/* Check structures and fixup version numbers (if necessary) */
62
63static void cms_sd_set_version(CMS_SignedData *sd)
64{
65 int i;
66 CMS_CertificateChoices *cch;
67 CMS_RevocationInfoChoice *rch;
68 CMS_SignerInfo *si;
69
70 for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
71 cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
72 if (cch->type == CMS_CERTCHOICE_OTHER) {
73 if (sd->version < 5)
74 sd->version = 5;
75 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
76 if (sd->version < 4)
77 sd->version = 4;
78 } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
79 if (sd->version < 3)
80 sd->version = 3;
81 }
82 }
83
84 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
85 rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
86 if (rch->type == CMS_REVCHOICE_OTHER) {
87 if (sd->version < 5)
88 sd->version = 5;
89 }
90 }
91
92 if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
93 && (sd->version < 3))
94 sd->version = 3;
95
96 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
97 si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
98 if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
99 if (si->version < 3)
100 si->version = 3;
101 if (sd->version < 3)
102 sd->version = 3;
103 } else if (si->version < 1)
104 si->version = 1;
105 }
106
107 if (sd->version < 1)
108 sd->version = 1;
109
110}
111
112/* Copy an existing messageDigest value */
113
114static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
115{
116 STACK_OF(CMS_SignerInfo) *sinfos;
117 CMS_SignerInfo *sitmp;
118 int i;
119 sinfos = CMS_get0_SignerInfos(cms);
120 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
121 ASN1_OCTET_STRING *messageDigest;
122 sitmp = sk_CMS_SignerInfo_value(sinfos, i);
123 if (sitmp == si)
124 continue;
125 if (CMS_signed_get_attr_count(sitmp) < 0)
126 continue;
127 if (OBJ_cmp(si->digestAlgorithm->algorithm,
128 sitmp->digestAlgorithm->algorithm))
129 continue;
130 messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
131 OBJ_nid2obj
132 (NID_pkcs9_messageDigest),
133 -3, V_ASN1_OCTET_STRING);
134 if (!messageDigest) {
135 CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
136 CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
137 return 0;
138 }
139
140 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
141 V_ASN1_OCTET_STRING,
142 messageDigest, -1))
143 return 1;
144 else
145 return 0;
146 }
147 CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
148 return 0;
149}
150
151int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
152{
153 switch (type) {
154 case CMS_SIGNERINFO_ISSUER_SERIAL:
155 if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert))
156 return 0;
157 break;
158
159 case CMS_SIGNERINFO_KEYIDENTIFIER:
160 if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert))
161 return 0;
162 break;
163
164 default:
165 CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
166 return 0;
167 }
168
169 sid->type = type;
170
171 return 1;
172}
173
174int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
175 ASN1_OCTET_STRING **keyid,
176 X509_NAME **issuer,
177 ASN1_INTEGER **sno)
178{
179 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
180 if (issuer)
181 *issuer = sid->d.issuerAndSerialNumber->issuer;
182 if (sno)
183 *sno = sid->d.issuerAndSerialNumber->serialNumber;
184 } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
185 if (keyid)
186 *keyid = sid->d.subjectKeyIdentifier;
187 } else
188 return 0;
189 return 1;
190}
191
192int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
193{
194 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
195 return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert);
196 else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
197 return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert);
198 else
199 return -1;
200}
201
202static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
203{
204 EVP_PKEY *pkey = si->pkey;
205 int i;
206 if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
207 return 1;
208 i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
209 if (i == -2) {
210 CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
211 return 0;
212 }
213 if (i <= 0) {
214 CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE);
215 return 0;
216 }
217 return 1;
218}
219
220CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
221 X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
222 unsigned int flags)
223{
224 CMS_SignedData *sd;
225 CMS_SignerInfo *si = NULL;
226 X509_ALGOR *alg;
227 int i, type;
228 if (!X509_check_private_key(signer, pk)) {
229 CMSerr(CMS_F_CMS_ADD1_SIGNER,
230 CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
231 return NULL;
232 }
233 sd = cms_signed_data_init(cms);
234 if (!sd)
235 goto err;
236 si = M_ASN1_new_of(CMS_SignerInfo);
237 if (!si)
238 goto merr;
239 /* Call for side-effect of computing hash and caching extensions */
240 X509_check_purpose(signer, -1, -1);
241
242 X509_up_ref(signer);
243 EVP_PKEY_up_ref(pk);
244
245 si->pkey = pk;
246 si->signer = signer;
247 si->mctx = EVP_MD_CTX_new();
248 si->pctx = NULL;
249
250 if (si->mctx == NULL) {
251 CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
252 goto err;
253 }
254
255 if (flags & CMS_USE_KEYID) {
256 si->version = 3;
257 if (sd->version < 3)
258 sd->version = 3;
259 type = CMS_SIGNERINFO_KEYIDENTIFIER;
260 } else {
261 type = CMS_SIGNERINFO_ISSUER_SERIAL;
262 si->version = 1;
263 }
264
265 if (!cms_set1_SignerIdentifier(si->sid, signer, type))
266 goto err;
267
268 if (md == NULL) {
269 int def_nid;
270 if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
271 goto err;
272 md = EVP_get_digestbynid(def_nid);
273 if (md == NULL) {
274 CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
275 goto err;
276 }
277 }
278
279 if (!md) {
280 CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
281 goto err;
282 }
283
284 X509_ALGOR_set_md(si->digestAlgorithm, md);
285
286 /* See if digest is present in digestAlgorithms */
287 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
288 const ASN1_OBJECT *aoid;
289 alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
290 X509_ALGOR_get0(&aoid, NULL, NULL, alg);
291 if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
292 break;
293 }
294
295 if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
296 alg = X509_ALGOR_new();
297 if (alg == NULL)
298 goto merr;
299 X509_ALGOR_set_md(alg, md);
300 if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
301 X509_ALGOR_free(alg);
302 goto merr;
303 }
304 }
305
306 if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0))
307 goto err;
308 if (!(flags & CMS_NOATTR)) {
309 /*
310 * Initialize signed attributes structure so other attributes
311 * such as signing time etc are added later even if we add none here.
312 */
313 if (!si->signedAttrs) {
314 si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
315 if (!si->signedAttrs)
316 goto merr;
317 }
318
319 if (!(flags & CMS_NOSMIMECAP)) {
320 STACK_OF(X509_ALGOR) *smcap = NULL;
321 i = CMS_add_standard_smimecap(&smcap);
322 if (i)
323 i = CMS_add_smimecap(si, smcap);
324 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
325 if (!i)
326 goto merr;
327 }
328 if (flags & CMS_REUSE_DIGEST) {
329 if (!cms_copy_messageDigest(cms, si))
330 goto err;
331 if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
332 !CMS_SignerInfo_sign(si))
333 goto err;
334 }
335 }
336
337 if (!(flags & CMS_NOCERTS)) {
338 /* NB ignore -1 return for duplicate cert */
339 if (!CMS_add1_cert(cms, signer))
340 goto merr;
341 }
342
343 if (flags & CMS_KEY_PARAM) {
344 if (flags & CMS_NOATTR) {
345 si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
346 if (si->pctx == NULL)
347 goto err;
348 if (EVP_PKEY_sign_init(si->pctx) <= 0)
349 goto err;
350 if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
351 goto err;
352 } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md, NULL, pk) <=
353 0)
354 goto err;
355 }
356
357 if (!sd->signerInfos)
358 sd->signerInfos = sk_CMS_SignerInfo_new_null();
359 if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si))
360 goto merr;
361
362 return si;
363
364 merr:
365 CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
366 err:
367 M_ASN1_free_of(si, CMS_SignerInfo);
368 return NULL;
369
370}
371
372static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
373{
374 ASN1_TIME *tt;
375 int r = 0;
376 if (t)
377 tt = t;
378 else
379 tt = X509_gmtime_adj(NULL, 0);
380
381 if (!tt)
382 goto merr;
383
384 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
385 tt->type, tt, -1) <= 0)
386 goto merr;
387
388 r = 1;
389
390 merr:
391
392 if (!t)
393 ASN1_TIME_free(tt);
394
395 if (!r)
396 CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
397
398 return r;
399
400}
401
402EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
403{
404 return si->pctx;
405}
406
407EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
408{
409 return si->mctx;
410}
411
412STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
413{
414 CMS_SignedData *sd;
415 sd = cms_get0_signed(cms);
416 if (!sd)
417 return NULL;
418 return sd->signerInfos;
419}
420
421STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
422{
423 STACK_OF(X509) *signers = NULL;
424 STACK_OF(CMS_SignerInfo) *sinfos;
425 CMS_SignerInfo *si;
426 int i;
427 sinfos = CMS_get0_SignerInfos(cms);
428 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
429 si = sk_CMS_SignerInfo_value(sinfos, i);
430 if (si->signer) {
431 if (!signers) {
432 signers = sk_X509_new_null();
433 if (!signers)
434 return NULL;
435 }
436 if (!sk_X509_push(signers, si->signer)) {
437 sk_X509_free(signers);
438 return NULL;
439 }
440 }
441 }
442 return signers;
443}
444
445void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
446{
447 if (signer) {
448 X509_up_ref(signer);
449 EVP_PKEY_free(si->pkey);
450 si->pkey = X509_get_pubkey(signer);
451 }
452 X509_free(si->signer);
453 si->signer = signer;
454}
455
456int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
457 ASN1_OCTET_STRING **keyid,
458 X509_NAME **issuer, ASN1_INTEGER **sno)
459{
460 return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
461}
462
463int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
464{
465 return cms_SignerIdentifier_cert_cmp(si->sid, cert);
466}
467
468int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
469 unsigned int flags)
470{
471 CMS_SignedData *sd;
472 CMS_SignerInfo *si;
473 CMS_CertificateChoices *cch;
474 STACK_OF(CMS_CertificateChoices) *certs;
475 X509 *x;
476 int i, j;
477 int ret = 0;
478 sd = cms_get0_signed(cms);
479 if (!sd)
480 return -1;
481 certs = sd->certificates;
482 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
483 si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
484 if (si->signer)
485 continue;
486
487 for (j = 0; j < sk_X509_num(scerts); j++) {
488 x = sk_X509_value(scerts, j);
489 if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
490 CMS_SignerInfo_set1_signer_cert(si, x);
491 ret++;
492 break;
493 }
494 }
495
496 if (si->signer || (flags & CMS_NOINTERN))
497 continue;
498
499 for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
500 cch = sk_CMS_CertificateChoices_value(certs, j);
501 if (cch->type != 0)
502 continue;
503 x = cch->d.certificate;
504 if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
505 CMS_SignerInfo_set1_signer_cert(si, x);
506 ret++;
507 break;
508 }
509 }
510 }
511 return ret;
512}
513
514void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
515 X509 **signer, X509_ALGOR **pdig,
516 X509_ALGOR **psig)
517{
518 if (pk)
519 *pk = si->pkey;
520 if (signer)
521 *signer = si->signer;
522 if (pdig)
523 *pdig = si->digestAlgorithm;
524 if (psig)
525 *psig = si->signatureAlgorithm;
526}
527
528ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si)
529{
530 return si->signature;
531}
532
533static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
534 CMS_SignerInfo *si, BIO *chain)
535{
536 EVP_MD_CTX *mctx = EVP_MD_CTX_new();
537 int r = 0;
538 EVP_PKEY_CTX *pctx = NULL;
539
540 if (mctx == NULL) {
541 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
542 return 0;
543 }
544
545 if (!si->pkey) {
546 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
547 goto err;
548 }
549
550 if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
551 goto err;
552 /* Set SignerInfo algorithm details if we used custom parameter */
553 if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
554 goto err;
555
556 /*
557 * If any signed attributes calculate and add messageDigest attribute
558 */
559
560 if (CMS_signed_get_attr_count(si) >= 0) {
561 ASN1_OBJECT *ctype =
562 cms->d.signedData->encapContentInfo->eContentType;
563 unsigned char md[EVP_MAX_MD_SIZE];
564 unsigned int mdlen;
565 if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
566 goto err;
567 if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
568 V_ASN1_OCTET_STRING, md, mdlen))
569 goto err;
570 /* Copy content type across */
571 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
572 V_ASN1_OBJECT, ctype, -1) <= 0)
573 goto err;
574 if (!CMS_SignerInfo_sign(si))
575 goto err;
576 } else if (si->pctx) {
577 unsigned char *sig;
578 size_t siglen;
579 unsigned char md[EVP_MAX_MD_SIZE];
580 unsigned int mdlen;
581 pctx = si->pctx;
582 if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
583 goto err;
584 siglen = EVP_PKEY_size(si->pkey);
585 sig = OPENSSL_malloc(siglen);
586 if (sig == NULL) {
587 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
588 goto err;
589 }
590 if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) {
591 OPENSSL_free(sig);
592 goto err;
593 }
594 ASN1_STRING_set0(si->signature, sig, siglen);
595 } else {
596 unsigned char *sig;
597 unsigned int siglen;
598 sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
599 if (sig == NULL) {
600 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
601 goto err;
602 }
603 if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) {
604 CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
605 OPENSSL_free(sig);
606 goto err;
607 }
608 ASN1_STRING_set0(si->signature, sig, siglen);
609 }
610
611 r = 1;
612
613 err:
614 EVP_MD_CTX_free(mctx);
615 EVP_PKEY_CTX_free(pctx);
616 return r;
617
618}
619
620int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
621{
622 STACK_OF(CMS_SignerInfo) *sinfos;
623 CMS_SignerInfo *si;
624 int i;
625 sinfos = CMS_get0_SignerInfos(cms);
626 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
627 si = sk_CMS_SignerInfo_value(sinfos, i);
628 if (!cms_SignerInfo_content_sign(cms, si, chain))
629 return 0;
630 }
631 cms->d.signedData->encapContentInfo->partial = 0;
632 return 1;
633}
634
635int CMS_SignerInfo_sign(CMS_SignerInfo *si)
636{
637 EVP_MD_CTX *mctx = si->mctx;
638 EVP_PKEY_CTX *pctx = NULL;
639 unsigned char *abuf = NULL;
640 int alen;
641 size_t siglen;
642 const EVP_MD *md = NULL;
643
644 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
645 if (md == NULL)
646 return 0;
647
648 if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
649 if (!cms_add1_signingTime(si, NULL))
650 goto err;
651 }
652
653 if (si->pctx)
654 pctx = si->pctx;
655 else {
656 EVP_MD_CTX_reset(mctx);
657 if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
658 goto err;
659 si->pctx = pctx;
660 }
661
662 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
663 EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) {
664 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
665 goto err;
666 }
667
668 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
669 ASN1_ITEM_rptr(CMS_Attributes_Sign));
670 if (!abuf)
671 goto err;
672 if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
673 goto err;
674 if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
675 goto err;
676 OPENSSL_free(abuf);
677 abuf = OPENSSL_malloc(siglen);
678 if (abuf == NULL)
679 goto err;
680 if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
681 goto err;
682
683 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
684 EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) {
685 CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
686 goto err;
687 }
688
689 EVP_MD_CTX_reset(mctx);
690
691 ASN1_STRING_set0(si->signature, abuf, siglen);
692
693 return 1;
694
695 err:
696 OPENSSL_free(abuf);
697 EVP_MD_CTX_reset(mctx);
698 return 0;
699
700}
701
702int CMS_SignerInfo_verify(CMS_SignerInfo *si)
703{
704 EVP_MD_CTX *mctx = NULL;
705 unsigned char *abuf = NULL;
706 int alen, r = -1;
707 const EVP_MD *md = NULL;
708
709 if (!si->pkey) {
710 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
711 return -1;
712 }
713
714 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
715 if (md == NULL)
716 return -1;
717 if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) {
718 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, ERR_R_MALLOC_FAILURE);
719 return -1;
720 }
721 mctx = si->mctx;
722 if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
723 goto err;
724
725 if (!cms_sd_asn1_ctrl(si, 1))
726 goto err;
727
728 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
729 ASN1_ITEM_rptr(CMS_Attributes_Verify));
730 if (!abuf)
731 goto err;
732 r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
733 OPENSSL_free(abuf);
734 if (r <= 0) {
735 r = -1;
736 goto err;
737 }
738 r = EVP_DigestVerifyFinal(mctx,
739 si->signature->data, si->signature->length);
740 if (r <= 0)
741 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
742 err:
743 EVP_MD_CTX_reset(mctx);
744 return r;
745}
746
747/* Create a chain of digest BIOs from a CMS ContentInfo */
748
749BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
750{
751 int i;
752 CMS_SignedData *sd;
753 BIO *chain = NULL;
754 sd = cms_get0_signed(cms);
755 if (!sd)
756 return NULL;
757 if (cms->d.signedData->encapContentInfo->partial)
758 cms_sd_set_version(sd);
759 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
760 X509_ALGOR *digestAlgorithm;
761 BIO *mdbio;
762 digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
763 mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
764 if (!mdbio)
765 goto err;
766 if (chain)
767 BIO_push(chain, mdbio);
768 else
769 chain = mdbio;
770 }
771 return chain;
772 err:
773 BIO_free_all(chain);
774 return NULL;
775}
776
777int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
778{
779 ASN1_OCTET_STRING *os = NULL;
780 EVP_MD_CTX *mctx = EVP_MD_CTX_new();
781 EVP_PKEY_CTX *pkctx = NULL;
782 int r = -1;
783 unsigned char mval[EVP_MAX_MD_SIZE];
784 unsigned int mlen;
785
786 if (mctx == NULL) {
787 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, ERR_R_MALLOC_FAILURE);
788 goto err;
789 }
790 /* If we have any signed attributes look for messageDigest value */
791 if (CMS_signed_get_attr_count(si) >= 0) {
792 os = CMS_signed_get0_data_by_OBJ(si,
793 OBJ_nid2obj(NID_pkcs9_messageDigest),
794 -3, V_ASN1_OCTET_STRING);
795 if (!os) {
796 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
797 CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
798 goto err;
799 }
800 }
801
802 if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
803 goto err;
804
805 if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) {
806 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
807 CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
808 goto err;
809 }
810
811 /* If messageDigest found compare it */
812
813 if (os) {
814 if (mlen != (unsigned int)os->length) {
815 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
816 CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
817 goto err;
818 }
819
820 if (memcmp(mval, os->data, mlen)) {
821 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
822 CMS_R_VERIFICATION_FAILURE);
823 r = 0;
824 } else
825 r = 1;
826 } else {
827 const EVP_MD *md = EVP_MD_CTX_md(mctx);
828 pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
829 if (pkctx == NULL)
830 goto err;
831 if (EVP_PKEY_verify_init(pkctx) <= 0)
832 goto err;
833 if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
834 goto err;
835 si->pctx = pkctx;
836 if (!cms_sd_asn1_ctrl(si, 1))
837 goto err;
838 r = EVP_PKEY_verify(pkctx, si->signature->data,
839 si->signature->length, mval, mlen);
840 if (r <= 0) {
841 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
842 CMS_R_VERIFICATION_FAILURE);
843 r = 0;
844 }
845 }
846
847 err:
848 EVP_PKEY_CTX_free(pkctx);
849 EVP_MD_CTX_free(mctx);
850 return r;
851
852}
853
854int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
855{
856 unsigned char *smder = NULL;
857 int smderlen, r;
858 smderlen = i2d_X509_ALGORS(algs, &smder);
859 if (smderlen <= 0)
860 return 0;
861 r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
862 V_ASN1_SEQUENCE, smder, smderlen);
863 OPENSSL_free(smder);
864 return r;
865}
866
867int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
868 int algnid, int keysize)
869{
870 X509_ALGOR *alg;
871 ASN1_INTEGER *key = NULL;
872 if (keysize > 0) {
873 key = ASN1_INTEGER_new();
874 if (key == NULL || !ASN1_INTEGER_set(key, keysize))
875 return 0;
876 }
877 alg = X509_ALGOR_new();
878 if (alg == NULL) {
879 ASN1_INTEGER_free(key);
880 return 0;
881 }
882
883 X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
884 key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
885 if (*algs == NULL)
886 *algs = sk_X509_ALGOR_new_null();
887 if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) {
888 X509_ALGOR_free(alg);
889 return 0;
890 }
891 return 1;
892}
893
894/* Check to see if a cipher exists and if so add S/MIME capabilities */
895
896static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
897{
898 if (EVP_get_cipherbynid(nid))
899 return CMS_add_simple_smimecap(sk, nid, arg);
900 return 1;
901}
902
903static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
904{
905 if (EVP_get_digestbynid(nid))
906 return CMS_add_simple_smimecap(sk, nid, arg);
907 return 1;
908}
909
910int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
911{
912 if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
913 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1)
914 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1)
915 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
916 || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
917 || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
918 || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
919 || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
920 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
921 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
922 || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
923 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
924 return 0;
925 return 1;
926}
diff --git a/src/lib/libcrypto/cms/cms_smime.c b/src/lib/libcrypto/cms/cms_smime.c
new file mode 100644
index 0000000000..5dcf803f4b
--- /dev/null
+++ b/src/lib/libcrypto/cms/cms_smime.c
@@ -0,0 +1,843 @@
1/*
2 * Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include "internal/cryptlib.h"
11#include <openssl/asn1t.h>
12#include <openssl/x509.h>
13#include <openssl/x509v3.h>
14#include <openssl/err.h>
15#include <openssl/cms.h>
16#include "cms_lcl.h"
17#include "internal/asn1_int.h"
18
19static BIO *cms_get_text_bio(BIO *out, unsigned int flags)
20{
21 BIO *rbio;
22 if (out == NULL)
23 rbio = BIO_new(BIO_s_null());
24 else if (flags & CMS_TEXT) {
25 rbio = BIO_new(BIO_s_mem());
26 BIO_set_mem_eof_return(rbio, 0);
27 } else
28 rbio = out;
29 return rbio;
30}
31
32static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
33{
34 unsigned char buf[4096];
35 int r = 0, i;
36 BIO *tmpout;
37
38 tmpout = cms_get_text_bio(out, flags);
39
40 if (tmpout == NULL) {
41 CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE);
42 goto err;
43 }
44
45 /* Read all content through chain to process digest, decrypt etc */
46 for (;;) {
47 i = BIO_read(in, buf, sizeof(buf));
48 if (i <= 0) {
49 if (BIO_method_type(in) == BIO_TYPE_CIPHER) {
50 if (!BIO_get_cipher_status(in))
51 goto err;
52 }
53 if (i < 0)
54 goto err;
55 break;
56 }
57
58 if (tmpout && (BIO_write(tmpout, buf, i) != i))
59 goto err;
60 }
61
62 if (flags & CMS_TEXT) {
63 if (!SMIME_text(tmpout, out)) {
64 CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR);
65 goto err;
66 }
67 }
68
69 r = 1;
70
71 err:
72 if (tmpout != out)
73 BIO_free(tmpout);
74 return r;
75
76}
77
78static int check_content(CMS_ContentInfo *cms)
79{
80 ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
81 if (!pos || !*pos) {
82 CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
83 return 0;
84 }
85 return 1;
86}
87
88static void do_free_upto(BIO *f, BIO *upto)
89{
90 if (upto) {
91 BIO *tbio;
92 do {
93 tbio = BIO_pop(f);
94 BIO_free(f);
95 f = tbio;
96 }
97 while (f && f != upto);
98 } else
99 BIO_free_all(f);
100}
101
102int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
103{
104 BIO *cont;
105 int r;
106 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) {
107 CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
108 return 0;
109 }
110 cont = CMS_dataInit(cms, NULL);
111 if (!cont)
112 return 0;
113 r = cms_copy_content(out, cont, flags);
114 BIO_free_all(cont);
115 return r;
116}
117
118CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
119{
120 CMS_ContentInfo *cms;
121 cms = cms_Data_create();
122 if (!cms)
123 return NULL;
124
125 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
126 return cms;
127
128 CMS_ContentInfo_free(cms);
129
130 return NULL;
131}
132
133int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
134 unsigned int flags)
135{
136 BIO *cont;
137 int r;
138 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) {
139 CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
140 return 0;
141 }
142
143 if (!dcont && !check_content(cms))
144 return 0;
145
146 cont = CMS_dataInit(cms, dcont);
147 if (!cont)
148 return 0;
149 r = cms_copy_content(out, cont, flags);
150 if (r)
151 r = cms_DigestedData_do_final(cms, cont, 1);
152 do_free_upto(cont, dcont);
153 return r;
154}
155
156CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
157 unsigned int flags)
158{
159 CMS_ContentInfo *cms;
160 if (!md)
161 md = EVP_sha1();
162 cms = cms_DigestedData_create(md);
163 if (!cms)
164 return NULL;
165
166 if (!(flags & CMS_DETACHED))
167 CMS_set_detached(cms, 0);
168
169 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
170 return cms;
171
172 CMS_ContentInfo_free(cms);
173 return NULL;
174}
175
176int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
177 const unsigned char *key, size_t keylen,
178 BIO *dcont, BIO *out, unsigned int flags)
179{
180 BIO *cont;
181 int r;
182 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) {
183 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
184 CMS_R_TYPE_NOT_ENCRYPTED_DATA);
185 return 0;
186 }
187
188 if (!dcont && !check_content(cms))
189 return 0;
190
191 if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
192 return 0;
193 cont = CMS_dataInit(cms, dcont);
194 if (!cont)
195 return 0;
196 r = cms_copy_content(out, cont, flags);
197 do_free_upto(cont, dcont);
198 return r;
199}
200
201CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
202 const unsigned char *key,
203 size_t keylen, unsigned int flags)
204{
205 CMS_ContentInfo *cms;
206 if (!cipher) {
207 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
208 return NULL;
209 }
210 cms = CMS_ContentInfo_new();
211 if (cms == NULL)
212 return NULL;
213 if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
214 return NULL;
215
216 if (!(flags & CMS_DETACHED))
217 CMS_set_detached(cms, 0);
218
219 if ((flags & (CMS_STREAM | CMS_PARTIAL))
220 || CMS_final(cms, in, NULL, flags))
221 return cms;
222
223 CMS_ContentInfo_free(cms);
224 return NULL;
225}
226
227static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
228 X509_STORE *store,
229 STACK_OF(X509) *certs,
230 STACK_OF(X509_CRL) *crls)
231{
232 X509_STORE_CTX *ctx = X509_STORE_CTX_new();
233 X509 *signer;
234 int i, j, r = 0;
235
236 if (ctx == NULL) {
237 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
238 goto err;
239 }
240 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
241 if (!X509_STORE_CTX_init(ctx, store, signer, certs)) {
242 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR);
243 goto err;
244 }
245 X509_STORE_CTX_set_default(ctx, "smime_sign");
246 if (crls)
247 X509_STORE_CTX_set0_crls(ctx, crls);
248
249 i = X509_verify_cert(ctx);
250 if (i <= 0) {
251 j = X509_STORE_CTX_get_error(ctx);
252 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
253 CMS_R_CERTIFICATE_VERIFY_ERROR);
254 ERR_add_error_data(2, "Verify error:",
255 X509_verify_cert_error_string(j));
256 goto err;
257 }
258 r = 1;
259 err:
260 X509_STORE_CTX_free(ctx);
261 return r;
262
263}
264
265int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
266 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
267{
268 CMS_SignerInfo *si;
269 STACK_OF(CMS_SignerInfo) *sinfos;
270 STACK_OF(X509) *cms_certs = NULL;
271 STACK_OF(X509_CRL) *crls = NULL;
272 X509 *signer;
273 int i, scount = 0, ret = 0;
274 BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
275
276 if (!dcont && !check_content(cms))
277 return 0;
278 if (dcont && !(flags & CMS_BINARY)) {
279 const ASN1_OBJECT *coid = CMS_get0_eContentType(cms);
280 if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF)
281 flags |= CMS_ASCIICRLF;
282 }
283
284 /* Attempt to find all signer certificates */
285
286 sinfos = CMS_get0_SignerInfos(cms);
287
288 if (sk_CMS_SignerInfo_num(sinfos) <= 0) {
289 CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
290 goto err;
291 }
292
293 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
294 si = sk_CMS_SignerInfo_value(sinfos, i);
295 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
296 if (signer)
297 scount++;
298 }
299
300 if (scount != sk_CMS_SignerInfo_num(sinfos))
301 scount += CMS_set1_signers_certs(cms, certs, flags);
302
303 if (scount != sk_CMS_SignerInfo_num(sinfos)) {
304 CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
305 goto err;
306 }
307
308 /* Attempt to verify all signers certs */
309
310 if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) {
311 cms_certs = CMS_get1_certs(cms);
312 if (!(flags & CMS_NOCRL))
313 crls = CMS_get1_crls(cms);
314 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
315 si = sk_CMS_SignerInfo_value(sinfos, i);
316 if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls))
317 goto err;
318 }
319 }
320
321 /* Attempt to verify all SignerInfo signed attribute signatures */
322
323 if (!(flags & CMS_NO_ATTR_VERIFY)) {
324 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
325 si = sk_CMS_SignerInfo_value(sinfos, i);
326 if (CMS_signed_get_attr_count(si) < 0)
327 continue;
328 if (CMS_SignerInfo_verify(si) <= 0)
329 goto err;
330 }
331 }
332
333 /*
334 * Performance optimization: if the content is a memory BIO then store
335 * its contents in a temporary read only memory BIO. This avoids
336 * potentially large numbers of slow copies of data which will occur when
337 * reading from a read write memory BIO when signatures are calculated.
338 */
339
340 if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
341 char *ptr;
342 long len;
343 len = BIO_get_mem_data(dcont, &ptr);
344 tmpin = BIO_new_mem_buf(ptr, len);
345 if (tmpin == NULL) {
346 CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
347 goto err2;
348 }
349 } else
350 tmpin = dcont;
351 /*
352 * If not binary mode and detached generate digests by *writing* through
353 * the BIO. That makes it possible to canonicalise the input.
354 */
355 if (!(flags & SMIME_BINARY) && dcont) {
356 /*
357 * Create output BIO so we can either handle text or to ensure
358 * included content doesn't override detached content.
359 */
360 tmpout = cms_get_text_bio(out, flags);
361 if (!tmpout) {
362 CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
363 goto err;
364 }
365 cmsbio = CMS_dataInit(cms, tmpout);
366 if (!cmsbio)
367 goto err;
368 /*
369 * Don't use SMIME_TEXT for verify: it adds headers and we want to
370 * remove them.
371 */
372 SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT);
373
374 if (flags & CMS_TEXT) {
375 if (!SMIME_text(tmpout, out)) {
376 CMSerr(CMS_F_CMS_VERIFY, CMS_R_SMIME_TEXT_ERROR);
377 goto err;
378 }
379 }
380 } else {
381 cmsbio = CMS_dataInit(cms, tmpin);
382 if (!cmsbio)
383 goto err;
384
385 if (!cms_copy_content(out, cmsbio, flags))
386 goto err;
387
388 }
389 if (!(flags & CMS_NO_CONTENT_VERIFY)) {
390 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
391 si = sk_CMS_SignerInfo_value(sinfos, i);
392 if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) {
393 CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR);
394 goto err;
395 }
396 }
397 }
398
399 ret = 1;
400
401 err:
402 if (!(flags & SMIME_BINARY) && dcont) {
403 do_free_upto(cmsbio, tmpout);
404 if (tmpin != dcont)
405 BIO_free(tmpin);
406 } else {
407 if (dcont && (tmpin == dcont))
408 do_free_upto(cmsbio, dcont);
409 else
410 BIO_free_all(cmsbio);
411 }
412
413 if (out != tmpout)
414 BIO_free_all(tmpout);
415
416 err2:
417 sk_X509_pop_free(cms_certs, X509_free);
418 sk_X509_CRL_pop_free(crls, X509_CRL_free);
419
420 return ret;
421}
422
423int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
424 STACK_OF(X509) *certs,
425 X509_STORE *store, unsigned int flags)
426{
427 int r;
428 flags &= ~(CMS_DETACHED | CMS_TEXT);
429 r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
430 if (r <= 0)
431 return r;
432 return cms_Receipt_verify(rcms, ocms);
433}
434
435CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
436 STACK_OF(X509) *certs, BIO *data,
437 unsigned int flags)
438{
439 CMS_ContentInfo *cms;
440 int i;
441
442 cms = CMS_ContentInfo_new();
443 if (cms == NULL || !CMS_SignedData_init(cms))
444 goto merr;
445 if (flags & CMS_ASCIICRLF
446 && !CMS_set1_eContentType(cms,
447 OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF)))
448 goto err;
449
450 if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
451 CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
452 goto err;
453 }
454
455 for (i = 0; i < sk_X509_num(certs); i++) {
456 X509 *x = sk_X509_value(certs, i);
457 if (!CMS_add1_cert(cms, x))
458 goto merr;
459 }
460
461 if (!(flags & CMS_DETACHED))
462 CMS_set_detached(cms, 0);
463
464 if ((flags & (CMS_STREAM | CMS_PARTIAL))
465 || CMS_final(cms, data, NULL, flags))
466 return cms;
467 else
468 goto err;
469
470 merr:
471 CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
472
473 err:
474 CMS_ContentInfo_free(cms);
475 return NULL;
476}
477
478CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
479 X509 *signcert, EVP_PKEY *pkey,
480 STACK_OF(X509) *certs, unsigned int flags)
481{
482 CMS_SignerInfo *rct_si;
483 CMS_ContentInfo *cms = NULL;
484 ASN1_OCTET_STRING **pos, *os;
485 BIO *rct_cont = NULL;
486 int r = 0;
487
488 flags &= ~(CMS_STREAM | CMS_TEXT);
489 /* Not really detached but avoids content being allocated */
490 flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED;
491 if (!pkey || !signcert) {
492 CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
493 return NULL;
494 }
495
496 /* Initialize signed data */
497
498 cms = CMS_sign(NULL, NULL, certs, NULL, flags);
499 if (!cms)
500 goto err;
501
502 /* Set inner content type to signed receipt */
503 if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
504 goto err;
505
506 rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
507 if (!rct_si) {
508 CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
509 goto err;
510 }
511
512 os = cms_encode_Receipt(si);
513
514 if (!os)
515 goto err;
516
517 /* Set content to digest */
518 rct_cont = BIO_new_mem_buf(os->data, os->length);
519 if (!rct_cont)
520 goto err;
521
522 /* Add msgSigDigest attribute */
523
524 if (!cms_msgSigDigest_add1(rct_si, si))
525 goto err;
526
527 /* Finalize structure */
528 if (!CMS_final(cms, rct_cont, NULL, flags))
529 goto err;
530
531 /* Set embedded content */
532 pos = CMS_get0_content(cms);
533 *pos = os;
534
535 r = 1;
536
537 err:
538 BIO_free(rct_cont);
539 if (r)
540 return cms;
541 CMS_ContentInfo_free(cms);
542 return NULL;
543
544}
545
546CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
547 const EVP_CIPHER *cipher, unsigned int flags)
548{
549 CMS_ContentInfo *cms;
550 int i;
551 X509 *recip;
552 cms = CMS_EnvelopedData_create(cipher);
553 if (!cms)
554 goto merr;
555 for (i = 0; i < sk_X509_num(certs); i++) {
556 recip = sk_X509_value(certs, i);
557 if (!CMS_add1_recipient_cert(cms, recip, flags)) {
558 CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
559 goto err;
560 }
561 }
562
563 if (!(flags & CMS_DETACHED))
564 CMS_set_detached(cms, 0);
565
566 if ((flags & (CMS_STREAM | CMS_PARTIAL))
567 || CMS_final(cms, data, NULL, flags))
568 return cms;
569 else
570 goto err;
571
572 merr:
573 CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
574 err:
575 CMS_ContentInfo_free(cms);
576 return NULL;
577}
578
579static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
580 EVP_PKEY *pk, X509 *cert)
581{
582 int i;
583 STACK_OF(CMS_RecipientEncryptedKey) *reks;
584 CMS_RecipientEncryptedKey *rek;
585 reks = CMS_RecipientInfo_kari_get0_reks(ri);
586 for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
587 int rv;
588 rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
589 if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert))
590 continue;
591 CMS_RecipientInfo_kari_set0_pkey(ri, pk);
592 rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek);
593 CMS_RecipientInfo_kari_set0_pkey(ri, NULL);
594 if (rv > 0)
595 return 1;
596 return cert == NULL ? 0 : -1;
597 }
598 return 0;
599}
600
601int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
602{
603 STACK_OF(CMS_RecipientInfo) *ris;
604 CMS_RecipientInfo *ri;
605 int i, r, ri_type;
606 int debug = 0, match_ri = 0;
607 ris = CMS_get0_RecipientInfos(cms);
608 if (ris)
609 debug = cms->d.envelopedData->encryptedContentInfo->debug;
610 ri_type = cms_pkey_get_ri_type(pk);
611 if (ri_type == CMS_RECIPINFO_NONE) {
612 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
613 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
614 return 0;
615 }
616
617 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
618 ri = sk_CMS_RecipientInfo_value(ris, i);
619 if (CMS_RecipientInfo_type(ri) != ri_type)
620 continue;
621 match_ri = 1;
622 if (ri_type == CMS_RECIPINFO_AGREE) {
623 r = cms_kari_set1_pkey(cms, ri, pk, cert);
624 if (r > 0)
625 return 1;
626 if (r < 0)
627 return 0;
628 }
629 /*
630 * If we have a cert try matching RecipientInfo otherwise try them
631 * all.
632 */
633 else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
634 EVP_PKEY_up_ref(pk);
635 CMS_RecipientInfo_set0_pkey(ri, pk);
636 r = CMS_RecipientInfo_decrypt(cms, ri);
637 CMS_RecipientInfo_set0_pkey(ri, NULL);
638 if (cert) {
639 /*
640 * If not debugging clear any error and return success to
641 * avoid leaking of information useful to MMA
642 */
643 if (!debug) {
644 ERR_clear_error();
645 return 1;
646 }
647 if (r > 0)
648 return 1;
649 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR);
650 return 0;
651 }
652 /*
653 * If no cert and not debugging don't leave loop after first
654 * successful decrypt. Always attempt to decrypt all recipients
655 * to avoid leaking timing of a successful decrypt.
656 */
657 else if (r > 0 && debug)
658 return 1;
659 }
660 }
661 /* If no cert, key transport and not debugging always return success */
662 if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) {
663 ERR_clear_error();
664 return 1;
665 }
666
667 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
668 return 0;
669
670}
671
672int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
673 unsigned char *key, size_t keylen,
674 const unsigned char *id, size_t idlen)
675{
676 STACK_OF(CMS_RecipientInfo) *ris;
677 CMS_RecipientInfo *ri;
678 int i, r;
679 ris = CMS_get0_RecipientInfos(cms);
680 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
681 ri = sk_CMS_RecipientInfo_value(ris, i);
682 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
683 continue;
684
685 /*
686 * If we have an id try matching RecipientInfo otherwise try them
687 * all.
688 */
689 if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
690 CMS_RecipientInfo_set0_key(ri, key, keylen);
691 r = CMS_RecipientInfo_decrypt(cms, ri);
692 CMS_RecipientInfo_set0_key(ri, NULL, 0);
693 if (r > 0)
694 return 1;
695 if (id) {
696 CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR);
697 return 0;
698 }
699 ERR_clear_error();
700 }
701 }
702
703 CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
704 return 0;
705
706}
707
708int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
709 unsigned char *pass, ossl_ssize_t passlen)
710{
711 STACK_OF(CMS_RecipientInfo) *ris;
712 CMS_RecipientInfo *ri;
713 int i, r;
714 ris = CMS_get0_RecipientInfos(cms);
715 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
716 ri = sk_CMS_RecipientInfo_value(ris, i);
717 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
718 continue;
719 CMS_RecipientInfo_set0_password(ri, pass, passlen);
720 r = CMS_RecipientInfo_decrypt(cms, ri);
721 CMS_RecipientInfo_set0_password(ri, NULL, 0);
722 if (r > 0)
723 return 1;
724 }
725
726 CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT);
727 return 0;
728
729}
730
731int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
732 BIO *dcont, BIO *out, unsigned int flags)
733{
734 int r;
735 BIO *cont;
736 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) {
737 CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
738 return 0;
739 }
740 if (!dcont && !check_content(cms))
741 return 0;
742 if (flags & CMS_DEBUG_DECRYPT)
743 cms->d.envelopedData->encryptedContentInfo->debug = 1;
744 else
745 cms->d.envelopedData->encryptedContentInfo->debug = 0;
746 if (!pk && !cert && !dcont && !out)
747 return 1;
748 if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
749 return 0;
750 cont = CMS_dataInit(cms, dcont);
751 if (!cont)
752 return 0;
753 r = cms_copy_content(out, cont, flags);
754 do_free_upto(cont, dcont);
755 return r;
756}
757
758int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
759{
760 BIO *cmsbio;
761 int ret = 0;
762
763 if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) {
764 CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_LIB);
765 return 0;
766 }
767
768 SMIME_crlf_copy(data, cmsbio, flags);
769
770 (void)BIO_flush(cmsbio);
771
772 if (!CMS_dataFinal(cms, cmsbio)) {
773 CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR);
774 goto err;
775 }
776
777 ret = 1;
778
779 err:
780 do_free_upto(cmsbio, dcont);
781
782 return ret;
783
784}
785
786#ifdef ZLIB
787
788int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
789 unsigned int flags)
790{
791 BIO *cont;
792 int r;
793 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) {
794 CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA);
795 return 0;
796 }
797
798 if (!dcont && !check_content(cms))
799 return 0;
800
801 cont = CMS_dataInit(cms, dcont);
802 if (!cont)
803 return 0;
804 r = cms_copy_content(out, cont, flags);
805 do_free_upto(cont, dcont);
806 return r;
807}
808
809CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
810{
811 CMS_ContentInfo *cms;
812 if (comp_nid <= 0)
813 comp_nid = NID_zlib_compression;
814 cms = cms_CompressedData_create(comp_nid);
815 if (!cms)
816 return NULL;
817
818 if (!(flags & CMS_DETACHED))
819 CMS_set_detached(cms, 0);
820
821 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
822 return cms;
823
824 CMS_ContentInfo_free(cms);
825 return NULL;
826}
827
828#else
829
830int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
831 unsigned int flags)
832{
833 CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
834 return 0;
835}
836
837CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
838{
839 CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
840 return NULL;
841}
842
843#endif