2 * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/cms.h>
12 #include <openssl/err.h>
13 #include "crypto/asn1.h"
14 #include "crypto/rsa.h"
15 #include "cms_local.h"
17 static RSA_OAEP_PARAMS
*rsa_oaep_decode(const X509_ALGOR
*alg
)
19 RSA_OAEP_PARAMS
*oaep
;
21 oaep
= ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS
),
27 if (oaep
->maskGenFunc
!= NULL
) {
28 oaep
->maskHash
= x509_algor_mgf1_decode(oaep
->maskGenFunc
);
29 if (oaep
->maskHash
== NULL
) {
30 RSA_OAEP_PARAMS_free(oaep
);
37 static int rsa_cms_decrypt(CMS_RecipientInfo
*ri
)
43 unsigned char *label
= NULL
;
45 const EVP_MD
*mgf1md
= NULL
, *md
= NULL
;
46 RSA_OAEP_PARAMS
*oaep
;
48 pkctx
= CMS_RecipientInfo_get0_pkey_ctx(ri
);
51 if (!CMS_RecipientInfo_ktri_get0_algs(ri
, NULL
, NULL
, &cmsalg
))
53 nid
= OBJ_obj2nid(cmsalg
->algorithm
);
54 if (nid
== NID_rsaEncryption
)
56 if (nid
!= NID_rsaesOaep
) {
57 ERR_raise(ERR_LIB_CMS
, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE
);
60 /* Decode OAEP parameters */
61 oaep
= rsa_oaep_decode(cmsalg
);
64 ERR_raise(ERR_LIB_CMS
, CMS_R_INVALID_OAEP_PARAMETERS
);
68 mgf1md
= x509_algor_get_md(oaep
->maskHash
);
71 md
= x509_algor_get_md(oaep
->hashFunc
);
75 if (oaep
->pSourceFunc
!= NULL
) {
76 X509_ALGOR
*plab
= oaep
->pSourceFunc
;
78 if (OBJ_obj2nid(plab
->algorithm
) != NID_pSpecified
) {
79 ERR_raise(ERR_LIB_CMS
, CMS_R_UNSUPPORTED_LABEL_SOURCE
);
82 if (plab
->parameter
->type
!= V_ASN1_OCTET_STRING
) {
83 ERR_raise(ERR_LIB_CMS
, CMS_R_INVALID_LABEL
);
87 label
= plab
->parameter
->value
.octet_string
->data
;
88 /* Stop label being freed when OAEP parameters are freed */
89 plab
->parameter
->value
.octet_string
->data
= NULL
;
90 labellen
= plab
->parameter
->value
.octet_string
->length
;
93 if (EVP_PKEY_CTX_set_rsa_padding(pkctx
, RSA_PKCS1_OAEP_PADDING
) <= 0)
95 if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx
, md
) <= 0)
97 if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx
, mgf1md
) <= 0)
100 && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx
, label
, labellen
) <= 0)
106 RSA_OAEP_PARAMS_free(oaep
);
110 static int rsa_cms_encrypt(CMS_RecipientInfo
*ri
)
112 const EVP_MD
*md
, *mgf1md
;
113 RSA_OAEP_PARAMS
*oaep
= NULL
;
114 ASN1_STRING
*os
= NULL
;
116 EVP_PKEY_CTX
*pkctx
= CMS_RecipientInfo_get0_pkey_ctx(ri
);
117 int pad_mode
= RSA_PKCS1_PADDING
, rv
= 0, labellen
;
118 unsigned char *label
;
120 if (CMS_RecipientInfo_ktri_get0_algs(ri
, NULL
, NULL
, &alg
) <= 0)
123 if (EVP_PKEY_CTX_get_rsa_padding(pkctx
, &pad_mode
) <= 0)
126 if (pad_mode
== RSA_PKCS1_PADDING
) {
127 X509_ALGOR_set0(alg
, OBJ_nid2obj(NID_rsaEncryption
), V_ASN1_NULL
, 0);
131 if (pad_mode
!= RSA_PKCS1_OAEP_PADDING
)
133 if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx
, &md
) <= 0)
135 if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx
, &mgf1md
) <= 0)
137 labellen
= EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx
, &label
);
140 oaep
= RSA_OAEP_PARAMS_new();
143 if (!x509_algor_new_from_md(&oaep
->hashFunc
, md
))
145 if (!x509_algor_md_to_mgf1(&oaep
->maskGenFunc
, mgf1md
))
148 ASN1_OCTET_STRING
*los
;
150 oaep
->pSourceFunc
= X509_ALGOR_new();
151 if (oaep
->pSourceFunc
== NULL
)
153 los
= ASN1_OCTET_STRING_new();
156 if (!ASN1_OCTET_STRING_set(los
, label
, labellen
)) {
157 ASN1_OCTET_STRING_free(los
);
160 X509_ALGOR_set0(oaep
->pSourceFunc
, OBJ_nid2obj(NID_pSpecified
),
161 V_ASN1_OCTET_STRING
, los
);
163 /* create string with pss parameter encoding. */
164 if (!ASN1_item_pack(oaep
, ASN1_ITEM_rptr(RSA_OAEP_PARAMS
), &os
))
166 X509_ALGOR_set0(alg
, OBJ_nid2obj(NID_rsaesOaep
), V_ASN1_SEQUENCE
, os
);
170 RSA_OAEP_PARAMS_free(oaep
);
171 ASN1_STRING_free(os
);
175 int cms_rsa_envelope(CMS_RecipientInfo
*ri
, int decrypt
)
177 assert(decrypt
== 0 || decrypt
== 1);
180 return rsa_cms_decrypt(ri
);
183 return rsa_cms_encrypt(ri
);
185 ERR_raise(ERR_LIB_CMS
, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
189 static int rsa_cms_sign(CMS_SignerInfo
*si
)
191 int pad_mode
= RSA_PKCS1_PADDING
;
193 EVP_PKEY_CTX
*pkctx
= CMS_SignerInfo_get0_pkey_ctx(si
);
194 ASN1_STRING
*os
= NULL
;
196 CMS_SignerInfo_get0_algs(si
, NULL
, NULL
, NULL
, &alg
);
198 if (EVP_PKEY_CTX_get_rsa_padding(pkctx
, &pad_mode
) <= 0)
201 if (pad_mode
== RSA_PKCS1_PADDING
) {
202 X509_ALGOR_set0(alg
, OBJ_nid2obj(NID_rsaEncryption
), V_ASN1_NULL
, 0);
205 /* We don't support it */
206 if (pad_mode
!= RSA_PKCS1_PSS_PADDING
)
208 os
= ossl_rsa_ctx_to_pss_string(pkctx
);
211 X509_ALGOR_set0(alg
, OBJ_nid2obj(EVP_PKEY_RSA_PSS
), V_ASN1_SEQUENCE
, os
);
215 static int rsa_cms_verify(CMS_SignerInfo
*si
)
219 EVP_PKEY_CTX
*pkctx
= CMS_SignerInfo_get0_pkey_ctx(si
);
220 EVP_PKEY
*pkey
= EVP_PKEY_CTX_get0_pkey(pkctx
);
222 CMS_SignerInfo_get0_algs(si
, NULL
, NULL
, NULL
, &alg
);
223 nid
= OBJ_obj2nid(alg
->algorithm
);
224 if (nid
== EVP_PKEY_RSA_PSS
)
225 return ossl_rsa_pss_to_ctx(NULL
, pkctx
, alg
, NULL
);
226 /* Only PSS allowed for PSS keys */
227 if (EVP_PKEY_is_a(pkey
, "RSA-PSS")) {
228 ERR_raise(ERR_LIB_RSA
, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
);
231 if (nid
== NID_rsaEncryption
)
233 /* Workaround for some implementation that use a signature OID */
234 if (OBJ_find_sigid_algs(nid
, NULL
, &nid2
)) {
235 if (nid2
== NID_rsaEncryption
)
241 int cms_rsa_sign(CMS_SignerInfo
*si
, int verify
)
243 assert(verify
== 0 || verify
== 1);
246 return rsa_cms_verify(si
);
249 return rsa_cms_sign(si
);
251 ERR_raise(ERR_LIB_CMS
, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);