Coverage Report

Created: 2024-11-21 07:03

/src/boringssl/crypto/evp/p_dsa_asn1.c
Line
Count
Source (jump to first uncovered line)
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 "../dsa/internal.h"
65
#include "internal.h"
66
67
68
0
static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
69
  // See RFC 3279, section 2.3.2.
70
71
  // Parameters may or may not be present.
72
0
  DSA *dsa;
73
0
  if (CBS_len(params) == 0) {
74
0
    dsa = DSA_new();
75
0
    if (dsa == NULL) {
76
0
      return 0;
77
0
    }
78
0
  } else {
79
0
    dsa = DSA_parse_parameters(params);
80
0
    if (dsa == NULL || CBS_len(params) != 0) {
81
0
      OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
82
0
      goto err;
83
0
    }
84
0
  }
85
86
0
  dsa->pub_key = BN_new();
87
0
  if (dsa->pub_key == NULL) {
88
0
    goto err;
89
0
  }
90
91
0
  if (!BN_parse_asn1_unsigned(key, dsa->pub_key) ||
92
0
      CBS_len(key) != 0) {
93
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
94
0
    goto err;
95
0
  }
96
97
0
  EVP_PKEY_assign_DSA(out, dsa);
98
0
  return 1;
99
100
0
err:
101
0
  DSA_free(dsa);
102
0
  return 0;
103
0
}
104
105
0
static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) {
106
0
  const DSA *dsa = key->pkey;
107
0
  const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL;
108
109
  // See RFC 5480, section 2.
110
0
  CBB spki, algorithm, oid, key_bitstring;
111
0
  if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) ||
112
0
      !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
113
0
      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
114
0
      !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
115
0
      (has_params &&
116
0
       !DSA_marshal_parameters(&algorithm, dsa)) ||
117
0
      !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) ||
118
0
      !CBB_add_u8(&key_bitstring, 0 /* padding */) ||
119
0
      !BN_marshal_asn1(&key_bitstring, dsa->pub_key) ||
120
0
      !CBB_flush(out)) {
121
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
122
0
    return 0;
123
0
  }
124
125
0
  return 1;
126
0
}
127
128
0
static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) {
129
  // See PKCS#11, v2.40, section 2.5.
130
131
  // Decode parameters.
132
0
  BN_CTX *ctx = NULL;
133
0
  DSA *dsa = DSA_parse_parameters(params);
134
0
  if (dsa == NULL || CBS_len(params) != 0) {
135
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
136
0
    goto err;
137
0
  }
138
139
0
  dsa->priv_key = BN_new();
140
0
  if (dsa->priv_key == NULL) {
141
0
    goto err;
142
0
  }
143
0
  if (!BN_parse_asn1_unsigned(key, dsa->priv_key) ||
144
0
      CBS_len(key) != 0) {
145
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
146
0
    goto err;
147
0
  }
148
149
  // To avoid DoS attacks when importing private keys, check bounds on |dsa|.
150
  // This bounds |dsa->priv_key| against |dsa->q| and bounds |dsa->q|'s bit
151
  // width.
152
0
  if (!dsa_check_key(dsa)) {
153
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
154
0
    goto err;
155
0
  }
156
157
  // Calculate the public key.
158
0
  ctx = BN_CTX_new();
159
0
  dsa->pub_key = BN_new();
160
0
  if (ctx == NULL || dsa->pub_key == NULL ||
161
0
      !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p,
162
0
                                 ctx, NULL)) {
163
0
    goto err;
164
0
  }
165
166
0
  BN_CTX_free(ctx);
167
0
  EVP_PKEY_assign_DSA(out, dsa);
168
0
  return 1;
169
170
0
err:
171
0
  BN_CTX_free(ctx);
172
0
  DSA_free(dsa);
173
0
  return 0;
174
0
}
175
176
0
static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) {
177
0
  const DSA *dsa = key->pkey;
178
0
  if (dsa == NULL || dsa->priv_key == NULL) {
179
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
180
0
    return 0;
181
0
  }
182
183
  // See PKCS#11, v2.40, section 2.5.
184
0
  CBB pkcs8, algorithm, oid, private_key;
185
0
  if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) ||
186
0
      !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) ||
187
0
      !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
188
0
      !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
189
0
      !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) ||
190
0
      !DSA_marshal_parameters(&algorithm, dsa) ||
191
0
      !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) ||
192
0
      !BN_marshal_asn1(&private_key, dsa->priv_key) ||
193
0
      !CBB_flush(out)) {
194
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR);
195
0
    return 0;
196
0
  }
197
198
0
  return 1;
199
0
}
200
201
0
static int int_dsa_size(const EVP_PKEY *pkey) {
202
0
  const DSA *dsa = pkey->pkey;
203
0
  return DSA_size(dsa);
204
0
}
205
206
0
static int dsa_bits(const EVP_PKEY *pkey) {
207
0
  const DSA *dsa = pkey->pkey;
208
0
  return BN_num_bits(DSA_get0_p(dsa));
209
0
}
210
211
0
static int dsa_missing_parameters(const EVP_PKEY *pkey) {
212
0
  const DSA *dsa = pkey->pkey;
213
0
  if (DSA_get0_p(dsa) == NULL || DSA_get0_q(dsa) == NULL ||
214
0
      DSA_get0_g(dsa) == NULL) {
215
0
    return 1;
216
0
  }
217
0
  return 0;
218
0
}
219
220
0
static int dup_bn_into(BIGNUM **out, BIGNUM *src) {
221
0
  BIGNUM *a;
222
223
0
  a = BN_dup(src);
224
0
  if (a == NULL) {
225
0
    return 0;
226
0
  }
227
0
  BN_free(*out);
228
0
  *out = a;
229
230
0
  return 1;
231
0
}
232
233
0
static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
234
0
  DSA *to_dsa = to->pkey;
235
0
  const DSA *from_dsa = from->pkey;
236
0
  if (!dup_bn_into(&to_dsa->p, from_dsa->p) ||
237
0
      !dup_bn_into(&to_dsa->q, from_dsa->q) ||
238
0
      !dup_bn_into(&to_dsa->g, from_dsa->g)) {
239
0
    return 0;
240
0
  }
241
242
0
  return 1;
243
0
}
244
245
0
static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
246
0
  const DSA *a_dsa = a->pkey;
247
0
  const DSA *b_dsa = b->pkey;
248
0
  return BN_cmp(DSA_get0_p(a_dsa), DSA_get0_p(b_dsa)) == 0 &&
249
0
         BN_cmp(DSA_get0_q(a_dsa), DSA_get0_q(b_dsa)) == 0 &&
250
0
         BN_cmp(DSA_get0_g(a_dsa), DSA_get0_g(b_dsa)) == 0;
251
0
}
252
253
0
static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
254
0
  const DSA *a_dsa = a->pkey;
255
0
  const DSA *b_dsa = b->pkey;
256
0
  return BN_cmp(DSA_get0_pub_key(b_dsa), DSA_get0_pub_key(a_dsa)) == 0;
257
0
}
258
259
0
static void int_dsa_free(EVP_PKEY *pkey) {
260
0
  DSA_free(pkey->pkey);
261
0
  pkey->pkey = NULL;
262
0
}
263
264
const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
265
    EVP_PKEY_DSA,
266
    // 1.2.840.10040.4.1
267
    {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01},
268
    7,
269
270
    /*pkey_method=*/NULL,
271
272
    dsa_pub_decode,
273
    dsa_pub_encode,
274
    dsa_pub_cmp,
275
276
    dsa_priv_decode,
277
    dsa_priv_encode,
278
279
    /*set_priv_raw=*/NULL,
280
    /*set_pub_raw=*/NULL,
281
    /*get_priv_raw=*/NULL,
282
    /*get_pub_raw=*/NULL,
283
    /*set1_tls_encodedpoint=*/NULL,
284
    /*get1_tls_encodedpoint=*/NULL,
285
286
    /*pkey_opaque=*/NULL,
287
288
    int_dsa_size,
289
    dsa_bits,
290
291
    dsa_missing_parameters,
292
    dsa_copy_parameters,
293
    dsa_cmp_parameters,
294
295
    int_dsa_free,
296
};
297
298
0
int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) {
299
  // BoringSSL does not support DSA in |EVP_PKEY_CTX|.
300
0
  OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
301
0
  return 0;
302
0
}
303
304
0
int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, int qbits) {
305
  // BoringSSL does not support DSA in |EVP_PKEY_CTX|.
306
0
  OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
307
0
  return 0;
308
0
}
309
310
0
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) {
311
0
  if (EVP_PKEY_assign_DSA(pkey, key)) {
312
0
    DSA_up_ref(key);
313
0
    return 1;
314
0
  }
315
0
  return 0;
316
0
}
317
318
0
int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) {
319
0
  evp_pkey_set_method(pkey, &dsa_asn1_meth);
320
0
  pkey->pkey = key;
321
0
  return key != NULL;
322
0
}
323
324
0
DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) {
325
0
  if (pkey->type != EVP_PKEY_DSA) {
326
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY);
327
0
    return NULL;
328
0
  }
329
0
  return pkey->pkey;
330
0
}
331
332
0
DSA *EVP_PKEY_get1_DSA(const EVP_PKEY *pkey) {
333
0
  DSA *dsa = EVP_PKEY_get0_DSA(pkey);
334
0
  if (dsa != NULL) {
335
0
    DSA_up_ref(dsa);
336
0
  }
337
0
  return dsa;
338
0
}