dh_ameth.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. /*
  2. * Copyright 2006-2022 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_ASN1_LIB);
  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_ASN1_LIB);
  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_ASN1_LIB);
  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_ASN1_LIB);
  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_ASN1_LIB);
  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. if (dplen <= 0) {
  170. ERR_raise(ERR_LIB_DH, DH_R_BN_ERROR);
  171. goto err;
  172. }
  173. if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
  174. V_ASN1_SEQUENCE, params, dp, dplen)) {
  175. OPENSSL_clear_free(dp, dplen);
  176. goto err;
  177. }
  178. return 1;
  179. err:
  180. ASN1_STRING_free(params);
  181. return 0;
  182. }
  183. static int dh_param_decode(EVP_PKEY *pkey,
  184. const unsigned char **pder, int derlen)
  185. {
  186. DH *dh;
  187. if ((dh = d2i_dhp(pkey, pder, derlen)) == NULL)
  188. return 0;
  189. dh->dirty_cnt++;
  190. EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
  191. return 1;
  192. }
  193. static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
  194. {
  195. return i2d_dhp(pkey, pkey->pkey.dh, pder);
  196. }
  197. static int do_dh_print(BIO *bp, const DH *x, int indent, int ptype)
  198. {
  199. int reason = ERR_R_BUF_LIB;
  200. const char *ktype = NULL;
  201. BIGNUM *priv_key, *pub_key;
  202. if (ptype == 2)
  203. priv_key = x->priv_key;
  204. else
  205. priv_key = NULL;
  206. if (ptype > 0)
  207. pub_key = x->pub_key;
  208. else
  209. pub_key = NULL;
  210. if (x->params.p == NULL || (ptype == 2 && priv_key == NULL)
  211. || (ptype > 0 && pub_key == NULL)) {
  212. reason = ERR_R_PASSED_NULL_PARAMETER;
  213. goto err;
  214. }
  215. if (ptype == 2)
  216. ktype = "DH Private-Key";
  217. else if (ptype == 1)
  218. ktype = "DH Public-Key";
  219. else
  220. ktype = "DH Parameters";
  221. if (!BIO_indent(bp, indent, 128)
  222. || BIO_printf(bp, "%s: (%d bit)\n", ktype, DH_bits(x)) <= 0)
  223. goto err;
  224. indent += 4;
  225. if (!ASN1_bn_print(bp, "private-key:", priv_key, NULL, indent))
  226. goto err;
  227. if (!ASN1_bn_print(bp, "public-key:", pub_key, NULL, indent))
  228. goto err;
  229. if (!ossl_ffc_params_print(bp, &x->params, indent))
  230. goto err;
  231. if (x->length != 0) {
  232. if (!BIO_indent(bp, indent, 128)
  233. || BIO_printf(bp, "recommended-private-length: %d bits\n",
  234. (int)x->length) <= 0)
  235. goto err;
  236. }
  237. return 1;
  238. err:
  239. ERR_raise(ERR_LIB_DH, reason);
  240. return 0;
  241. }
  242. static int int_dh_size(const EVP_PKEY *pkey)
  243. {
  244. return DH_size(pkey->pkey.dh);
  245. }
  246. static int dh_bits(const EVP_PKEY *pkey)
  247. {
  248. return DH_bits(pkey->pkey.dh);
  249. }
  250. static int dh_security_bits(const EVP_PKEY *pkey)
  251. {
  252. return DH_security_bits(pkey->pkey.dh);
  253. }
  254. static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
  255. {
  256. return ossl_ffc_params_cmp(&a->pkey.dh->params, &b->pkey.dh->params,
  257. a->ameth != &ossl_dhx_asn1_meth);
  258. }
  259. static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
  260. {
  261. if (is_x942 == -1)
  262. is_x942 = (from->params.q != NULL);
  263. if (!ossl_ffc_params_copy(&to->params, &from->params))
  264. return 0;
  265. if (!is_x942)
  266. to->length = from->length;
  267. to->dirty_cnt++;
  268. return 1;
  269. }
  270. DH *DHparams_dup(const DH *dh)
  271. {
  272. DH *ret;
  273. ret = DH_new();
  274. if (ret == NULL)
  275. return NULL;
  276. if (!int_dh_param_copy(ret, dh, -1)) {
  277. DH_free(ret);
  278. return NULL;
  279. }
  280. return ret;
  281. }
  282. static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
  283. {
  284. if (to->pkey.dh == NULL) {
  285. to->pkey.dh = DH_new();
  286. if (to->pkey.dh == NULL)
  287. return 0;
  288. }
  289. return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
  290. from->ameth == &ossl_dhx_asn1_meth);
  291. }
  292. static int dh_missing_parameters(const EVP_PKEY *a)
  293. {
  294. return a->pkey.dh == NULL
  295. || a->pkey.dh->params.p == NULL
  296. || a->pkey.dh->params.g == NULL;
  297. }
  298. static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
  299. {
  300. if (dh_cmp_parameters(a, b) == 0)
  301. return 0;
  302. if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0)
  303. return 0;
  304. else
  305. return 1;
  306. }
  307. static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
  308. ASN1_PCTX *ctx)
  309. {
  310. return do_dh_print(bp, pkey->pkey.dh, indent, 0);
  311. }
  312. static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent,
  313. ASN1_PCTX *ctx)
  314. {
  315. return do_dh_print(bp, pkey->pkey.dh, indent, 1);
  316. }
  317. static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent,
  318. ASN1_PCTX *ctx)
  319. {
  320. return do_dh_print(bp, pkey->pkey.dh, indent, 2);
  321. }
  322. int DHparams_print(BIO *bp, const DH *x)
  323. {
  324. return do_dh_print(bp, x, 4, 0);
  325. }
  326. static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
  327. {
  328. DH *dh;
  329. switch (op) {
  330. case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
  331. /* We should only be here if we have a legacy key */
  332. if (!ossl_assert(evp_pkey_is_legacy(pkey)))
  333. return 0;
  334. dh = (DH *) evp_pkey_get0_DH_int(pkey);
  335. if (dh == NULL)
  336. return 0;
  337. return ossl_dh_buf2key(dh, arg2, arg1);
  338. case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
  339. dh = (DH *) EVP_PKEY_get0_DH(pkey);
  340. if (dh == NULL)
  341. return 0;
  342. return ossl_dh_key2buf(dh, arg2, 0, 1);
  343. default:
  344. return -2;
  345. }
  346. }
  347. static int dhx_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
  348. {
  349. switch (op) {
  350. default:
  351. return -2;
  352. }
  353. }
  354. static int dh_pkey_public_check(const EVP_PKEY *pkey)
  355. {
  356. DH *dh = pkey->pkey.dh;
  357. if (dh->pub_key == NULL) {
  358. ERR_raise(ERR_LIB_DH, DH_R_MISSING_PUBKEY);
  359. return 0;
  360. }
  361. return DH_check_pub_key_ex(dh, dh->pub_key);
  362. }
  363. static int dh_pkey_param_check(const EVP_PKEY *pkey)
  364. {
  365. DH *dh = pkey->pkey.dh;
  366. return DH_check_ex(dh);
  367. }
  368. static size_t dh_pkey_dirty_cnt(const EVP_PKEY *pkey)
  369. {
  370. return pkey->pkey.dh->dirty_cnt;
  371. }
  372. static int dh_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
  373. OSSL_FUNC_keymgmt_import_fn *importer,
  374. OSSL_LIB_CTX *libctx, const char *propq)
  375. {
  376. DH *dh = from->pkey.dh;
  377. OSSL_PARAM_BLD *tmpl;
  378. const BIGNUM *p = DH_get0_p(dh), *g = DH_get0_g(dh), *q = DH_get0_q(dh);
  379. long l = DH_get_length(dh);
  380. const BIGNUM *pub_key = DH_get0_pub_key(dh);
  381. const BIGNUM *priv_key = DH_get0_priv_key(dh);
  382. OSSL_PARAM *params = NULL;
  383. int selection = 0;
  384. int rv = 0;
  385. if (p == NULL || g == NULL)
  386. return 0;
  387. tmpl = OSSL_PARAM_BLD_new();
  388. if (tmpl == NULL)
  389. return 0;
  390. if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
  391. || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g))
  392. goto err;
  393. if (q != NULL) {
  394. if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q))
  395. goto err;
  396. }
  397. selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
  398. if (l > 0) {
  399. if (!OSSL_PARAM_BLD_push_long(tmpl, OSSL_PKEY_PARAM_DH_PRIV_LEN, l))
  400. goto err;
  401. selection |= OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS;
  402. }
  403. if (pub_key != NULL) {
  404. if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, pub_key))
  405. goto err;
  406. selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
  407. }
  408. if (priv_key != NULL) {
  409. if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
  410. priv_key))
  411. goto err;
  412. selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
  413. }
  414. if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
  415. goto err;
  416. /* We export, the provider imports */
  417. rv = importer(to_keydata, selection, params);
  418. OSSL_PARAM_free(params);
  419. err:
  420. OSSL_PARAM_BLD_free(tmpl);
  421. return rv;
  422. }
  423. static int dh_pkey_import_from_type(const OSSL_PARAM params[], void *vpctx,
  424. int type)
  425. {
  426. EVP_PKEY_CTX *pctx = vpctx;
  427. EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
  428. DH *dh = ossl_dh_new_ex(pctx->libctx);
  429. if (dh == NULL) {
  430. ERR_raise(ERR_LIB_DH, ERR_R_DH_LIB);
  431. return 0;
  432. }
  433. DH_clear_flags(dh, DH_FLAG_TYPE_MASK);
  434. DH_set_flags(dh, type == EVP_PKEY_DH ? DH_FLAG_TYPE_DH : DH_FLAG_TYPE_DHX);
  435. if (!ossl_dh_params_fromdata(dh, params)
  436. || !ossl_dh_key_fromdata(dh, params, 1)
  437. || !EVP_PKEY_assign(pkey, type, dh)) {
  438. DH_free(dh);
  439. return 0;
  440. }
  441. return 1;
  442. }
  443. static int dh_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
  444. {
  445. return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DH);
  446. }
  447. static int dhx_pkey_import_from(const OSSL_PARAM params[], void *vpctx)
  448. {
  449. return dh_pkey_import_from_type(params, vpctx, EVP_PKEY_DHX);
  450. }
  451. static int dh_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
  452. {
  453. DH *dh = from->pkey.dh;
  454. DH *dupkey = NULL;
  455. int ret;
  456. if (dh != NULL) {
  457. dupkey = ossl_dh_dup(dh, OSSL_KEYMGMT_SELECT_ALL);
  458. if (dupkey == NULL)
  459. return 0;
  460. }
  461. ret = EVP_PKEY_assign(to, from->type, dupkey);
  462. if (!ret)
  463. DH_free(dupkey);
  464. return ret;
  465. }
  466. const EVP_PKEY_ASN1_METHOD ossl_dh_asn1_meth = {
  467. EVP_PKEY_DH,
  468. EVP_PKEY_DH,
  469. 0,
  470. "DH",
  471. "OpenSSL PKCS#3 DH method",
  472. dh_pub_decode,
  473. dh_pub_encode,
  474. dh_pub_cmp,
  475. dh_public_print,
  476. dh_priv_decode,
  477. dh_priv_encode,
  478. dh_private_print,
  479. int_dh_size,
  480. dh_bits,
  481. dh_security_bits,
  482. dh_param_decode,
  483. dh_param_encode,
  484. dh_missing_parameters,
  485. dh_copy_parameters,
  486. dh_cmp_parameters,
  487. dh_param_print,
  488. 0,
  489. int_dh_free,
  490. dh_pkey_ctrl,
  491. 0, 0, 0, 0, 0,
  492. 0,
  493. dh_pkey_public_check,
  494. dh_pkey_param_check,
  495. 0, 0, 0, 0,
  496. dh_pkey_dirty_cnt,
  497. dh_pkey_export_to,
  498. dh_pkey_import_from,
  499. dh_pkey_copy
  500. };
  501. const EVP_PKEY_ASN1_METHOD ossl_dhx_asn1_meth = {
  502. EVP_PKEY_DHX,
  503. EVP_PKEY_DHX,
  504. 0,
  505. "X9.42 DH",
  506. "OpenSSL X9.42 DH method",
  507. dh_pub_decode,
  508. dh_pub_encode,
  509. dh_pub_cmp,
  510. dh_public_print,
  511. dh_priv_decode,
  512. dh_priv_encode,
  513. dh_private_print,
  514. int_dh_size,
  515. dh_bits,
  516. dh_security_bits,
  517. dh_param_decode,
  518. dh_param_encode,
  519. dh_missing_parameters,
  520. dh_copy_parameters,
  521. dh_cmp_parameters,
  522. dh_param_print,
  523. 0,
  524. int_dh_free,
  525. dhx_pkey_ctrl,
  526. 0, 0, 0, 0, 0,
  527. 0,
  528. dh_pkey_public_check,
  529. dh_pkey_param_check,
  530. 0, 0, 0, 0,
  531. dh_pkey_dirty_cnt,
  532. dh_pkey_export_to,
  533. dhx_pkey_import_from,
  534. dh_pkey_copy
  535. };