p_dsa_asn1.c
Go to the documentation of this file.
1 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
2  * 2006.
3  */
4 /* ====================================================================
5  * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  * software must display the following acknowledgment:
21  * "This product includes software developed by the OpenSSL Project
22  * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  * endorse or promote products derived from this software without
26  * prior written permission. For written permission, please contact
27  * licensing@OpenSSL.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  * nor may "OpenSSL" appear in their names without prior written
31  * permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  * acknowledgment:
35  * "This product includes software developed by the OpenSSL Project
36  * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com). This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com). */
55 
56 #include <openssl/evp.h>
57 
58 #include <openssl/digest.h>
59 #include <openssl/bn.h>
60 #include <openssl/bytestring.h>
61 #include <openssl/dsa.h>
62 #include <openssl/err.h>
63 
64 #include "internal.h"
65 
66 
67 static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
68  // See RFC 3279, section 2.3.2.
69 
70  // Parameters may or may not be present.
71  DSA *dsa;
72  if (CBS_len(params) == 0) {
73  dsa = DSA_new();
74  if (dsa == NULL) {
75  return 0;
76  }
77  } else {
78  dsa = DSA_parse_parameters(params);
79  if (dsa == NULL || CBS_len(params) != 0) {
81  goto err;
82  }
83  }
84 
85  dsa->pub_key = BN_new();
86  if (dsa->pub_key == NULL) {
87  goto err;
88  }
89 
90  if (!BN_parse_asn1_unsigned(key, dsa->pub_key) ||
91  CBS_len(key) != 0) {
93  goto err;
94  }
95 
97  return 1;
98 
99 err:
100  DSA_free(dsa);
101  return 0;
102 }
103 
104 static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) {
105  const DSA *dsa = key->pkey.dsa;
106  const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL;
107 
108  // See RFC 5480, section 2.
109  CBB spki, algorithm, oid, key_bitstring;
110  if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
111  !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
112  !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
114  (has_params &&
115  !DSA_marshal_parameters(&algorithm, dsa)) ||
116  !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
117  !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
118  !BN_marshal_asn1(&key_bitstring, dsa->pub_key) ||
119  !CBB_flush(out)) {
121  return 0;
122  }
123 
124  return 1;
125 }
126 
127 static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
128  // See PKCS#11, v2.40, section 2.5.
129 
130  // Decode parameters.
131  BN_CTX *ctx = NULL;
132  DSA *dsa = DSA_parse_parameters(params);
133  if (dsa == NULL || CBS_len(params) != 0) {
135  goto err;
136  }
137 
138  dsa->priv_key = BN_new();
139  dsa->pub_key = BN_new();
140  if (dsa->priv_key == NULL || dsa->pub_key == NULL) {
141  goto err;
142  }
143 
144  // Decode the key. To avoid DoS attacks when importing private keys, we bound
145  // |dsa->priv_key| against |dsa->q|, which itself bound by
146  // |DSA_parse_parameters|. (We cannot call |BN_num_bits| on |dsa->priv_key|.
147  // That would leak a secret bit width.)
148  if (!BN_parse_asn1_unsigned(key, dsa->priv_key) ||
149  CBS_len(key) != 0 ||
150  BN_cmp(dsa->priv_key, dsa->q) >= 0) {
152  goto err;
153  }
154 
155  // Calculate the public key.
156  ctx = BN_CTX_new();
157  if (ctx == NULL ||
158  !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p,
159  ctx, NULL)) {
160  goto err;
161  }
162 
163  BN_CTX_free(ctx);
164  EVP_PKEY_assign_DSA(out, dsa);
165  return 1;
166 
167 err:
168  BN_CTX_free(ctx);
169  DSA_free(dsa);
170  return 0;
171 }
172 
173 static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) {
174  const DSA *dsa = key->pkey.dsa;
175  if (dsa == NULL || dsa->priv_key == NULL) {
177  return 0;
178  }
179 
180  // See PKCS#11, v2.40, section 2.5.
181  CBB pkcs8, algorithm, oid, private_key;
182  if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
183  !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
184  !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
185  !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
187  !DSA_marshal_parameters(&algorithm, dsa) ||
190  !CBB_flush(out)) {
192  return 0;
193  }
194 
195  return 1;
196 }
197 
198 static int int_dsa_size(const EVP_PKEY *pkey) {
199  return DSA_size(pkey->pkey.dsa);
200 }
201 
202 static int dsa_bits(const EVP_PKEY *pkey) {
203  return BN_num_bits(pkey->pkey.dsa->p);
204 }
205 
206 static int dsa_missing_parameters(const EVP_PKEY *pkey) {
207  DSA *dsa;
208  dsa = pkey->pkey.dsa;
209  if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) {
210  return 1;
211  }
212  return 0;
213 }
214 
215 static int dup_bn_into(BIGNUM **out, BIGNUM *src) {
216  BIGNUM *a;
217 
218  a = BN_dup(src);
219  if (a == NULL) {
220  return 0;
221  }
222  BN_free(*out);
223  *out = a;
224 
225  return 1;
226 }
227 
229  if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) ||
230  !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) ||
231  !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) {
232  return 0;
233  }
234 
235  return 1;
236 }
237 
238 static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
239  return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 &&
240  BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 &&
241  BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0;
242 }
243 
244 static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
245  return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0;
246 }
247 
248 static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); }
249 
251  EVP_PKEY_DSA,
252  // 1.2.840.10040.4.1
253  {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7,
254 
257  dsa_pub_cmp,
258 
261 
262  NULL /* set_priv_raw */,
263  NULL /* set_pub_raw */,
264  NULL /* get_priv_raw */,
265  NULL /* get_pub_raw */,
266 
267  NULL /* pkey_opaque */,
268 
269  int_dsa_size,
270  dsa_bits,
271 
275 
276  int_dsa_free,
277 };
dsa_bits
static int dsa_bits(const EVP_PKEY *pkey)
Definition: p_dsa_asn1.c:202
bn.h
CBB_flush
#define CBB_flush
Definition: boringssl_prefix_symbols.h:1045
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
int_dsa_free
static void int_dsa_free(EVP_PKEY *pkey)
Definition: p_dsa_asn1.c:248
cbs_st
Definition: bytestring.h:39
dsa_asn1_meth
const EVP_PKEY_ASN1_METHOD dsa_asn1_meth
Definition: p_dsa_asn1.c:250
ctx
Definition: benchmark-async.c:30
BN_dup
#define BN_dup
Definition: boringssl_prefix_symbols.h:919
evp.h
int_dsa_size
static int int_dsa_size(const EVP_PKEY *pkey)
Definition: p_dsa_asn1.c:198
evp_pkey_st::dsa
DSA * dsa
Definition: evp.h:1056
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
CBS_ASN1_OCTETSTRING
#define CBS_ASN1_OCTETSTRING
Definition: bytestring.h:209
CBB_add_u8
#define CBB_add_u8
Definition: boringssl_prefix_symbols.h:1036
error_ref_leak.err
err
Definition: error_ref_leak.py:35
evp_pkey_asn1_method_st::oid_len
uint8_t oid_len
Definition: third_party/boringssl-with-bazel/src/crypto/evp/internal.h:72
CBS_len
#define CBS_len
Definition: boringssl_prefix_symbols.h:1089
BN_free
#define BN_free
Definition: boringssl_prefix_symbols.h:923
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
to
size_t to
Definition: abseil-cpp/absl/container/internal/layout_test.cc:1385
bignum_ctx
Definition: ctx.c:91
dsa_priv_decode
static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key)
Definition: p_dsa_asn1.c:127
DSA_parse_parameters
#define DSA_parse_parameters
Definition: boringssl_prefix_symbols.h:1285
DSA_new
#define DSA_new
Definition: boringssl_prefix_symbols.h:1284
EVP_R_ENCODE_ERROR
#define EVP_R_ENCODE_ERROR
Definition: evp_errors.h:65
EVP_PKEY_DSA
#define EVP_PKEY_DSA
Definition: evp.h:177
from
size_t from
Definition: abseil-cpp/absl/container/internal/layout_test.cc:1384
EVP_R_DECODE_ERROR
#define EVP_R_DECODE_ERROR
Definition: evp_errors.h:62
bytestring.h
internal.h
dsa_copy_parameters
static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
Definition: p_dsa_asn1.c:228
evp_pkey_st
Definition: evp.h:1046
oid
uint8_t oid[9]
Definition: digest_extra.c:124
dsa_st::p
BIGNUM * p
Definition: dsa.h:400
DSA_free
#define DSA_free
Definition: boringssl_prefix_symbols.h:1269
DSA_marshal_parameters
#define DSA_marshal_parameters
Definition: boringssl_prefix_symbols.h:1281
dsa_pub_cmp
static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
Definition: p_dsa_asn1.c:244
dsa_st::q
BIGNUM * q
Definition: dsa.h:401
CBB_add_asn1
#define CBB_add_asn1
Definition: boringssl_prefix_symbols.h:1019
err.h
dsa.h
dsa_st::priv_key
BIGNUM * priv_key
Definition: dsa.h:405
BN_CTX_new
#define BN_CTX_new
Definition: boringssl_prefix_symbols.h:885
DSA_size
#define DSA_size
Definition: boringssl_prefix_symbols.h:1292
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
dsa_pub_decode
static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key)
Definition: p_dsa_asn1.c:67
dsa_priv_encode
static int dsa_priv_encode(CBB *out, const EVP_PKEY *key)
Definition: p_dsa_asn1.c:173
EVP_R_MISSING_PARAMETERS
#define EVP_R_MISSING_PARAMETERS
Definition: evp_errors.h:78
BN_num_bits
#define BN_num_bits
Definition: boringssl_prefix_symbols.h:974
evp_pkey_st::pkey
union evp_pkey_st::@364 pkey
CBB_add_bytes
#define CBB_add_bytes
Definition: boringssl_prefix_symbols.h:1025
digest.h
key
const char * key
Definition: hpack_parser_table.cc:164
CBS_ASN1_BITSTRING
#define CBS_ASN1_BITSTRING
Definition: bytestring.h:208
bignum_st
Definition: bn.h:957
CBS_ASN1_OBJECT
#define CBS_ASN1_OBJECT
Definition: bytestring.h:211
BN_CTX_free
#define BN_CTX_free
Definition: boringssl_prefix_symbols.h:883
private_key
Definition: hrss.c:1885
BN_cmp
#define BN_cmp
Definition: boringssl_prefix_symbols.h:912
BN_mod_exp_mont_consttime
#define BN_mod_exp_mont_consttime
Definition: boringssl_prefix_symbols.h:951
dsa_st
Definition: dsa.h:398
dsa_st::g
BIGNUM * g
Definition: dsa.h:402
BN_parse_asn1_unsigned
#define BN_parse_asn1_unsigned
Definition: boringssl_prefix_symbols.h:978
evp_pkey_asn1_method_st
Definition: third_party/boringssl-with-bazel/src/crypto/evp/internal.h:69
dsa_st::pub_key
BIGNUM * pub_key
Definition: dsa.h:404
dsa_pub_encode
static int dsa_pub_encode(CBB *out, const EVP_PKEY *key)
Definition: p_dsa_asn1.c:104
EVP_PKEY_assign_DSA
#define EVP_PKEY_assign_DSA
Definition: boringssl_prefix_symbols.h:1610
BN_marshal_asn1
#define BN_marshal_asn1
Definition: boringssl_prefix_symbols.h:944
CBS_ASN1_SEQUENCE
#define CBS_ASN1_SEQUENCE
Definition: bytestring.h:214
tests.interop.resources.private_key
def private_key()
Definition: interop/resources.py:29
dup_bn_into
static int dup_bn_into(BIGNUM **out, BIGNUM *src)
Definition: p_dsa_asn1.c:215
dsa_missing_parameters
static int dsa_missing_parameters(const EVP_PKEY *pkey)
Definition: p_dsa_asn1.c:206
dsa_cmp_parameters
static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
Definition: p_dsa_asn1.c:238
BN_new
#define BN_new
Definition: boringssl_prefix_symbols.h:971
evp_pkey_asn1_method_st::oid
uint8_t oid[9]
Definition: third_party/boringssl-with-bazel/src/crypto/evp/internal.h:71
CBB_add_asn1_uint64
#define CBB_add_asn1_uint64
Definition: boringssl_prefix_symbols.h:1024
cbb_st
Definition: bytestring.h:375


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:38