/* * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html */ #include #include #include "crypto/rsa.h" /* * The intention with the "backend" source file is to offer backend support * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider * implementations alike. */ DEFINE_STACK_OF(BIGNUM) static int collect_numbers(STACK_OF(BIGNUM) *numbers, const OSSL_PARAM params[], const char *names[]) { const OSSL_PARAM *p = NULL; int i; if (numbers == NULL) return 0; for (i = 0; names[i] != NULL; i++){ p = OSSL_PARAM_locate_const(params, names[i]); if (p != NULL) { BIGNUM *tmp = NULL; if (!OSSL_PARAM_get_BN(p, &tmp) || sk_BIGNUM_push(numbers, tmp) == 0) return 0; } } return 1; } int rsa_fromdata(RSA *rsa, const OSSL_PARAM params[]) { const OSSL_PARAM *param_n, *param_e, *param_d; BIGNUM *n = NULL, *e = NULL, *d = NULL; STACK_OF(BIGNUM) *factors = NULL, *exps = NULL, *coeffs = NULL; int is_private = 0; if (rsa == NULL) return 0; param_n = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N); param_e = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E); param_d = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D); if ((param_n != NULL && !OSSL_PARAM_get_BN(param_n, &n)) || (param_e != NULL && !OSSL_PARAM_get_BN(param_e, &e)) || (param_d != NULL && !OSSL_PARAM_get_BN(param_d, &d))) goto err; is_private = (d != NULL); if (!RSA_set0_key(rsa, n, e, d)) goto err; n = e = d = NULL; if (is_private) { if (!collect_numbers(factors = sk_BIGNUM_new_null(), params, rsa_mp_factor_names) || !collect_numbers(exps = sk_BIGNUM_new_null(), params, rsa_mp_exp_names) || !collect_numbers(coeffs = sk_BIGNUM_new_null(), params, rsa_mp_coeff_names)) goto err; /* It's ok if this private key just has n, e and d */ if (sk_BIGNUM_num(factors) != 0 && !rsa_set0_all_params(rsa, factors, exps, coeffs)) goto err; } sk_BIGNUM_free(factors); sk_BIGNUM_free(exps); sk_BIGNUM_free(coeffs); return 1; err: BN_free(n); BN_free(e); BN_free(d); sk_BIGNUM_pop_free(factors, BN_free); sk_BIGNUM_pop_free(exps, BN_free); sk_BIGNUM_pop_free(coeffs, BN_free); return 0; }