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 OPENSSL_free(label); 104 goto err; 105 } 106 /* Carry on */ 107 rv = 1; 108 109 err: 110 RSA_OAEP_PARAMS_free(oaep); 111 return rv; 112 } 113 114 static int rsa_cms_encrypt(CMS_RecipientInfo *ri) 115 { 116 const EVP_MD *md, *mgf1md; 117 RSA_OAEP_PARAMS *oaep = NULL; 118 ASN1_STRING *os = NULL; 119 ASN1_OCTET_STRING *los = NULL; 120 X509_ALGOR *alg; 121 EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); 122 int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; 123 unsigned char *label; 124 125 if (CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg) <= 0) 126 return 0; 127 if (pkctx != NULL) { 128 if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) 129 return 0; 130 } 131 if (pad_mode == RSA_PKCS1_PADDING) 132 return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), 133 V_ASN1_NULL, NULL); 134 135 /* Not supported */ 136 if (pad_mode != RSA_PKCS1_OAEP_PADDING) 137 return 0; 138 if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) 139 goto err; 140 if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) 141 goto err; 142 labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); 143 if (labellen < 0) 144 goto err; 145 oaep = RSA_OAEP_PARAMS_new(); 146 if (oaep == NULL) 147 goto err; 148 if (!ossl_x509_algor_new_from_md(&oaep->hashFunc, md)) 149 goto err; 150 if (!ossl_x509_algor_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) 151 goto err; 152 if (labellen > 0) { 153 oaep->pSourceFunc = X509_ALGOR_new(); 154 if (oaep->pSourceFunc == NULL) 155 goto err; 156 los = ASN1_OCTET_STRING_new(); 157 if (los == NULL) 158 goto err; 159 if (!ASN1_OCTET_STRING_set(los, label, labellen)) 160 goto err; 161 162 if (!X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), 163 V_ASN1_OCTET_STRING, los)) 164 goto err; 165 166 los = NULL; 167 } 168 /* create string with oaep parameter encoding. */ 169 if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) 170 goto err; 171 if (!X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os)) 172 goto err; 173 os = NULL; 174 rv = 1; 175 err: 176 RSA_OAEP_PARAMS_free(oaep); 177 ASN1_STRING_free(os); 178 ASN1_OCTET_STRING_free(los); 179 return rv; 180 } 181 182 int ossl_cms_rsa_envelope(CMS_RecipientInfo *ri, int decrypt) 183 { 184 assert(decrypt == 0 || decrypt == 1); 185 186 if (decrypt == 1) 187 return rsa_cms_decrypt(ri); 188 189 if (decrypt == 0) 190 return rsa_cms_encrypt(ri); 191 192 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 193 return 0; 194 } 195 196 static int rsa_cms_sign(CMS_SignerInfo *si) 197 { 198 int pad_mode = RSA_PKCS1_PADDING; 199 X509_ALGOR *alg; 200 EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); 201 unsigned char aid[128]; 202 const unsigned char *pp = aid; 203 size_t aid_len = 0; 204 OSSL_PARAM params[2]; 205 206 CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); 207 if (pkctx != NULL) { 208 if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) 209 return 0; 210 } 211 if (pad_mode == RSA_PKCS1_PADDING) { 212 X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); 213 return 1; 214 } 215 /* We don't support it */ 216 if (pad_mode != RSA_PKCS1_PSS_PADDING) 217 return 0; 218 219 if (evp_pkey_ctx_is_legacy(pkctx)) { 220 /* No provider -> we cannot query it for algorithm ID. */ 221 ASN1_STRING *os = NULL; 222 223 os = ossl_rsa_ctx_to_pss_string(pkctx); 224 if (os == NULL) 225 return 0; 226 return X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_PKEY_RSA_PSS), V_ASN1_SEQUENCE, os); 227 } 228 229 params[0] = OSSL_PARAM_construct_octet_string( 230 OSSL_SIGNATURE_PARAM_ALGORITHM_ID, aid, sizeof(aid)); 231 params[1] = OSSL_PARAM_construct_end(); 232 233 if (EVP_PKEY_CTX_get_params(pkctx, params) <= 0) 234 return 0; 235 if ((aid_len = params[0].return_size) == 0) 236 return 0; 237 if (d2i_X509_ALGOR(&alg, &pp, aid_len) == NULL) 238 return 0; 239 return 1; 240 } 241 242 static int rsa_cms_verify(CMS_SignerInfo *si) 243 { 244 int nid, nid2; 245 X509_ALGOR *alg; 246 EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); 247 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pkctx); 248 249 CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); 250 nid = OBJ_obj2nid(alg->algorithm); 251 if (nid == EVP_PKEY_RSA_PSS) 252 return ossl_rsa_pss_to_ctx(NULL, pkctx, alg, NULL) > 0; 253 /* Only PSS allowed for PSS keys */ 254 if (EVP_PKEY_is_a(pkey, "RSA-PSS")) { 255 ERR_raise(ERR_LIB_RSA, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); 256 return 0; 257 } 258 if (nid == NID_rsaEncryption) 259 return 1; 260 /* Workaround for some implementation that use a signature OID */ 261 if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { 262 if (nid2 == NID_rsaEncryption) 263 return 1; 264 } 265 return 0; 266 } 267 268 int ossl_cms_rsa_sign(CMS_SignerInfo *si, int verify) 269 { 270 assert(verify == 0 || verify == 1); 271 272 if (verify == 1) 273 return rsa_cms_verify(si); 274 275 if (verify == 0) 276 return rsa_cms_sign(si); 277 278 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 279 return 0; 280 } 281