dh_ameth.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  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. * DH low level APIs are deprecated for public use, but still ok for
  11. * internal use.
  12. */
  13. #include "internal/deprecated.h"
  14. #include <stdio.h>
  15. #include <openssl/x509.h>
  16. #include <openssl/asn1.h>
  17. #include <openssl/bn.h>
  18. #include <openssl/core_names.h>
  19. #include <openssl/param_build.h>
  20. #include "internal/ffc.h"
  21. #include "internal/cryptlib.h"
  22. #include "crypto/asn1.h"
  23. #include "crypto/dh.h"
  24. #include "crypto/evp.h"
  25. #include "dh_local.h"
  26. /*
  27. * i2d/d2i like DH parameter functions which use the appropriate routine for
  28. * PKCS#3 DH or X9.42 DH.
  29. */
  30. static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp,
  31. long length)
  32. {
  33. DH *dh = NULL;
  34. int is_dhx = (pkey->ameth == &ossl_dhx_asn1_meth);
  35. if (is_dhx)
  36. dh = d2i_DHxparams(NULL, pp, length);
  37. else
  38. dh = d2i_DHparams(NULL, pp, length);
  39. return dh;
  40. }
  41. static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp)
  42. {
  43. if (pkey->ameth == &ossl_dhx_asn1_meth)
  44. return i2d_DHxparams(a, pp);
  45. return i2d_DHparams(a, pp);
  46. }
  47. static void int_dh_free(EVP_PKEY *pkey)
  48. {
  49. DH_free(pkey->pkey.dh);
  50. }
  51. static int dh_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
  52. {
  53. const unsigned char *p, *pm;
  54. int pklen, pmlen;
  55. int ptype;
  56. const void *pval;
  57. const ASN1_STRING *pstr;
  58. X509_ALGOR *palg;
  59. ASN1_INTEGER *public_key = NULL;
  60. DH *dh = NULL;
  61. if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
  62. return 0;
  63. X509_ALGOR_get0(NULL, &ptype, &pval, palg);
  64. if (ptype != V_ASN1_SEQUENCE) {
  65. ERR_raise(ERR_LIB_DH, DH_R_PARAMETER_ENCODING_ERROR);
  66. goto err;
  67. }
  68. pstr = pval;
  69. pm = pstr->data;
  70. pmlen = pstr->length;
  71. if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL) {
  72. ERR_raise(ERR_LIB_DH, DH_R_DECODE_ERROR);
  73. goto err;
  74. }
  75. if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) {
  76. ERR_raise(ERR_LIB_DH, DH_R_DECODE_ERROR);
  77. goto err;
  78. }
  79. /* We have parameters now set public key */
  80. if ((dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) {
  81. ERR_raise(ERR_LIB_DH, DH_R_BN_DECODE_ERROR);
  82. goto err;
  83. }
  84. ASN1_INTEGER_free(public_key);
  85. EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
  86. return 1;
  87. err:
  88. ASN1_INTEGER_free(public_key);
  89. DH_free(dh);
  90. return 0;
  91. }
  92. static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
  93. {
  94. DH *dh;
  95. int ptype;
  96. unsigned char *penc = NULL;
  97. int penclen;
  98. ASN1_STRING *str;
  99. ASN1_INTEGER *pub_key = NULL;
  100. dh = pkey->pkey.dh;
  101. str = ASN1_STRING_new();
  102. if (str == NULL) {
  103. ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
  104. goto err;
  105. }
  106. str->length = i2d_dhp(pkey, dh, &str->data);
  107. if (str->length <= 0) {
  108. ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
  109. goto err;
  110. }
  111. ptype = V_ASN1_SEQUENCE;
  112. pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL);
  113. if (pub_key == NULL)
  114. goto err;
  115. penclen = i2d_ASN1_INTEGER(pub_key, &penc);
  116. ASN1_INTEGER_free(pub_key);
  117. if (penclen <= 0) {
  118. ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
  119. goto err;
  120. }
  121. if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
  122. ptype, str, penc, penclen))
  123. return 1;
  124. err:
  125. OPENSSL_free(penc);
  126. ASN1_STRING_free(str);
  127. return 0;
  128. }
  129. /*
  130. * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in that
  131. * the AlgorithmIdentifier contains the parameters, the private key is
  132. * explicitly included and the pubkey must be recalculated.
  133. */
  134. static int dh_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
  135. {
  136. int ret = 0;
  137. DH *dh = ossl_dh_key_from_pkcs8(p8, NULL, NULL);
  138. if (dh != NULL) {
  139. ret = 1;
  140. EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
  141. }
  142. return ret;
  143. }
  144. static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
  145. {
  146. ASN1_STRING *params = NULL;
  147. ASN1_INTEGER *prkey = NULL;
  148. unsigned char *dp = NULL;
  149. int dplen;
  150. params = ASN1_STRING_new();
  151. if (params == NULL) {
  152. ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
  153. goto err;
  154. }
  155. params->length = i2d_dhp(pkey, pkey->pkey.dh, &params->data);
  156. if (params->length <= 0) {
  157. ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
  158. goto err;
  159. }
  160. params->type = V_ASN1_SEQUENCE;
  161. /* Get private key into integer */
  162. prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL);
  163. if (prkey == NULL) {
  164. ERR_raise(ERR_LIB_DH, DH_R_BN_ERROR);
  165. goto err;
  166. }
  167. dplen = i2d_ASN1_INTEGER(prkey, &dp);
  168. ASN1_STRING_clear_free(prkey);
  169. prkey = NULL;
  170. if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
  171. V_ASN1_SEQUENCE, params, dp, dplen))
  172. goto err;
  173. return 1;
  174. err:
  175. OPENSSL_free(dp);
  176. ASN1_STRING_free(params);
  177. ASN1_STRING_clear_free(prkey);
  178. return 0;
  179. }
  180. static int dh_param_decode(EVP_PKEY *pkey,
  181. const unsigned char **pder, int derlen)
  182. {
  183. DH *dh;
  184. if ((dh = d2i_dhp(pkey, pder, derlen)) == NULL)
  185. return 0;
  186. dh->dirty_cnt++;
  187. EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
  188. return 1;
  189. }
  190. static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
  191. {
  192. return i2d_dhp(pkey, pkey->pkey.dh, pder);
  193. }
  194. static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype)
  195. {
  196. int reason = ERR_R_BUF_LIB;
  197. const char *ktype = NULL;
  198. BIGNUM *priv_key, *pub_key;
  199. if (ptype == 2)
  200. priv_key = x->priv_key;
  201. else
  202. priv_key = NULL;
  203. if (ptype > 0)
  204. pub_key = x->pub_key;
  205. else
  206. pub_key = NULL;
  207. if (x->params.p == NULL || (ptype == 2 && priv_key == NULL)
  208. || (ptype > 0 && pub_key == NULL)) {
  209. reason = ERR_R_PASSED_NULL_PARAMETER;
  210. goto err;
  211. }
  212. if (ptype == 2)
  213. ktype = "DH Private-Key";
  214. else if (ptype == 1)
  215. ktype = "DH Public-Key";
  216. else
  217. ktype = "DH Parameters";
  218. if (!BIO_indent(bp, indent, 128)
  219. || BIO_printf(bp, "%s: (%d bit)\n", ktype, DH_bits(x)) <= 0)
  220. goto err;
  221. indent += 4;
  222. if (!ASN1_bn_print(bp, "private-key:", priv_key, NULL, indent))
  223. goto err;
  224. if (!ASN1_bn_print(bp, "public-key:", pub_key, NULL, indent))
  225. goto err;
  226. if (!ossl_ffc_params_print(bp, &x->params, indent))
  227. goto err;
  228. if (x->length != 0) {
  229. if (!BIO_indent(bp, indent, 128)
  230. || BIO_printf(bp, "recommended-private-length: %d bits\n",
  231. (int)x->length) <= 0)
  232. goto err;
  233. }
  234. return 1;
  235. err:
  236. ERR_raise(ERR_LIB_DH, reason);
  237. return 0;
  238. }
  239. static int int_dh_size(const EVP_PKEY *pkey)
  240. {
  241. return DH_size(pkey->pkey.dh);
  242. }
  243. static int dh_bits(const EVP_PKEY *pkey)
  244. {
  245. return DH_bits(pkey->pkey.dh);
  246. }
  247. static int dh_security_bits(const EVP_PKEY *pkey)
  248. {
  249. return DH_security_bits(pkey->pkey.dh);
  250. }
  251. static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
  252. {
  253. return ossl_ffc_params_cmp(&a->pkey.dh->params, &a->pkey.dh->params,
  254. a->ameth != &ossl_dhx_asn1_meth);
  255. }
  256. static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
  257. {
  258. if (is_x942 == -1)
  259. is_x942 = (from->params.q != NULL);
  260. if (!ossl_ffc_params_copy(&to->params, &from->params))
  261. return 0;
  262. if (!is_x942)
  263. to->length = from->length;
  264. to->dirty_cnt++;
  265. return 1;
  266. }
  267. DH *DHparams_dup(const DH *dh)
  268. {
  269. DH *ret;
  270. ret = DH_new();
  271. if (ret == NULL)
  272. return NULL;
  273. if (!int_dh_param_copy(ret, dh, -1)) {
  274. DH_free(ret);
  275. return NULL;
  276. }
  277. return ret;
  278. }
  279. static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
  280. {
  281. if (to->pkey.dh == NULL) {
  282. to->pkey.dh = DH_new();
  283. if (to->pkey.dh == NULL)
  284. return 0;
  285. }
  286. return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
  287. from->ameth == &ossl_dhx_asn1_meth);
  288. }
  289. static int dh_missing_parameters(const EVP_PKEY *a)
  290. {
  291. return a->pkey.dh == NULL
  292. || a->pkey.dh->params.p == NULL
  293. || a->pkey.dh->params.g == NULL;
  294. }
  295. static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
  296. {
  297. if (dh_cmp_parameters(a, b) == 0)
  298. return 0;
  299. if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0)
  300. return 0;
  301. else
  302. return 1;
  303. }
  304. static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
  305. ASN1_PCTX *ctx)
  306. {
  307. return do_dh_print(bp, pkey->pkey.dh, indent, 0);
  308. }
  309. static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
  310. ASN1_PCTX *ctx)
  311. {
  312. return do_dh_print(bp, pkey->pkey.dh, indent, 1);
  313. }
  314. static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
  315. ASN1_PCTX *ctx)
  316. {
  317. return do_dh_print(bp, pkey->pkey.dh, indent, 2);
  318. }
  319. int DHparams_print(BIO *bp, const DH *x)
  320. {
  321. return do_dh_print(bp, x, 4, 0);
  322. }
  323. static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
  324. {
  325. switch (op) {
  326. case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
  327. /* We should only be here if we have a legacy key */
  328. if (!ossl_assert(evp_pkey_is_legacy(pkey)))
  329. return 0;
  330. return ossl_dh_buf2key(evp_pkey_get0_DH_int(pkey), arg2, arg1);
  331. case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
  332. return ossl_dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2, 0, 1);
  333. default:
  334. return -2;
  335. }
  336. }
  337. static int dhx_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
  338. {
  339. switch (op) {
  340. default:
  341. return -2;
  342. }
  343. }
  344. static int dh_pkey_public_check(const EVP_PKEY *pkey)
  345. {
  346. DH *dh = pkey->pkey.dh;
  347. if (dh->pub_key == NULL) {
  348. ERR_raise(ERR_LIB_DH, DH_R_MISSING_PUBKEY);
  349. return 0;
  350. }
  351. return DH_check_pub_key_ex(dh, dh->pub_key);
  352. }
  353. static int dh_pkey_param_check(const EVP_PKEY *pkey)
  354. {
  355. DH *dh = pkey->pkey.dh;
  356. return DH_check_ex(dh);
  357. }
  358. static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey)
  359. {
  360. return pkey->pkey.dh->dirty_cnt;
  361. }
  362. static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
  363. OSSL_FUNC_keymgmt_import_fn *importer,
  364. OSSL_LIB_CTX *libctx, const char *propq)
  365. {
  366. DH *dh = from->pkey.dh;
  367. OSSL_PARAM_BLD *tmpl;
  368. const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh);
  369. long l = DH_get_length(dh);
  370. const BIGNUM *pub_key = DH_get0_pub_key(dh);
  371. const BIGNUM *priv_key = DH_get0_priv_key(dh);
  372. OSSL_PARAM *params = NULL;
  373. int selection = 0;
  374. int rv = 0;
  375. /*
  376. * If the DH method is foreign, then we can't be sure of anything, and
  377. * can therefore not export or pretend to export.
  378. */
  379. if (ossl_dh_get_method(dh) != DH_OpenSSL())
  380. return 0;
  381. if (p == NULL || g == NULL)
  382. return 0;
  383. tmpl = OSSL_PARAM_BLD_new();
  384. if (tmpl == NULL)
  385. return 0;
  386. if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
  387. || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g))
  388. goto err;
  389. if (q != NULL) {
  390. if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
  391. goto err;
  392. }
  393. selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
  394. if (l > 0) {
  395. if (!OSSL_PARAM_BLD_push_long(tmpl, OSSL_PKEY_PARAM_DH_PRIV_LEN, l))
  396. goto err;
  397. selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS;
  398. }
  399. if (pub_key != NULL) {
  400. if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key))
  401. goto err;
  402. selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
  403. }
  404. if (priv_key != NULL) {
  405. if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
  406. priv_key))
  407. goto err;
  408. selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
  409. }
  410. if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
  411. goto err;
  412. /* We export, the provider imports */
  413. rv = importer(to_keydata, selection, params);
  414. OSSL_PARAM_free(params);
  415. err:
  416. OSSL_PARAM_BLD_free(tmpl);
  417. return rv;
  418. }
  419. static int dh_pkey_import_from_type(const OSSL_PARAM params[], void *vpctx,
  420. int type)
  421. {
  422. EVP_PKEY_CTX *pctx = vpctx;
  423. EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
  424. DH *dh = ossl_dh_new_ex(pctx->libctx);
  425. if (dh == NULL) {
  426. ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
  427. return 0;
  428. }
  429. DH_clear_flags(dh, DH_FLAG_TYPE_MASK);
  430. DH_set_flags(dh, type == EVP_PKEY_DH ? DH_FLAG_TYPE_DH : DH_FLAG_TYPE_DHX);
  431. if (!ossl_dh_params_fromdata(dh, params)
  432. || !ossl_dh_key_fromdata(dh, params)
  433. || !EVP_PKEY_assign(pkey, type, dh)) {
  434. DH_free(dh);
  435. return 0;
  436. }
  437. return 1;
  438. }
  439. static int dh_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
  440. {
  441. return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DH);
  442. }
  443. static int dhx_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
  444. {
  445. return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DHX);
  446. }
  447. static int dh_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
  448. {
  449. DH *dh = from->pkey.dh;
  450. DH *dupkey = NULL;
  451. int ret;
  452. if (dh != NULL) {
  453. dupkey = ossl_dh_dup(dh, OSSL_KEYMGMT_SELECT_ALL);
  454. if (dupkey == NULL)
  455. return 0;
  456. }
  457. ret = EVP_PKEY_assign(to, from->type, dupkey);
  458. if (!ret)
  459. DH_free(dupkey);
  460. return ret;
  461. }
  462. const EVP_PKEY_ASN1_METHOD ossl_dh_asn1_meth = {
  463. EVP_PKEY_DH,
  464. EVP_PKEY_DH,
  465. 0,
  466. "DH",
  467. "OpenSSL PKCS#3 DH method",
  468. dh_pub_decode,
  469. dh_pub_encode,
  470. dh_pub_cmp,
  471. dh_public_print,
  472. dh_priv_decode,
  473. dh_priv_encode,
  474. dh_private_print,
  475. int_dh_size,
  476. dh_bits,
  477. dh_security_bits,
  478. dh_param_decode,
  479. dh_param_encode,
  480. dh_missing_parameters,
  481. dh_copy_parameters,
  482. dh_cmp_parameters,
  483. dh_param_print,
  484. 0,
  485. int_dh_free,
  486. dh_pkey_ctrl,
  487. 0, 0, 0, 0, 0,
  488. 0,
  489. dh_pkey_public_check,
  490. dh_pkey_param_check,
  491. 0, 0, 0, 0,
  492. dh_pkey_dirty_cnt,
  493. dh_pkey_export_to,
  494. dh_pkey_import_from,
  495. dh_pkey_copy
  496. };
  497. const EVP_PKEY_ASN1_METHOD ossl_dhx_asn1_meth = {
  498. EVP_PKEY_DHX,
  499. EVP_PKEY_DHX,
  500. 0,
  501. "X9.42 DH",
  502. "OpenSSL X9.42 DH method",
  503. dh_pub_decode,
  504. dh_pub_encode,
  505. dh_pub_cmp,
  506. dh_public_print,
  507. dh_priv_decode,
  508. dh_priv_encode,
  509. dh_private_print,
  510. int_dh_size,
  511. dh_bits,
  512. dh_security_bits,
  513. dh_param_decode,
  514. dh_param_encode,
  515. dh_missing_parameters,
  516. dh_copy_parameters,
  517. dh_cmp_parameters,
  518. dh_param_print,
  519. 0,
  520. int_dh_free,
  521. dhx_pkey_ctrl,
  522. 0, 0, 0, 0, 0,
  523. 0,
  524. dh_pkey_public_check,
  525. dh_pkey_param_check,
  526. 0, 0, 0, 0,
  527. dh_pkey_dirty_cnt,
  528. dh_pkey_export_to,
  529. dhx_pkey_import_from,
  530. dh_pkey_copy
  531. };