dsa_backend.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright 2020-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. * DSA low level APIs are deprecated for public use, but still ok for
  11. * internal use.
  12. */
  13. #include "internal/deprecated.h"
  14. #include <openssl/core_names.h>
  15. #include <openssl/err.h>
  16. #ifndef FIPS_MODULE
  17. # include <openssl/x509.h>
  18. #endif
  19. #include "crypto/dsa.h"
  20. #include "dsa_local.h"
  21. /*
  22. * The intention with the "backend" source file is to offer backend support
  23. * for legacy backends (EVP_PKEY_ASN1_METHOD and EVP_PKEY_METHOD) and provider
  24. * implementations alike.
  25. */
  26. int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[],
  27. int include_private)
  28. {
  29. const OSSL_PARAM *param_priv_key = NULL, *param_pub_key;
  30. BIGNUM *priv_key = NULL, *pub_key = NULL;
  31. if (dsa == NULL)
  32. return 0;
  33. if (include_private) {
  34. param_priv_key =
  35. OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
  36. }
  37. param_pub_key =
  38. OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
  39. /* It's ok if neither half is present */
  40. if (param_priv_key == NULL && param_pub_key == NULL)
  41. return 1;
  42. if (param_pub_key != NULL && !OSSL_PARAM_get_BN(param_pub_key, &pub_key))
  43. goto err;
  44. if (param_priv_key != NULL && !OSSL_PARAM_get_BN(param_priv_key, &priv_key))
  45. goto err;
  46. if (!DSA_set0_key(dsa, pub_key, priv_key))
  47. goto err;
  48. return 1;
  49. err:
  50. BN_clear_free(priv_key);
  51. BN_free(pub_key);
  52. return 0;
  53. }
  54. int ossl_dsa_is_foreign(const DSA *dsa)
  55. {
  56. #ifndef FIPS_MODULE
  57. if (dsa->engine != NULL || DSA_get_method((DSA *)dsa) != DSA_OpenSSL())
  58. return 1;
  59. #endif
  60. return 0;
  61. }
  62. static ossl_inline int dsa_bn_dup_check(BIGNUM **out, const BIGNUM *f)
  63. {
  64. if (f != NULL && (*out = BN_dup(f)) == NULL)
  65. return 0;
  66. return 1;
  67. }
  68. DSA *ossl_dsa_dup(const DSA *dsa, int selection)
  69. {
  70. DSA *dupkey = NULL;
  71. /* Do not try to duplicate foreign DSA keys */
  72. if (ossl_dsa_is_foreign(dsa))
  73. return NULL;
  74. if ((dupkey = ossl_dsa_new(dsa->libctx)) == NULL)
  75. return NULL;
  76. if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0
  77. && !ossl_ffc_params_copy(&dupkey->params, &dsa->params))
  78. goto err;
  79. dupkey->flags = dsa->flags;
  80. if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0
  81. && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0
  82. || !dsa_bn_dup_check(&dupkey->pub_key, dsa->pub_key)))
  83. goto err;
  84. if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
  85. && ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0
  86. || !dsa_bn_dup_check(&dupkey->priv_key, dsa->priv_key)))
  87. goto err;
  88. #ifndef FIPS_MODULE
  89. if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_DSA,
  90. &dupkey->ex_data, &dsa->ex_data))
  91. goto err;
  92. #endif
  93. return dupkey;
  94. err:
  95. DSA_free(dupkey);
  96. return NULL;
  97. }
  98. #ifndef FIPS_MODULE
  99. DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
  100. OSSL_LIB_CTX *libctx, const char *propq)
  101. {
  102. const unsigned char *p, *pm;
  103. int pklen, pmlen;
  104. int ptype;
  105. const void *pval;
  106. const ASN1_STRING *pstr;
  107. const X509_ALGOR *palg;
  108. ASN1_INTEGER *privkey = NULL;
  109. const BIGNUM *dsa_p, *dsa_g;
  110. BIGNUM *dsa_pubkey = NULL, *dsa_privkey = NULL;
  111. BN_CTX *ctx = NULL;
  112. DSA *dsa = NULL;
  113. if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf))
  114. return 0;
  115. X509_ALGOR_get0(NULL, &ptype, &pval, palg);
  116. if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL)
  117. goto decerr;
  118. if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE)
  119. goto decerr;
  120. pstr = pval;
  121. pm = pstr->data;
  122. pmlen = pstr->length;
  123. if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL)
  124. goto decerr;
  125. /* We have parameters now set private key */
  126. if ((dsa_privkey = BN_secure_new()) == NULL
  127. || !ASN1_INTEGER_to_BN(privkey, dsa_privkey)) {
  128. ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR);
  129. goto dsaerr;
  130. }
  131. /* Calculate public key */
  132. if ((dsa_pubkey = BN_new()) == NULL) {
  133. ERR_raise(ERR_LIB_DSA, ERR_R_BN_LIB);
  134. goto dsaerr;
  135. }
  136. if ((ctx = BN_CTX_new()) == NULL) {
  137. ERR_raise(ERR_LIB_DSA, ERR_R_BN_LIB);
  138. goto dsaerr;
  139. }
  140. dsa_p = DSA_get0_p(dsa);
  141. dsa_g = DSA_get0_g(dsa);
  142. BN_set_flags(dsa_privkey, BN_FLG_CONSTTIME);
  143. if (!BN_mod_exp(dsa_pubkey, dsa_g, dsa_privkey, dsa_p, ctx)) {
  144. ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR);
  145. goto dsaerr;
  146. }
  147. if (!DSA_set0_key(dsa, dsa_pubkey, dsa_privkey)) {
  148. ERR_raise(ERR_LIB_DSA, ERR_R_INTERNAL_ERROR);
  149. goto dsaerr;
  150. }
  151. goto done;
  152. decerr:
  153. ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR);
  154. dsaerr:
  155. BN_free(dsa_privkey);
  156. BN_free(dsa_pubkey);
  157. DSA_free(dsa);
  158. dsa = NULL;
  159. done:
  160. BN_CTX_free(ctx);
  161. ASN1_STRING_clear_free(privkey);
  162. return dsa;
  163. }
  164. #endif