|
| 1 | +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ |
| 2 | +/* SPDX-License-Identifier: Unlicense */ |
| 3 | + |
| 4 | +#include "tomcrypt_private.h" |
| 5 | + |
| 6 | +#ifdef LTC_MDH |
| 7 | + |
| 8 | +int dh_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dh_key *key) |
| 9 | +{ |
| 10 | + int err; |
| 11 | + |
| 12 | + LTC_ARGCHK(key != NULL); |
| 13 | + |
| 14 | + if (!alg_id->child || |
| 15 | + !LTC_ASN1_IS_TYPE(alg_id->child->next, LTC_ASN1_SEQUENCE) || |
| 16 | + !LTC_ASN1_IS_TYPE(alg_id->child->next->child, LTC_ASN1_INTEGER) || |
| 17 | + !LTC_ASN1_IS_TYPE(alg_id->child->next->child->next, LTC_ASN1_INTEGER)) { |
| 18 | + return CRYPT_PK_INVALID_TYPE; |
| 19 | + } |
| 20 | + |
| 21 | + if ((err = dh_init(key)) != CRYPT_OK) { |
| 22 | + return err; |
| 23 | + } |
| 24 | + |
| 25 | + if ((err = mp_copy(alg_id->child->next->child->data, key->prime)) != CRYPT_OK) { |
| 26 | + goto error; |
| 27 | + } |
| 28 | + if ((err = mp_copy(alg_id->child->next->child->next->data, key->base)) != CRYPT_OK) { |
| 29 | + goto error; |
| 30 | + } |
| 31 | + |
| 32 | + if ((err = der_decode_integer(priv_key->data, priv_key->size, key->x)) != CRYPT_OK) { |
| 33 | + goto error; |
| 34 | + } |
| 35 | + /* compute public key: y = (base ^ x) mod prime */ |
| 36 | + if ((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) { |
| 37 | + goto error; |
| 38 | + } |
| 39 | + /* check public key */ |
| 40 | + if ((err = dh_check_pubkey(key)) != CRYPT_OK) { |
| 41 | + goto error; |
| 42 | + } |
| 43 | + key->type = PK_PRIVATE; |
| 44 | + |
| 45 | + return CRYPT_OK; |
| 46 | +error: |
| 47 | + dh_free(key); |
| 48 | + return err; |
| 49 | +} |
| 50 | + |
| 51 | +/** |
| 52 | + Import a DH key in PKCS#8 format |
| 53 | + @param in The packet to import from |
| 54 | + @param inlen It's length (octets) |
| 55 | + @param pw_ctx The password context when decrypting the private key |
| 56 | + @param key [out] Destination for newly imported key |
| 57 | + @return CRYPT_OK if successful, on error all allocated memory is freed automatically |
| 58 | +*/ |
| 59 | +int dh_import_pkcs8(const unsigned char *in, unsigned long inlen, |
| 60 | + const password_ctx *pw_ctx, dh_key *key) |
| 61 | +{ |
| 62 | + int err; |
| 63 | + ltc_asn1_list *l = NULL; |
| 64 | + ltc_asn1_list *alg_id, *priv_key; |
| 65 | + enum ltc_oid_id pka; |
| 66 | + |
| 67 | + LTC_ARGCHK(in != NULL); |
| 68 | + |
| 69 | + if ((err = pkcs8_decode_flexi(in, inlen, pw_ctx, &l)) != CRYPT_OK) { |
| 70 | + return err; |
| 71 | + } |
| 72 | + if ((err = pkcs8_get_children(l, &pka, &alg_id, &priv_key)) != CRYPT_OK) { |
| 73 | + goto LBL_DER_FREE; |
| 74 | + } |
| 75 | + if (pka != LTC_OID_DH) { |
| 76 | + err = CRYPT_INVALID_PACKET; |
| 77 | + goto LBL_DER_FREE; |
| 78 | + } |
| 79 | + |
| 80 | + err = dh_import_pkcs8_asn1(alg_id, priv_key, key); |
| 81 | + |
| 82 | +LBL_DER_FREE: |
| 83 | + der_free_sequence_flexi(l); |
| 84 | + return err; |
| 85 | +} |
| 86 | + |
| 87 | +#endif /* LTC_MDH */ |
0 commit comments