1 /* 2 * Copyright 2006-2023 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 <assert.h> 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 "crypto/evp.h" 17 #include "cms_local.h" 18 19 static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg) 20 { 21 RSA_OAEP_PARAMS *oaep; 22 23 oaep = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_OAEP_PARAMS), 24 alg->parameter); 25 26 if (oaep == NULL) 27 return NULL; 28 29 if (oaep->maskGenFunc != NULL) { 30 oaep->maskHash = ossl_x509_algor_mgf1_decode(oaep->maskGenFunc); 31 if (oaep->maskHash == NULL) { 32 RSA_OAEP_PARAMS_free(oaep); 33 return NULL; 34 } 35 } 36 return oaep; 37 } 38 39 static int rsa_cms_decrypt(CMS_RecipientInfo *ri) 40 { 41 EVP_PKEY_CTX *pkctx; 42 X509_ALGOR *cmsalg; 43 int nid; 44 int rv = -1; 45 unsigned char *label = NULL; 46 int labellen = 0; 47 const EVP_MD *mgf1md = NULL, *md = NULL; 48 RSA_OAEP_PARAMS *oaep; 49 50 pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); 51 if (pkctx == NULL) 52 return 0; 53 if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) 54 return -1; 55 nid = OBJ_obj2nid(cmsalg->algorithm); 56 if (nid == NID_rsaEncryption) 57 return 1; 58 if (nid != NID_rsaesOaep) { 59 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE); 60 return -1; 61 } 62 /* Decode OAEP parameters */ 63 oaep = rsa_oaep_decode(cmsalg); 64 65 if (oaep == NULL) { 66 ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_OAEP_PARAMETERS); 67 goto err; 68 } 69 70 mgf1md = ossl_x509_algor_get_md(oaep->maskHash); 71 if (mgf1md == NULL) 72 goto err; 73 md = ossl_x509_algor_get_md(oaep->hashFunc); 74 if (md == NULL) 75 goto err; 76 77 if (oaep->pSourceFunc != NULL) { 78 X509_ALGOR *plab = oaep->pSourceFunc; 79 80 if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { 81 ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_LABEL_SOURCE); 82 goto err; 83 } 84 if (plab->parameter->type != V_ASN1_OCTET_STRING) { 85 ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_LABEL); 86 goto err; 87 } 88 89 label = plab->parameter->value.octet_string->data; 90 /* Stop label being freed when OAEP parameters are freed */ 91 plab->parameter->value.octet_string->data = NULL; 92 labellen = plab->parameter->value.octet_string->length; 93 } 94 95 if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) 96 goto err; 97 if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) 98 goto err; 99 if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) 100 goto err; 101 if (label != NULL 102 && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) 103 goto err; 104 /* Carry on */ 105 rv = 1; 106 107 err: 108 RSA_OAEP_PARAMS_free(oaep); 109 return rv; 110 } 111 112 static int rsa_cms_encrypt(CMS_RecipientInfo *ri) 113 { 114 const EVP_MD *md, *mgf1md; 115 RSA_OAEP_PARAMS *oaep = NULL; 116 ASN1_STRING *os = NULL; 117 X509_ALGOR *alg; 118 EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); 119 int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; 120 unsigned char *label; 121 122 if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) 123 return 0; 124 if (pkctx != NULL) { 125 if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) 126 return 0; 127 } 128 if (pad_mode == RSA_PKCS1_PADDING) { 129 X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); 130 return 1; 131 } 132 /* Not supported */ 133 if (pad_mode != RSA_PKCS1_OAEP_PADDING) 134 return 0; 135 if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) 136 goto err; 137 if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) 138 goto err; 139 labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); 140 if (labellen < 0) 141 goto err; 142 oaep = RSA_OAEP_PARAMS_new(); 143 if (oaep == NULL) 144 goto err; 145 if (!ossl_x509_algor_new_from_md(&oaep->hashFunc, md)) 146 goto err; 147 if (!ossl_x509_algor_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) 148 goto err; 149 if (labellen > 0) { 150 ASN1_OCTET_STRING *los; 151 152 oaep->pSourceFunc = X509_ALGOR_new(); 153 if (oaep->pSourceFunc == NULL) 154 goto err; 155 los = ASN1_OCTET_STRING_new(); 156 if (los == NULL) 157 goto err; 158 if (!ASN1_OCTET_STRING_set(los, label, labellen)) { 159 ASN1_OCTET_STRING_free(los); 160 goto err; 161 } 162 X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), 163 V_ASN1_OCTET_STRING, los); 164 } 165 /* create string with pss parameter encoding. */ 166 if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) 167 goto err; 168 X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); 169 os = NULL; 170 rv = 1; 171 err: 172 RSA_OAEP_PARAMS_free(oaep); 173 ASN1_STRING_free(os); 174 return rv; 175 } 176 177 int ossl_cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt) 178 { 179 assert(decrypt == 0 || decrypt == 1); 180 181 if (decrypt == 1) 182 return rsa_cms_decrypt(ri); 183 184 if (decrypt == 0) 185 return rsa_cms_encrypt(ri); 186 187 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 188 return 0; 189 } 190 191 static int rsa_cms_sign(CMS_SignerInfo *si) 192 { 193 int pad_mode = RSA_PKCS1_PADDING; 194 X509_ALGOR *alg; 195 EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); 196 unsigned char aid[128]; 197 const unsigned char *pp = aid; 198 size_t aid_len = 0; 199 OSSL_PARAM params[2]; 200 201 CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); 202 if (pkctx != NULL) { 203 if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) 204 return 0; 205 } 206 if (pad_mode == RSA_PKCS1_PADDING) { 207 X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); 208 return 1; 209 } 210 /* We don't support it */ 211 if (pad_mode != RSA_PKCS1_PSS_PADDING) 212 return 0; 213 214 if (evp_pkey_ctx_is_legacy(pkctx)) { 215 /* No provider -> we cannot query it for algorithm ID. */ 216 ASN1_STRING *os = NULL; 217 218 os = ossl_rsa_ctx_to_pss_string(pkctx); 219 if (os == NULL) 220 return 0; 221 return X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); 222 } 223 224 params[0] = OSSL_PARAM_construct_octet_string( 225 OSSL_SIGNATURE_PARAM_ALGORITHM_ID, aid, sizeof(aid)); 226 params[1] = OSSL_PARAM_construct_end(); 227 228 if (EVP_PKEY_CTX_get_params(pkctx, params) <= 0) 229 return 0; 230 if ((aid_len = params[0].return_size) == 0) 231 return 0; 232 if (d2i_X509_ALGOR(&alg, &pp, aid_len) == NULL) 233 return 0; 234 return 1; 235 } 236 237 static int rsa_cms_verify(CMS_SignerInfo *si) 238 { 239 int nid, nid2; 240 X509_ALGOR *alg; 241 EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); 242 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pkctx); 243 244 CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); 245 nid = OBJ_obj2nid(alg->algorithm); 246 if (nid == EVP_PKEY_RSA_PSS) 247 return ossl_rsa_pss_to_ctx(NULL, pkctx, alg, NULL) > 0; 248 /* Only PSS allowed for PSS keys */ 249 if (EVP_PKEY_is_a(pkey, "RSA-PSS")) { 250 ERR_raise(ERR_LIB_RSA, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); 251 return 0; 252 } 253 if (nid == NID_rsaEncryption) 254 return 1; 255 /* Workaround for some implementation that use a signature OID */ 256 if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { 257 if (nid2 == NID_rsaEncryption) 258 return 1; 259 } 260 return 0; 261 } 262 263 int ossl_cms_rsa_sign(CMS_SignerInfo *si, int verify) 264 { 265 assert(verify == 0 || verify == 1); 266 267 if (verify == 1) 268 return rsa_cms_verify(si); 269 270 if (verify == 0) 271 return rsa_cms_sign(si); 272 273 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 274 return 0; 275 } 276