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