2 * Copyright 2006-2022 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 <openssl/core_names.h>
14 #include "crypto/asn1.h"
15 #include "crypto/rsa.h"
16 #include "cms_local.h"
18 static RSA_OAEP_PARAMS
*rsa_oaep_decode(const X509_ALGOR
*alg
)
20 RSA_OAEP_PARAMS
*oaep
;
22 oaep
= ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS
),
28 if (oaep
->maskGenFunc
!= NULL
) {
29 oaep
->maskHash
= ossl_x509_algor_mgf1_decode(oaep
->maskGenFunc
);
30 if (oaep
->maskHash
== NULL
) {
31 RSA_OAEP_PARAMS_free(oaep
);
38 static int rsa_cms_decrypt(CMS_RecipientInfo
*ri
)
44 unsigned char *label
= NULL
;
46 const EVP_MD
*mgf1md
= NULL
, *md
= NULL
;
47 RSA_OAEP_PARAMS
*oaep
;
49 pkctx
= CMS_RecipientInfo_get0_pkey_ctx(ri
);
52 if (!CMS_RecipientInfo_ktri_get0_algs(ri
, NULL
, NULL
, &cmsalg
))
54 nid
= OBJ_obj2nid(cmsalg
->algorithm
);
55 if (nid
== NID_rsaEncryption
)
57 if (nid
!= NID_rsaesOaep
) {
58 ERR_raise(ERR_LIB_CMS
, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE
);
61 /* Decode OAEP parameters */
62 oaep
= rsa_oaep_decode(cmsalg
);
65 ERR_raise(ERR_LIB_CMS
, CMS_R_INVALID_OAEP_PARAMETERS
);
69 mgf1md
= ossl_x509_algor_get_md(oaep
->maskHash
);
72 md
= ossl_x509_algor_get_md(oaep
->hashFunc
);
76 if (oaep
->pSourceFunc
!= NULL
) {
77 X509_ALGOR
*plab
= oaep
->pSourceFunc
;
79 if (OBJ_obj2nid(plab
->algorithm
) != NID_pSpecified
) {
80 ERR_raise(ERR_LIB_CMS
, CMS_R_UNSUPPORTED_LABEL_SOURCE
);
83 if (plab
->parameter
->type
!= V_ASN1_OCTET_STRING
) {
84 ERR_raise(ERR_LIB_CMS
, CMS_R_INVALID_LABEL
);
88 label
= plab
->parameter
->value
.octet_string
->data
;
89 /* Stop label being freed when OAEP parameters are freed */
90 plab
->parameter
->value
.octet_string
->data
= NULL
;
91 labellen
= plab
->parameter
->value
.octet_string
->length
;
94 if (EVP_PKEY_CTX_set_rsa_padding(pkctx
, RSA_PKCS1_OAEP_PADDING
) <= 0)
96 if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx
, md
) <= 0)
98 if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx
, mgf1md
) <= 0)
101 && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx
, label
, labellen
) <= 0)
107 RSA_OAEP_PARAMS_free(oaep
);
111 static int rsa_cms_encrypt(CMS_RecipientInfo
*ri
)
113 const EVP_MD
*md
, *mgf1md
;
114 RSA_OAEP_PARAMS
*oaep
= NULL
;
115 ASN1_STRING
*os
= NULL
;
117 EVP_PKEY_CTX
*pkctx
= CMS_RecipientInfo_get0_pkey_ctx(ri
);
118 int pad_mode
= RSA_PKCS1_PADDING
, rv
= 0, labellen
;
119 unsigned char *label
;
121 if (CMS_RecipientInfo_ktri_get0_algs(ri
, NULL
, NULL
, &alg
) <= 0)
124 if (EVP_PKEY_CTX_get_rsa_padding(pkctx
, &pad_mode
) <= 0)
127 if (pad_mode
== RSA_PKCS1_PADDING
)
128 return X509_ALGOR_set0(alg
, OBJ_nid2obj(NID_rsaEncryption
),
132 if (pad_mode
!= RSA_PKCS1_OAEP_PADDING
)
134 if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx
, &md
) <= 0)
136 if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx
, &mgf1md
) <= 0)
138 labellen
= EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx
, &label
);
141 oaep
= RSA_OAEP_PARAMS_new();
144 if (!ossl_x509_algor_new_from_md(&oaep
->hashFunc
, md
))
146 if (!ossl_x509_algor_md_to_mgf1(&oaep
->maskGenFunc
, mgf1md
))
149 ASN1_OCTET_STRING
*los
= ASN1_OCTET_STRING_new();
153 if (!ASN1_OCTET_STRING_set(los
, label
, labellen
)) {
154 ASN1_OCTET_STRING_free(los
);
157 oaep
->pSourceFunc
= ossl_X509_ALGOR_from_nid(NID_pSpecified
,
158 V_ASN1_OCTET_STRING
, los
);
159 if (oaep
->pSourceFunc
== NULL
)
162 /* create string with pss parameter encoding. */
163 if (!ASN1_item_pack(oaep
, ASN1_ITEM_rptr(RSA_OAEP_PARAMS
), &os
))
165 if (!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 ossl_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 unsigned char aid
[128];
195 const unsigned char *pp
= aid
;
197 OSSL_PARAM params
[2];
199 CMS_SignerInfo_get0_algs(si
, NULL
, NULL
, NULL
, &alg
);
201 if (EVP_PKEY_CTX_get_rsa_padding(pkctx
, &pad_mode
) <= 0)
204 if (pad_mode
== RSA_PKCS1_PADDING
)
205 return X509_ALGOR_set0(alg
, OBJ_nid2obj(NID_rsaEncryption
),
208 /* We don't support it */
209 if (pad_mode
!= RSA_PKCS1_PSS_PADDING
)
212 params
[0] = OSSL_PARAM_construct_octet_string(
213 OSSL_SIGNATURE_PARAM_ALGORITHM_ID
, aid
, sizeof(aid
));
214 params
[1] = OSSL_PARAM_construct_end();
216 if (EVP_PKEY_CTX_get_params(pkctx
, params
) <= 0)
218 if ((aid_len
= params
[0].return_size
) == 0)
220 if (d2i_X509_ALGOR(&alg
, &pp
, aid_len
) == NULL
)
225 static int rsa_cms_verify(CMS_SignerInfo
*si
)
229 EVP_PKEY_CTX
*pkctx
= CMS_SignerInfo_get0_pkey_ctx(si
);
230 EVP_PKEY
*pkey
= EVP_PKEY_CTX_get0_pkey(pkctx
);
232 CMS_SignerInfo_get0_algs(si
, NULL
, NULL
, NULL
, &alg
);
233 nid
= OBJ_obj2nid(alg
->algorithm
);
234 if (nid
== EVP_PKEY_RSA_PSS
)
235 return ossl_rsa_pss_to_ctx(NULL
, pkctx
, alg
, NULL
) > 0;
236 /* Only PSS allowed for PSS keys */
237 if (EVP_PKEY_is_a(pkey
, "RSA-PSS")) {
238 ERR_raise(ERR_LIB_RSA
, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
);
241 if (nid
== NID_rsaEncryption
)
243 /* Workaround for some implementation that use a signature OID */
244 if (OBJ_find_sigid_algs(nid
, NULL
, &nid2
)) {
245 if (nid2
== NID_rsaEncryption
)
251 int ossl_cms_rsa_sign(CMS_SignerInfo
*si
, int verify
)
253 assert(verify
== 0 || verify
== 1);
256 return rsa_cms_verify(si
);
259 return rsa_cms_sign(si
);
261 ERR_raise(ERR_LIB_CMS
, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);