Coverage Report

Created: 2024-11-21 07:03

/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
}