Modify OBJ_nid2sn(OBJ_obj2nid(...)) occurences to use OBJ_obj2txt()
[openssl.git] / crypto / cms / cms_env.c
1 /*
2  * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (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/evp.h>
17 #include "internal/sizes.h"
18 #include "crypto/asn1.h"
19 #include "crypto/evp.h"
20 #include "crypto/x509.h"
21 #include "cms_local.h"
22
23 /* CMS EnvelopedData Utilities */
24 static void cms_env_set_version(CMS_EnvelopedData *env);
25
26 #define CMS_ENVELOPED_STANDARD 1
27 #define CMS_ENVELOPED_AUTH     2
28
29 static int cms_get_enveloped_type(const CMS_ContentInfo *cms)
30 {
31     int nid = OBJ_obj2nid(cms->contentType);
32
33     switch (nid) {
34     case NID_pkcs7_enveloped:
35         return CMS_ENVELOPED_STANDARD;
36
37     case NID_id_smime_ct_authEnvelopedData:
38         return CMS_ENVELOPED_AUTH;
39
40     default:
41         ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
42         return 0;
43     }
44 }
45
46 CMS_EnvelopedData *ossl_cms_get0_enveloped(CMS_ContentInfo *cms)
47 {
48     if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) {
49         ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
50         return NULL;
51     }
52     return cms->d.envelopedData;
53 }
54
55 CMS_AuthEnvelopedData *ossl_cms_get0_auth_enveloped(CMS_ContentInfo *cms)
56 {
57     if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_authEnvelopedData) {
58         ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
59         return NULL;
60     }
61     return cms->d.authEnvelopedData;
62 }
63
64 static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
65 {
66     if (cms->d.other == NULL) {
67         cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
68         if (cms->d.envelopedData == NULL) {
69             ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
70             return NULL;
71         }
72         cms->d.envelopedData->version = 0;
73         cms->d.envelopedData->encryptedContentInfo->contentType =
74             OBJ_nid2obj(NID_pkcs7_data);
75         ASN1_OBJECT_free(cms->contentType);
76         cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
77         return cms->d.envelopedData;
78     }
79     return ossl_cms_get0_enveloped(cms);
80 }
81
82 static CMS_AuthEnvelopedData *
83 cms_auth_enveloped_data_init(CMS_ContentInfo *cms)
84 {
85     if (cms->d.other == NULL) {
86         cms->d.authEnvelopedData = M_ASN1_new_of(CMS_AuthEnvelopedData);
87         if (cms->d.authEnvelopedData == NULL) {
88             ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
89             return NULL;
90         }
91         /* Defined in RFC 5083 - Section 2.1. "AuthEnvelopedData Type" */
92         cms->d.authEnvelopedData->version = 0;
93         cms->d.authEnvelopedData->authEncryptedContentInfo->contentType =
94             OBJ_nid2obj(NID_pkcs7_data);
95         ASN1_OBJECT_free(cms->contentType);
96         cms->contentType = OBJ_nid2obj(NID_id_smime_ct_authEnvelopedData);
97         return cms->d.authEnvelopedData;
98     }
99     return ossl_cms_get0_auth_enveloped(cms);
100 }
101
102 int ossl_cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
103 {
104     EVP_PKEY *pkey;
105     int i;
106     if (ri->type == CMS_RECIPINFO_TRANS)
107         pkey = ri->d.ktri->pkey;
108     else if (ri->type == CMS_RECIPINFO_AGREE) {
109         EVP_PKEY_CTX *pctx = ri->d.kari->pctx;
110
111         if (pctx == NULL)
112             return 0;
113         pkey = EVP_PKEY_CTX_get0_pkey(pctx);
114         if (pkey == NULL)
115             return 0;
116     } else
117         return 0;
118
119     if (EVP_PKEY_is_a(pkey, "DHX") || EVP_PKEY_is_a(pkey, "DH"))
120         return ossl_cms_dh_envelope(ri, cmd);
121     else if (EVP_PKEY_is_a(pkey, "EC"))
122         return ossl_cms_ecdh_envelope(ri, cmd);
123     else if (EVP_PKEY_is_a(pkey, "RSA"))
124         return ossl_cms_rsa_envelope(ri, cmd);
125
126     /* Something else? We'll give engines etc a chance to handle this */
127     if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
128         return 1;
129     i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
130     if (i == -2) {
131         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
132         return 0;
133     }
134     if (i <= 0) {
135         ERR_raise(ERR_LIB_CMS, CMS_R_CTRL_FAILURE);
136         return 0;
137     }
138     return 1;
139 }
140
141 CMS_EncryptedContentInfo* ossl_cms_get0_env_enc_content(const CMS_ContentInfo *cms)
142 {
143     switch (cms_get_enveloped_type(cms)) {
144     case CMS_ENVELOPED_STANDARD:
145         return cms->d.envelopedData->encryptedContentInfo;
146
147     case CMS_ENVELOPED_AUTH:
148         return cms->d.authEnvelopedData->authEncryptedContentInfo;
149
150     default:
151         return NULL;
152     }
153 }
154
155 STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
156 {
157     switch (cms_get_enveloped_type(cms)) {
158     case CMS_ENVELOPED_STANDARD:
159         return cms->d.envelopedData->recipientInfos;
160
161     case CMS_ENVELOPED_AUTH:
162         return cms->d.authEnvelopedData->recipientInfos;
163
164     default:
165         return NULL;
166     }
167 }
168
169 void ossl_cms_RecipientInfos_set_cmsctx(CMS_ContentInfo *cms)
170 {
171     int i;
172     CMS_RecipientInfo *ri;
173     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
174     STACK_OF(CMS_RecipientInfo) *rinfos = CMS_get0_RecipientInfos(cms);
175
176     for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
177         ri = sk_CMS_RecipientInfo_value(rinfos, i);
178         if (ri != NULL) {
179             switch (ri->type) {
180             case CMS_RECIPINFO_AGREE:
181                 ri->d.kari->cms_ctx = ctx;
182                 break;
183             case CMS_RECIPINFO_TRANS:
184                 ri->d.ktri->cms_ctx = ctx;
185                 ossl_x509_set0_libctx(ri->d.ktri->recip,
186                                       ossl_cms_ctx_get0_libctx(ctx),
187                                       ossl_cms_ctx_get0_propq(ctx));
188                 break;
189             case CMS_RECIPINFO_KEK:
190                 ri->d.kekri->cms_ctx = ctx;
191                 break;
192             case CMS_RECIPINFO_PASS:
193                 ri->d.pwri->cms_ctx = ctx;
194                 break;
195             default:
196                 break;
197             }
198         }
199     }
200 }
201
202 int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
203 {
204     return ri->type;
205 }
206
207 EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
208 {
209     if (ri->type == CMS_RECIPINFO_TRANS)
210         return ri->d.ktri->pctx;
211     else if (ri->type == CMS_RECIPINFO_AGREE)
212         return ri->d.kari->pctx;
213     return NULL;
214 }
215
216 CMS_ContentInfo *CMS_EnvelopedData_create_ex(const EVP_CIPHER *cipher,
217                                              OSSL_LIB_CTX *libctx,
218                                              const char *propq)
219 {
220     CMS_ContentInfo *cms;
221     CMS_EnvelopedData *env;
222
223     cms = CMS_ContentInfo_new_ex(libctx, propq);
224     if (cms == NULL)
225         goto merr;
226     env = cms_enveloped_data_init(cms);
227     if (env == NULL)
228         goto merr;
229
230     if (!ossl_cms_EncryptedContent_init(env->encryptedContentInfo, cipher, NULL,
231                                         0, ossl_cms_get0_cmsctx(cms)))
232         goto merr;
233     return cms;
234  merr:
235     CMS_ContentInfo_free(cms);
236     ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
237     return NULL;
238 }
239
240 CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
241 {
242     return CMS_EnvelopedData_create_ex(cipher, NULL, NULL);
243 }
244
245 CMS_ContentInfo *
246 CMS_AuthEnvelopedData_create_ex(const EVP_CIPHER *cipher, OSSL_LIB_CTX *libctx,
247                                 const char *propq)
248 {
249     CMS_ContentInfo *cms;
250     CMS_AuthEnvelopedData *aenv;
251
252     cms = CMS_ContentInfo_new_ex(libctx, propq);
253     if (cms == NULL)
254         goto merr;
255     aenv = cms_auth_enveloped_data_init(cms);
256     if (aenv == NULL)
257         goto merr;
258     if (!ossl_cms_EncryptedContent_init(aenv->authEncryptedContentInfo,
259                                         cipher, NULL, 0,
260                                         ossl_cms_get0_cmsctx(cms)))
261         goto merr;
262     return cms;
263  merr:
264     CMS_ContentInfo_free(cms);
265     ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
266     return NULL;
267 }
268
269
270 CMS_ContentInfo *CMS_AuthEnvelopedData_create(const EVP_CIPHER *cipher)
271 {
272     return CMS_AuthEnvelopedData_create_ex(cipher, NULL, NULL);
273 }
274
275 /* Key Transport Recipient Info (KTRI) routines */
276
277 /* Initialise a ktri based on passed certificate and key */
278
279 static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
280                                        EVP_PKEY *pk, unsigned int flags,
281                                        const CMS_CTX *ctx)
282 {
283     CMS_KeyTransRecipientInfo *ktri;
284     int idtype;
285
286     ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
287     if (!ri->d.ktri)
288         return 0;
289     ri->type = CMS_RECIPINFO_TRANS;
290
291     ktri = ri->d.ktri;
292     ktri->cms_ctx = ctx;
293
294     if (flags & CMS_USE_KEYID) {
295         ktri->version = 2;
296         idtype = CMS_RECIPINFO_KEYIDENTIFIER;
297     } else {
298         ktri->version = 0;
299         idtype = CMS_RECIPINFO_ISSUER_SERIAL;
300     }
301
302     /*
303      * Not a typo: RecipientIdentifier and SignerIdentifier are the same
304      * structure.
305      */
306
307     if (!ossl_cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx))
308         return 0;
309
310     X509_up_ref(recip);
311     EVP_PKEY_up_ref(pk);
312
313     ktri->pkey = pk;
314     ktri->recip = recip;
315
316     if (flags & CMS_KEY_PARAM) {
317         ktri->pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
318                                                 ktri->pkey,
319                                                 ossl_cms_ctx_get0_propq(ctx));
320         if (ktri->pctx == NULL)
321             return 0;
322         if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
323             return 0;
324     } else if (!ossl_cms_env_asn1_ctrl(ri, 0))
325         return 0;
326     return 1;
327 }
328
329 /*
330  * Add a recipient certificate using appropriate type of RecipientInfo
331  */
332
333 CMS_RecipientInfo *CMS_add1_recipient(CMS_ContentInfo *cms, X509 *recip,
334                                       EVP_PKEY *originatorPrivKey,
335                                       X509 *originator, unsigned int flags)
336 {
337     CMS_RecipientInfo *ri = NULL;
338     STACK_OF(CMS_RecipientInfo) *ris;
339     EVP_PKEY *pk = NULL;
340     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
341
342     ris = CMS_get0_RecipientInfos(cms);
343     if (ris == NULL)
344         goto err;
345
346     /* Initialize recipient info */
347     ri = M_ASN1_new_of(CMS_RecipientInfo);
348     if (ri == NULL)
349         goto merr;
350
351     pk = X509_get0_pubkey(recip);
352     if (pk == NULL) {
353         ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_GETTING_PUBLIC_KEY);
354         goto err;
355     }
356
357     switch (ossl_cms_pkey_get_ri_type(pk)) {
358
359     case CMS_RECIPINFO_TRANS:
360         if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags, ctx))
361             goto err;
362         break;
363
364     case CMS_RECIPINFO_AGREE:
365         if (!ossl_cms_RecipientInfo_kari_init(ri, recip, pk, originator,
366                                               originatorPrivKey, flags, ctx))
367             goto err;
368         break;
369
370     default:
371         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
372         goto err;
373
374     }
375
376     if (!sk_CMS_RecipientInfo_push(ris, ri))
377         goto merr;
378
379     return ri;
380
381  merr:
382     ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
383  err:
384     M_ASN1_free_of(ri, CMS_RecipientInfo);
385     return NULL;
386
387 }
388
389 CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, X509 *recip,
390                                            unsigned int flags)
391 {
392      return CMS_add1_recipient(cms, recip, NULL, NULL, flags);
393 }
394
395 int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
396                                      EVP_PKEY **pk, X509 **recip,
397                                      X509_ALGOR **palg)
398 {
399     CMS_KeyTransRecipientInfo *ktri;
400     if (ri->type != CMS_RECIPINFO_TRANS) {
401         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT);
402         return 0;
403     }
404
405     ktri = ri->d.ktri;
406
407     if (pk)
408         *pk = ktri->pkey;
409     if (recip)
410         *recip = ktri->recip;
411     if (palg)
412         *palg = ktri->keyEncryptionAlgorithm;
413     return 1;
414 }
415
416 int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
417                                           ASN1_OCTET_STRING **keyid,
418                                           X509_NAME **issuer,
419                                           ASN1_INTEGER **sno)
420 {
421     CMS_KeyTransRecipientInfo *ktri;
422     if (ri->type != CMS_RECIPINFO_TRANS) {
423         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT);
424         return 0;
425     }
426     ktri = ri->d.ktri;
427
428     return ossl_cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer,
429                                                     sno);
430 }
431
432 int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
433 {
434     if (ri->type != CMS_RECIPINFO_TRANS) {
435         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT);
436         return -2;
437     }
438     return ossl_cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
439 }
440
441 int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
442 {
443     if (ri->type != CMS_RECIPINFO_TRANS) {
444         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT);
445         return 0;
446     }
447     EVP_PKEY_free(ri->d.ktri->pkey);
448     ri->d.ktri->pkey = pkey;
449     return 1;
450 }
451
452 /* Encrypt content key in key transport recipient info */
453
454 static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms,
455                                           CMS_RecipientInfo *ri)
456 {
457     CMS_KeyTransRecipientInfo *ktri;
458     CMS_EncryptedContentInfo *ec;
459     EVP_PKEY_CTX *pctx;
460     unsigned char *ek = NULL;
461     size_t eklen;
462     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
463
464     int ret = 0;
465
466     if (ri->type != CMS_RECIPINFO_TRANS) {
467         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT);
468         return 0;
469     }
470     ktri = ri->d.ktri;
471     ec = ossl_cms_get0_env_enc_content(cms);
472
473     pctx = ktri->pctx;
474
475     if (pctx) {
476         if (!ossl_cms_env_asn1_ctrl(ri, 0))
477             goto err;
478     } else {
479         pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
480                                           ktri->pkey,
481                                           ossl_cms_ctx_get0_propq(ctx));
482         if (pctx == NULL)
483             return 0;
484
485         if (EVP_PKEY_encrypt_init(pctx) <= 0)
486             goto err;
487     }
488
489     if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
490         goto err;
491
492     ek = OPENSSL_malloc(eklen);
493
494     if (ek == NULL) {
495         ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
496         goto err;
497     }
498
499     if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
500         goto err;
501
502     ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
503     ek = NULL;
504
505     ret = 1;
506
507  err:
508     EVP_PKEY_CTX_free(pctx);
509     ktri->pctx = NULL;
510     OPENSSL_free(ek);
511     return ret;
512 }
513
514 /* Decrypt content key from KTRI */
515
516 static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
517                                           CMS_RecipientInfo *ri)
518 {
519     CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
520     EVP_PKEY *pkey = ktri->pkey;
521     unsigned char *ek = NULL;
522     size_t eklen;
523     int ret = 0;
524     size_t fixlen = 0;
525     const EVP_CIPHER *cipher = NULL;
526     EVP_CIPHER *fetched_cipher = NULL;
527     CMS_EncryptedContentInfo *ec;
528     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
529     OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx);
530     const char *propq = ossl_cms_ctx_get0_propq(ctx);
531
532     ec = ossl_cms_get0_env_enc_content(cms);
533
534     if (ktri->pkey == NULL) {
535         ERR_raise(ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY);
536         return 0;
537     }
538
539     if (cms->d.envelopedData->encryptedContentInfo->havenocert
540             && !cms->d.envelopedData->encryptedContentInfo->debug) {
541         X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
542         char name[OSSL_MAX_NAME_SIZE];
543
544         OBJ_obj2txt(name, sizeof(name), calg->algorithm, 0);
545
546         (void)ERR_set_mark();
547         fetched_cipher = EVP_CIPHER_fetch(libctx, name, propq);
548
549         if (fetched_cipher != NULL)
550             cipher = fetched_cipher;
551         else
552             cipher = EVP_get_cipherbyobj(calg->algorithm);
553         if (cipher == NULL) {
554             (void)ERR_clear_last_mark();
555             ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER);
556             return 0;
557         }
558         (void)ERR_pop_to_mark();
559
560         fixlen = EVP_CIPHER_key_length(cipher);
561         EVP_CIPHER_free(fetched_cipher);
562     }
563
564     ktri->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, propq);
565     if (ktri->pctx == NULL)
566         goto err;
567
568     if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
569         goto err;
570
571     if (!ossl_cms_env_asn1_ctrl(ri, 1))
572         goto err;
573
574     if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
575                          ktri->encryptedKey->data,
576                          ktri->encryptedKey->length) <= 0)
577         goto err;
578
579     ek = OPENSSL_malloc(eklen);
580     if (ek == NULL) {
581         ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
582         goto err;
583     }
584
585     if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
586                          ktri->encryptedKey->data,
587                          ktri->encryptedKey->length) <= 0
588             || eklen == 0
589             || (fixlen != 0 && eklen != fixlen)) {
590         ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB);
591         goto err;
592     }
593
594     ret = 1;
595
596     OPENSSL_clear_free(ec->key, ec->keylen);
597     ec->key = ek;
598     ec->keylen = eklen;
599
600  err:
601     EVP_PKEY_CTX_free(ktri->pctx);
602     ktri->pctx = NULL;
603     if (!ret)
604         OPENSSL_free(ek);
605
606     return ret;
607 }
608
609 /* Key Encrypted Key (KEK) RecipientInfo routines */
610
611 int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
612                                    const unsigned char *id, size_t idlen)
613 {
614     ASN1_OCTET_STRING tmp_os;
615     CMS_KEKRecipientInfo *kekri;
616     if (ri->type != CMS_RECIPINFO_KEK) {
617         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEK);
618         return -2;
619     }
620     kekri = ri->d.kekri;
621     tmp_os.type = V_ASN1_OCTET_STRING;
622     tmp_os.flags = 0;
623     tmp_os.data = (unsigned char *)id;
624     tmp_os.length = (int)idlen;
625     return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
626 }
627
628 /* For now hard code AES key wrap info */
629
630 static size_t aes_wrap_keylen(int nid)
631 {
632     switch (nid) {
633     case NID_id_aes128_wrap:
634         return 16;
635
636     case NID_id_aes192_wrap:
637         return 24;
638
639     case NID_id_aes256_wrap:
640         return 32;
641
642     default:
643         return 0;
644     }
645 }
646
647 CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
648                                           unsigned char *key, size_t keylen,
649                                           unsigned char *id, size_t idlen,
650                                           ASN1_GENERALIZEDTIME *date,
651                                           ASN1_OBJECT *otherTypeId,
652                                           ASN1_TYPE *otherType)
653 {
654     CMS_RecipientInfo *ri = NULL;
655     CMS_KEKRecipientInfo *kekri;
656     STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms);
657
658     if (ris == NULL)
659         goto err;
660
661     if (nid == NID_undef) {
662         switch (keylen) {
663         case 16:
664             nid = NID_id_aes128_wrap;
665             break;
666
667         case 24:
668             nid = NID_id_aes192_wrap;
669             break;
670
671         case 32:
672             nid = NID_id_aes256_wrap;
673             break;
674
675         default:
676             ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH);
677             goto err;
678         }
679
680     } else {
681
682         size_t exp_keylen = aes_wrap_keylen(nid);
683
684         if (!exp_keylen) {
685             ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEK_ALGORITHM);
686             goto err;
687         }
688
689         if (keylen != exp_keylen) {
690             ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH);
691             goto err;
692         }
693
694     }
695
696     /* Initialize recipient info */
697     ri = M_ASN1_new_of(CMS_RecipientInfo);
698     if (!ri)
699         goto merr;
700
701     ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
702     if (!ri->d.kekri)
703         goto merr;
704     ri->type = CMS_RECIPINFO_KEK;
705
706     kekri = ri->d.kekri;
707
708     if (otherTypeId) {
709         kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
710         if (kekri->kekid->other == NULL)
711             goto merr;
712     }
713
714     if (!sk_CMS_RecipientInfo_push(ris, ri))
715         goto merr;
716
717     /* After this point no calls can fail */
718
719     kekri->version = 4;
720
721     kekri->key = key;
722     kekri->keylen = keylen;
723
724     ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
725
726     kekri->kekid->date = date;
727
728     if (kekri->kekid->other) {
729         kekri->kekid->other->keyAttrId = otherTypeId;
730         kekri->kekid->other->keyAttr = otherType;
731     }
732
733     X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
734                     OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
735
736     return ri;
737
738  merr:
739     ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
740  err:
741     M_ASN1_free_of(ri, CMS_RecipientInfo);
742     return NULL;
743 }
744
745 int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
746                                     X509_ALGOR **palg,
747                                     ASN1_OCTET_STRING **pid,
748                                     ASN1_GENERALIZEDTIME **pdate,
749                                     ASN1_OBJECT **potherid,
750                                     ASN1_TYPE **pothertype)
751 {
752     CMS_KEKIdentifier *rkid;
753     if (ri->type != CMS_RECIPINFO_KEK) {
754         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEK);
755         return 0;
756     }
757     rkid = ri->d.kekri->kekid;
758     if (palg)
759         *palg = ri->d.kekri->keyEncryptionAlgorithm;
760     if (pid)
761         *pid = rkid->keyIdentifier;
762     if (pdate)
763         *pdate = rkid->date;
764     if (potherid) {
765         if (rkid->other)
766             *potherid = rkid->other->keyAttrId;
767         else
768             *potherid = NULL;
769     }
770     if (pothertype) {
771         if (rkid->other)
772             *pothertype = rkid->other->keyAttr;
773         else
774             *pothertype = NULL;
775     }
776     return 1;
777 }
778
779 int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
780                                unsigned char *key, size_t keylen)
781 {
782     CMS_KEKRecipientInfo *kekri;
783     if (ri->type != CMS_RECIPINFO_KEK) {
784         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_KEK);
785         return 0;
786     }
787
788     kekri = ri->d.kekri;
789     kekri->key = key;
790     kekri->keylen = keylen;
791     return 1;
792 }
793
794 static EVP_CIPHER *cms_get_key_wrap_cipher(size_t keylen, const CMS_CTX *ctx)
795 {
796     const char *alg = NULL;
797
798     switch(keylen) {
799     case 16:
800         alg = "AES-128-WRAP";
801         break;
802     case 24:
803         alg = "AES-192-WRAP";
804         break;
805     case 32:
806         alg = "AES-256-WRAP";
807         break;
808     default:
809         return NULL;
810     }
811     return EVP_CIPHER_fetch(ossl_cms_ctx_get0_libctx(ctx), alg,
812                             ossl_cms_ctx_get0_propq(ctx));
813 }
814
815
816 /* Encrypt content key in KEK recipient info */
817
818 static int cms_RecipientInfo_kekri_encrypt(const CMS_ContentInfo *cms,
819                                            CMS_RecipientInfo *ri)
820 {
821     CMS_EncryptedContentInfo *ec;
822     CMS_KEKRecipientInfo *kekri;
823     unsigned char *wkey = NULL;
824     int wkeylen;
825     int r = 0;
826     EVP_CIPHER *cipher = NULL;
827     int outlen = 0;
828     EVP_CIPHER_CTX *ctx = NULL;
829     const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms);
830
831     ec = ossl_cms_get0_env_enc_content(cms);
832     if (ec == NULL)
833         return 0;
834
835     kekri = ri->d.kekri;
836
837     if (kekri->key == NULL) {
838         ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY);
839         return 0;
840     }
841
842     cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx);
843     if (cipher == NULL) {
844         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH);
845         goto err;
846     }
847
848     /* 8 byte prefix for AES wrap ciphers */
849     wkey = OPENSSL_malloc(ec->keylen + 8);
850     if (wkey == NULL) {
851         ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
852         goto err;
853     }
854
855     ctx = EVP_CIPHER_CTX_new();
856     if (ctx == NULL) {
857         ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
858         goto err;
859     }
860
861     EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
862     if (!EVP_EncryptInit_ex(ctx, cipher, NULL, kekri->key, NULL)
863             || !EVP_EncryptUpdate(ctx, wkey, &wkeylen, ec->key, ec->keylen)
864             || !EVP_EncryptFinal_ex(ctx, wkey + wkeylen, &outlen)) {
865         ERR_raise(ERR_LIB_CMS, CMS_R_WRAP_ERROR);
866         goto err;
867     }
868     wkeylen += outlen;
869     if (!ossl_assert((size_t)wkeylen == ec->keylen + 8)) {
870         ERR_raise(ERR_LIB_CMS, CMS_R_WRAP_ERROR);
871         goto err;
872     }
873
874     ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
875
876     r = 1;
877
878  err:
879     EVP_CIPHER_free(cipher);
880     if (!r)
881         OPENSSL_free(wkey);
882     EVP_CIPHER_CTX_free(ctx);
883
884     return r;
885 }
886
887 /* Decrypt content key in KEK recipient info */
888
889 static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
890                                            CMS_RecipientInfo *ri)
891 {
892     CMS_EncryptedContentInfo *ec;
893     CMS_KEKRecipientInfo *kekri;
894     unsigned char *ukey = NULL;
895     int ukeylen;
896     int r = 0, wrap_nid;
897     EVP_CIPHER *cipher = NULL;
898     int outlen = 0;
899     EVP_CIPHER_CTX *ctx = NULL;
900     const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms);
901
902     ec = ossl_cms_get0_env_enc_content(cms);
903     if (ec == NULL)
904         return 0;
905
906     kekri = ri->d.kekri;
907
908     if (!kekri->key) {
909         ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY);
910         return 0;
911     }
912
913     wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
914     if (aes_wrap_keylen(wrap_nid) != kekri->keylen) {
915         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH);
916         return 0;
917     }
918
919     /* If encrypted key length is invalid don't bother */
920
921     if (kekri->encryptedKey->length < 16) {
922         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
923         goto err;
924     }
925
926     cipher = cms_get_key_wrap_cipher(kekri->keylen, cms_ctx);
927     if (cipher == NULL) {
928         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH);
929         goto err;
930     }
931
932     ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
933     if (ukey == NULL) {
934         ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
935         goto err;
936     }
937
938     ctx = EVP_CIPHER_CTX_new();
939     if (ctx == NULL) {
940         ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
941         goto err;
942     }
943
944     if (!EVP_DecryptInit_ex(ctx, cipher, NULL, kekri->key, NULL)
945             || !EVP_DecryptUpdate(ctx, ukey, &ukeylen,
946                                   kekri->encryptedKey->data,
947                                   kekri->encryptedKey->length)
948             || !EVP_DecryptFinal_ex(ctx, ukey + ukeylen, &outlen)) {
949         ERR_raise(ERR_LIB_CMS, CMS_R_UNWRAP_ERROR);
950         goto err;
951     }
952     ukeylen += outlen;
953
954     ec->key = ukey;
955     ec->keylen = ukeylen;
956
957     r = 1;
958
959  err:
960     EVP_CIPHER_free(cipher);
961     if (!r)
962         OPENSSL_free(ukey);
963     EVP_CIPHER_CTX_free(ctx);
964
965     return r;
966 }
967
968 int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
969 {
970     switch (ri->type) {
971     case CMS_RECIPINFO_TRANS:
972         return cms_RecipientInfo_ktri_decrypt(cms, ri);
973
974     case CMS_RECIPINFO_KEK:
975         return cms_RecipientInfo_kekri_decrypt(cms, ri);
976
977     case CMS_RECIPINFO_PASS:
978         return ossl_cms_RecipientInfo_pwri_crypt(cms, ri, 0);
979
980     default:
981         ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE);
982         return 0;
983     }
984 }
985
986 int CMS_RecipientInfo_encrypt(const CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
987 {
988     switch (ri->type) {
989     case CMS_RECIPINFO_TRANS:
990         return cms_RecipientInfo_ktri_encrypt(cms, ri);
991
992     case CMS_RECIPINFO_AGREE:
993         return ossl_cms_RecipientInfo_kari_encrypt(cms, ri);
994
995     case CMS_RECIPINFO_KEK:
996         return cms_RecipientInfo_kekri_encrypt(cms, ri);
997
998     case CMS_RECIPINFO_PASS:
999         return ossl_cms_RecipientInfo_pwri_crypt(cms, ri, 1);
1000
1001     default:
1002         ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
1003         return 0;
1004     }
1005 }
1006
1007 /* Check structures and fixup version numbers (if necessary) */
1008
1009 static void cms_env_set_originfo_version(CMS_EnvelopedData *env)
1010 {
1011     CMS_OriginatorInfo *org = env->originatorInfo;
1012     int i;
1013     if (org == NULL)
1014         return;
1015     for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) {
1016         CMS_CertificateChoices *cch;
1017         cch = sk_CMS_CertificateChoices_value(org->certificates, i);
1018         if (cch->type == CMS_CERTCHOICE_OTHER) {
1019             env->version = 4;
1020             return;
1021         } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
1022             if (env->version < 3)
1023                 env->version = 3;
1024         }
1025     }
1026
1027     for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) {
1028         CMS_RevocationInfoChoice *rch;
1029         rch = sk_CMS_RevocationInfoChoice_value(org->crls, i);
1030         if (rch->type == CMS_REVCHOICE_OTHER) {
1031             env->version = 4;
1032             return;
1033         }
1034     }
1035 }
1036
1037 static void cms_env_set_version(CMS_EnvelopedData *env)
1038 {
1039     int i;
1040     CMS_RecipientInfo *ri;
1041
1042     /*
1043      * Can't set version higher than 4 so if 4 or more already nothing to do.
1044      */
1045     if (env->version >= 4)
1046         return;
1047
1048     cms_env_set_originfo_version(env);
1049
1050     if (env->version >= 3)
1051         return;
1052
1053     for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) {
1054         ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i);
1055         if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) {
1056             env->version = 3;
1057             return;
1058         } else if (ri->type != CMS_RECIPINFO_TRANS
1059                    || ri->d.ktri->version != 0) {
1060             env->version = 2;
1061         }
1062     }
1063     if (env->originatorInfo || env->unprotectedAttrs)
1064         env->version = 2;
1065     if (env->version == 2)
1066         return;
1067     env->version = 0;
1068 }
1069
1070 static int cms_env_encrypt_content_key(const CMS_ContentInfo *cms,
1071                                        STACK_OF(CMS_RecipientInfo) *ris)
1072 {
1073     int i;
1074     CMS_RecipientInfo *ri;
1075
1076     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
1077         ri = sk_CMS_RecipientInfo_value(ris, i);
1078         if (CMS_RecipientInfo_encrypt(cms, ri) <= 0)
1079             return -1;
1080     }
1081     return 1;
1082 }
1083
1084 static void cms_env_clear_ec(CMS_EncryptedContentInfo *ec)
1085 {
1086     ec->cipher = NULL;
1087     OPENSSL_clear_free(ec->key, ec->keylen);
1088     ec->key = NULL;
1089     ec->keylen = 0;
1090 }
1091
1092 static BIO *cms_EnvelopedData_Decryption_init_bio(CMS_ContentInfo *cms)
1093 {
1094     CMS_EncryptedContentInfo *ec = cms->d.envelopedData->encryptedContentInfo;
1095     BIO *contentBio = ossl_cms_EncryptedContent_init_bio(ec,
1096                                                          ossl_cms_get0_cmsctx(cms));
1097     EVP_CIPHER_CTX *ctx = NULL;
1098
1099     if (contentBio == NULL)
1100         return NULL;
1101
1102     BIO_get_cipher_ctx(contentBio, &ctx);
1103     if (ctx == NULL) {
1104         BIO_free(contentBio);
1105         return NULL;
1106     }
1107     /*
1108      * If the selected cipher supports unprotected attributes,
1109      * deal with it using special ctrl function
1110      */
1111     if ((EVP_CIPHER_flags(EVP_CIPHER_CTX_get0_cipher(ctx))
1112                 & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0
1113          && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED, 0,
1114                                 cms->d.envelopedData->unprotectedAttrs) <= 0) {
1115         BIO_free(contentBio);
1116         return NULL;
1117     }
1118     return contentBio;
1119 }
1120
1121 static BIO *cms_EnvelopedData_Encryption_init_bio(CMS_ContentInfo *cms)
1122 {
1123     CMS_EncryptedContentInfo *ec;
1124     STACK_OF(CMS_RecipientInfo) *rinfos;
1125     int ok = 0;
1126     BIO *ret;
1127     CMS_EnvelopedData *env = cms->d.envelopedData;
1128
1129     /* Get BIO first to set up key */
1130
1131     ec = env->encryptedContentInfo;
1132     ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms));
1133
1134     /* If error end of processing */
1135     if (!ret)
1136         return ret;
1137
1138     /* Now encrypt content key according to each RecipientInfo type */
1139     rinfos = env->recipientInfos;
1140     if (cms_env_encrypt_content_key(cms, rinfos) < 0) {
1141         ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO);
1142         goto err;
1143     }
1144
1145     /* And finally set the version */
1146     cms_env_set_version(env);
1147
1148     ok = 1;
1149
1150  err:
1151     cms_env_clear_ec(ec);
1152     if (ok)
1153         return ret;
1154     BIO_free(ret);
1155     return NULL;
1156 }
1157
1158 BIO *ossl_cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
1159 {
1160     if (cms->d.envelopedData->encryptedContentInfo->cipher != NULL) {
1161          /* If cipher is set it's encryption */
1162          return cms_EnvelopedData_Encryption_init_bio(cms);
1163     }
1164
1165     /* If cipher is not set it's decryption */
1166     return cms_EnvelopedData_Decryption_init_bio(cms);
1167 }
1168
1169 BIO *ossl_cms_AuthEnvelopedData_init_bio(CMS_ContentInfo *cms)
1170 {
1171     CMS_EncryptedContentInfo *ec;
1172     STACK_OF(CMS_RecipientInfo) *rinfos;
1173     int ok = 0;
1174     BIO *ret;
1175     CMS_AuthEnvelopedData *aenv = cms->d.authEnvelopedData;
1176
1177     /* Get BIO first to set up key */
1178     ec = aenv->authEncryptedContentInfo;
1179     /* Set tag for decryption */
1180     if (ec->cipher == NULL) {
1181         ec->tag = aenv->mac->data;
1182         ec->taglen = aenv->mac->length;
1183     }
1184     ret = ossl_cms_EncryptedContent_init_bio(ec, ossl_cms_get0_cmsctx(cms));
1185
1186     /* If error or no cipher end of processing */
1187     if (ret == NULL || ec->cipher == NULL)
1188         return ret;
1189
1190     /* Now encrypt content key according to each RecipientInfo type */
1191     rinfos = aenv->recipientInfos;
1192     if (cms_env_encrypt_content_key(cms, rinfos) < 0) {
1193         ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO);
1194         goto err;
1195     }
1196
1197     /* And finally set the version */
1198     aenv->version = 0;
1199
1200     ok = 1;
1201
1202  err:
1203     cms_env_clear_ec(ec);
1204     if (ok)
1205         return ret;
1206     BIO_free(ret);
1207     return NULL;
1208 }
1209
1210 int ossl_cms_EnvelopedData_final(CMS_ContentInfo *cms, BIO *chain)
1211 {
1212     CMS_EnvelopedData *env = NULL;
1213     EVP_CIPHER_CTX *ctx = NULL;
1214     BIO *mbio = BIO_find_type(chain, BIO_TYPE_CIPHER);
1215
1216     env = ossl_cms_get0_enveloped(cms);
1217     if (env == NULL)
1218         return 0;
1219
1220     if (mbio == NULL) {
1221         ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND);
1222         return 0;
1223     }
1224
1225     BIO_get_cipher_ctx(mbio, &ctx);
1226
1227     /*
1228      * If the selected cipher supports unprotected attributes,
1229      * deal with it using special ctrl function
1230      */
1231     if ((EVP_CIPHER_flags(EVP_CIPHER_CTX_get0_cipher(ctx))
1232             & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) {
1233         if (env->unprotectedAttrs == NULL)
1234             env->unprotectedAttrs = sk_X509_ATTRIBUTE_new_null();
1235
1236         if (env->unprotectedAttrs == NULL) {
1237             ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
1238             return 0;
1239         }
1240
1241         if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_PROCESS_UNPROTECTED,
1242                                 1, env->unprotectedAttrs) <= 0) {
1243             ERR_raise(ERR_LIB_CMS, CMS_R_CTRL_FAILURE);
1244             return 0;
1245         }
1246     }
1247
1248     cms_env_set_version(cms->d.envelopedData);
1249     return 1;
1250 }
1251
1252 int ossl_cms_AuthEnvelopedData_final(CMS_ContentInfo *cms, BIO *cmsbio)
1253 {
1254     EVP_CIPHER_CTX *ctx;
1255     unsigned char *tag = NULL;
1256     int taglen, ok = 0;
1257
1258     BIO_get_cipher_ctx(cmsbio, &ctx);
1259
1260     /* 
1261      * The tag is set only for encryption. There is nothing to do for
1262      * decryption.
1263      */
1264     if (!EVP_CIPHER_CTX_encrypting(ctx))
1265         return 1;
1266
1267     taglen = EVP_CIPHER_CTX_tag_length(ctx);
1268     if (taglen <= 0
1269             || (tag = OPENSSL_malloc(taglen)) == NULL
1270             || EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen,
1271                                    tag) <= 0) {
1272         ERR_raise(ERR_LIB_CMS, CMS_R_CIPHER_GET_TAG);
1273         goto err;
1274     }
1275
1276     if (!ASN1_OCTET_STRING_set(cms->d.authEnvelopedData->mac, tag, taglen))
1277         goto err;
1278
1279     ok = 1;
1280 err:
1281     OPENSSL_free(tag);
1282     return ok;
1283 }
1284
1285 /*
1286  * Get RecipientInfo type (if any) supported by a key (public or private). To
1287  * retain compatibility with previous behaviour if the ctrl value isn't
1288  * supported we assume key transport.
1289  */
1290 int ossl_cms_pkey_get_ri_type(EVP_PKEY *pk)
1291 {
1292     /* Check types that we know about */
1293     if (EVP_PKEY_is_a(pk, "DH"))
1294         return CMS_RECIPINFO_AGREE;
1295     else if (EVP_PKEY_is_a(pk, "DHX"))
1296         return CMS_RECIPINFO_AGREE;
1297     else if (EVP_PKEY_is_a(pk, "DSA"))
1298         return CMS_RECIPINFO_NONE;
1299     else if (EVP_PKEY_is_a(pk, "EC"))
1300         return CMS_RECIPINFO_AGREE;
1301     else if (EVP_PKEY_is_a(pk, "RSA"))
1302         return CMS_RECIPINFO_TRANS;
1303
1304     /*
1305      * Otherwise this might ben an engine implementation, so see if we can get
1306      * the type from the ameth.
1307      */
1308     if (pk->ameth && pk->ameth->pkey_ctrl) {
1309         int i, r;
1310         i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r);
1311         if (i > 0)
1312             return r;
1313     }
1314     return CMS_RECIPINFO_TRANS;
1315 }
1316
1317 int ossl_cms_pkey_is_ri_type_supported(EVP_PKEY *pk, int ri_type)
1318 {
1319     int supportedRiType;
1320
1321     if (pk->ameth != NULL && pk->ameth->pkey_ctrl != NULL) {
1322         int i, r;
1323
1324         i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_IS_RI_TYPE_SUPPORTED,
1325                                  ri_type, &r);
1326         if (i > 0)
1327             return r;
1328     }
1329
1330     supportedRiType = ossl_cms_pkey_get_ri_type(pk);
1331     if (supportedRiType < 0)
1332         return 0;
1333
1334     return (supportedRiType == ri_type);
1335 }