/src/boringssl/crypto/evp/p_dh_asn1.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * |
4 | | * Licensed under the OpenSSL license (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 | | #include <openssl/evp.h> |
11 | | |
12 | | #include <openssl/bn.h> |
13 | | #include <openssl/dh.h> |
14 | | #include <openssl/err.h> |
15 | | |
16 | | #include "internal.h" |
17 | | #include "../internal.h" |
18 | | |
19 | | |
20 | 0 | static void dh_free(EVP_PKEY *pkey) { |
21 | 0 | DH_free(pkey->pkey); |
22 | 0 | pkey->pkey = NULL; |
23 | 0 | } |
24 | | |
25 | 0 | static int dh_size(const EVP_PKEY *pkey) { return DH_size(pkey->pkey); } |
26 | | |
27 | 0 | static int dh_bits(const EVP_PKEY *pkey) { return DH_bits(pkey->pkey); } |
28 | | |
29 | 0 | static int dh_param_missing(const EVP_PKEY *pkey) { |
30 | 0 | const DH *dh = pkey->pkey; |
31 | 0 | return dh == NULL || DH_get0_p(dh) == NULL || DH_get0_g(dh) == NULL; |
32 | 0 | } |
33 | | |
34 | 0 | static int dh_param_copy(EVP_PKEY *to, const EVP_PKEY *from) { |
35 | 0 | if (dh_param_missing(from)) { |
36 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); |
37 | 0 | return 0; |
38 | 0 | } |
39 | | |
40 | 0 | const DH *dh = from->pkey; |
41 | 0 | const BIGNUM *q_old = DH_get0_q(dh); |
42 | 0 | BIGNUM *p = BN_dup(DH_get0_p(dh)); |
43 | 0 | BIGNUM *q = q_old == NULL ? NULL : BN_dup(q_old); |
44 | 0 | BIGNUM *g = BN_dup(DH_get0_g(dh)); |
45 | 0 | if (p == NULL || (q_old != NULL && q == NULL) || g == NULL || |
46 | 0 | !DH_set0_pqg(to->pkey, p, q, g)) { |
47 | 0 | BN_free(p); |
48 | 0 | BN_free(q); |
49 | 0 | BN_free(g); |
50 | 0 | return 0; |
51 | 0 | } |
52 | | |
53 | | // |DH_set0_pqg| took ownership of |p|, |q|, and |g|. |
54 | 0 | return 1; |
55 | 0 | } |
56 | | |
57 | 0 | static int dh_param_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { |
58 | 0 | if (dh_param_missing(a) || dh_param_missing(b)) { |
59 | 0 | return -2; |
60 | 0 | } |
61 | | |
62 | | // Matching OpenSSL, only compare p and g for PKCS#3-style Diffie-Hellman. |
63 | | // OpenSSL only checks q in X9.42-style Diffie-Hellman ("DHX"). |
64 | 0 | const DH *a_dh = a->pkey; |
65 | 0 | const DH *b_dh = b->pkey; |
66 | 0 | return BN_cmp(DH_get0_p(a_dh), DH_get0_p(b_dh)) == 0 && |
67 | 0 | BN_cmp(DH_get0_g(a_dh), DH_get0_g(b_dh)) == 0; |
68 | 0 | } |
69 | | |
70 | 0 | static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { |
71 | 0 | if (dh_param_cmp(a, b) <= 0) { |
72 | 0 | return 0; |
73 | 0 | } |
74 | | |
75 | 0 | const DH *a_dh = a->pkey; |
76 | 0 | const DH *b_dh = b->pkey; |
77 | 0 | return BN_cmp(DH_get0_pub_key(a_dh), DH_get0_pub_key(b_dh)) == 0; |
78 | 0 | } |
79 | | |
80 | | const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { |
81 | | .pkey_id = EVP_PKEY_DH, |
82 | | .pkey_method = &dh_pkey_meth, |
83 | | .pub_cmp = dh_pub_cmp, |
84 | | .pkey_size = dh_size, |
85 | | .pkey_bits = dh_bits, |
86 | | .param_missing = dh_param_missing, |
87 | | .param_copy = dh_param_copy, |
88 | | .param_cmp = dh_param_cmp, |
89 | | .pkey_free = dh_free, |
90 | | }; |
91 | | |
92 | 0 | int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) { |
93 | 0 | if (EVP_PKEY_assign_DH(pkey, key)) { |
94 | 0 | DH_up_ref(key); |
95 | 0 | return 1; |
96 | 0 | } |
97 | 0 | return 0; |
98 | 0 | } |
99 | | |
100 | 0 | int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) { |
101 | 0 | evp_pkey_set_method(pkey, &dh_asn1_meth); |
102 | 0 | pkey->pkey = key; |
103 | 0 | return key != NULL; |
104 | 0 | } |
105 | | |
106 | 0 | DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey) { |
107 | 0 | if (pkey->type != EVP_PKEY_DH) { |
108 | 0 | OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY); |
109 | 0 | return NULL; |
110 | 0 | } |
111 | 0 | return pkey->pkey; |
112 | 0 | } |
113 | | |
114 | 0 | DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey) { |
115 | 0 | DH *dh = EVP_PKEY_get0_DH(pkey); |
116 | 0 | if (dh != NULL) { |
117 | 0 | DH_up_ref(dh); |
118 | 0 | } |
119 | 0 | return dh; |
120 | 0 | } |