Coverage Report

Created: 2026-06-28 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/boringssl/crypto/evp/evp_asn1.cc
Line
Count
Source
1
// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include <openssl/evp.h>
16
17
#include <string.h>
18
19
#include <array>
20
21
#include <openssl/bytestring.h>
22
#include <openssl/dsa.h>
23
#include <openssl/ec_key.h>
24
#include <openssl/err.h>
25
#include <openssl/rsa.h>
26
#include <openssl/span.h>
27
28
#include "../bytestring/internal.h"
29
#include "../internal.h"
30
#include "../mem_internal.h"
31
#include "internal.h"
32
33
34
using namespace bssl;
35
36
EVP_PKEY *EVP_PKEY_from_subject_public_key_info(const uint8_t *in, size_t len,
37
                                                const EVP_PKEY_ALG *const *algs,
38
240k
                                                size_t num_algs) {
39
  // Parse the SubjectPublicKeyInfo.
40
240k
  CBS cbs, spki, algorithm, oid, key;
41
240k
  CBS_init(&cbs, in, len);
42
240k
  if (!CBS_get_asn1(&cbs, &spki, CBS_ASN1_SEQUENCE) ||
43
240k
      !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
44
240k
      !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
45
240k
      !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) ||
46
240k
      CBS_len(&spki) != 0 ||  //
47
240k
      CBS_len(&cbs) != 0) {
48
192
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
49
192
    return nullptr;
50
192
  }
51
52
240k
  UniquePtr<EvpPkey> ret(FromOpaque(EVP_PKEY_new()));
53
240k
  if (ret == nullptr) {
54
0
    return nullptr;
55
0
  }
56
1.16M
  for (const EVP_PKEY_ALG *alg : Span(algs, num_algs)) {
57
1.16M
    if (alg->method->pub_decode == nullptr ||
58
1.16M
        Span(alg->method->oid, alg->method->oid_len) != oid) {
59
889k
      continue;
60
889k
    }
61
    // Every key type we support encodes the key as a byte string with the same
62
    // conversion to BIT STRING, so perform that common conversion ahead of
63
    // time, but only after the OID is recognized as supported.
64
272k
    CBS key_bytes = key;
65
272k
    uint8_t padding;
66
272k
    if (!CBS_get_u8(&key_bytes, &padding) || padding != 0) {
67
129
      OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
68
129
      return nullptr;
69
129
    }
70
272k
    CBS params = algorithm;
71
272k
    switch (alg->method->pub_decode(alg, ret.get(), &params, &key_bytes)) {
72
56.8k
      case evp_decode_error:
73
56.8k
        return nullptr;
74
156k
      case evp_decode_ok:
75
156k
        return ret.release();
76
58.4k
      case evp_decode_unsupported:
77
        // Continue trying other algorithms.
78
58.4k
        break;
79
272k
    }
80
272k
  }
81
82
26.4k
  OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
83
26.4k
  return nullptr;
84
240k
}
85
86
3.24k
int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) {
87
3.24k
  auto *impl = FromOpaque(key);
88
3.24k
  if (impl->ameth == nullptr || impl->ameth->pub_encode == nullptr) {
89
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
90
0
    return 0;
91
0
  }
92
3.24k
  if (impl->pkey == nullptr) {
93
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET);
94
0
    return 0;
95
0
  }
96
97
3.24k
  return impl->ameth->pub_encode(cbb, impl);
98
3.24k
}
99
100
EVP_PKEY *EVP_PKEY_from_private_key_info(const uint8_t *in, size_t len,
101
                                         const EVP_PKEY_ALG *const *algs,
102
17.6k
                                         size_t num_algs) {
103
  // Parse the PrivateKeyInfo.
104
17.6k
  CBS cbs, pkcs8, oid, algorithm, key;
105
17.6k
  uint64_t version;
106
17.6k
  CBS_init(&cbs, in, len);
107
17.6k
  if (!CBS_get_asn1(&cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
108
17.6k
      !CBS_get_asn1_uint64(&pkcs8, &version) || version != 0 ||
109
12.2k
      !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
110
10.0k
      !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
111
10.0k
      !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING) ||
112
      // A PrivateKeyInfo ends with a SET of Attributes which we ignore.
113
9.99k
      CBS_len(&cbs) != 0) {
114
7.65k
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
115
7.65k
    return nullptr;
116
7.65k
  }
117
118
9.99k
  UniquePtr<EvpPkey> ret(FromOpaque(EVP_PKEY_new()));
119
9.99k
  if (ret == nullptr) {
120
0
    return nullptr;
121
0
  }
122
64.6k
  for (const EVP_PKEY_ALG *alg : Span(algs, num_algs)) {
123
64.6k
    if (alg->method->priv_decode == nullptr ||
124
64.6k
        Span(alg->method->oid, alg->method->oid_len) != oid) {
125
51.4k
      continue;
126
51.4k
    }
127
13.1k
    CBS params = algorithm, key_copy = key;
128
13.1k
    switch (alg->method->priv_decode(alg, ret.get(), &params, &key_copy)) {
129
6.07k
      case evp_decode_error:
130
6.07k
        return nullptr;
131
3.23k
      case evp_decode_ok:
132
3.23k
        return ret.release();
133
3.85k
      case evp_decode_unsupported:
134
        // Continue trying other algorithms.
135
3.85k
        break;
136
13.1k
    }
137
13.1k
  }
138
139
685
  OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
140
685
  return nullptr;
141
9.99k
}
142
143
2.72k
int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) {
144
2.72k
  auto *impl = FromOpaque(key);
145
2.72k
  if (impl->ameth == nullptr || impl->ameth->priv_encode == nullptr) {
146
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
147
0
    return 0;
148
0
  }
149
2.72k
  if (impl->pkey == nullptr) {
150
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET);
151
0
    return 0;
152
0
  }
153
154
2.72k
  return impl->ameth->priv_encode(cbb, impl);
155
2.72k
}
156
157
2.63k
EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
158
2.63k
  CBS elem;
159
2.63k
  if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) {
160
529
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
161
529
    return nullptr;
162
529
  }
163
164
2.10k
  auto algs = GetDefaultEVPAlgorithms();
165
2.10k
  return EVP_PKEY_from_subject_public_key_info(CBS_data(&elem), CBS_len(&elem),
166
2.10k
                                               algs.data(), algs.size());
167
2.63k
}
168
169
19.9k
EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
170
19.9k
  CBS elem;
171
19.9k
  if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) {
172
2.24k
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
173
2.24k
    return nullptr;
174
2.24k
  }
175
176
17.6k
  auto algs = GetDefaultEVPAlgorithms();
177
17.6k
  return EVP_PKEY_from_private_key_info(CBS_data(&elem), CBS_len(&elem),
178
17.6k
                                        algs.data(), algs.size());
179
19.9k
}
180
181
4.48k
static bssl::UniquePtr<EVP_PKEY> old_priv_decode(CBS *cbs, int type) {
182
4.48k
  UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
183
4.48k
  if (ret == nullptr) {
184
0
    return nullptr;
185
0
  }
186
187
4.48k
  switch (type) {
188
1.94k
    case EVP_PKEY_EC: {
189
1.94k
      UniquePtr<EC_KEY> ec_key(EC_KEY_parse_private_key(cbs, nullptr));
190
1.94k
      if (ec_key == nullptr) {
191
1.94k
        return nullptr;
192
1.94k
      }
193
1
      EVP_PKEY_assign_EC_KEY(ret.get(), ec_key.release());
194
1
      return ret;
195
1.94k
    }
196
615
    case EVP_PKEY_DSA: {
197
615
      UniquePtr<DSA> dsa(DSA_parse_private_key(cbs));
198
615
      if (dsa == nullptr) {
199
609
        return nullptr;
200
609
      }
201
6
      EVP_PKEY_assign_DSA(ret.get(), dsa.release());
202
6
      return ret;
203
615
    }
204
1.93k
    case EVP_PKEY_RSA: {
205
1.93k
      UniquePtr<RSA> rsa(RSA_parse_private_key(cbs));
206
1.93k
      if (rsa == nullptr) {
207
1.92k
        return nullptr;
208
1.92k
      }
209
1
      EVP_PKEY_assign_RSA(ret.get(), rsa.release());
210
1
      return ret;
211
1.93k
    }
212
0
    default:
213
0
      OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
214
0
      return nullptr;
215
4.48k
  }
216
4.48k
}
217
218
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
219
4.48k
                         long len) {
220
4.48k
  return D2IFromCBS(out, inp, len, [&](CBS *cbs) -> UniquePtr<EVP_PKEY> {
221
    // Parse with the legacy format.
222
4.48k
    CBS copy = *cbs;
223
4.48k
    UniquePtr<EVP_PKEY> ret = old_priv_decode(cbs, type);
224
4.48k
    if (ret == nullptr) {
225
      // Try again with PKCS#8.
226
4.48k
      ERR_clear_error();
227
4.48k
      *cbs = copy;
228
4.48k
      ret.reset(EVP_parse_private_key(cbs));
229
4.48k
      if (ret == nullptr) {
230
4.48k
        return nullptr;
231
4.48k
      }
232
0
      if (EVP_PKEY_id(ret.get()) != type) {
233
0
        OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
234
0
        return nullptr;
235
0
      }
236
0
    }
237
8
    return ret;
238
4.48k
  });
239
4.48k
}
240
241
// num_elements parses one SEQUENCE from `in` and returns the number of elements
242
// in it. On parse error, it returns zero.
243
4.48k
static size_t num_elements(const uint8_t *in, size_t in_len) {
244
4.48k
  CBS cbs, sequence;
245
4.48k
  CBS_init(&cbs, in, (size_t)in_len);
246
247
4.48k
  if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) {
248
505
    return 0;
249
505
  }
250
251
3.98k
  size_t count = 0;
252
24.2k
  while (CBS_len(&sequence) > 0) {
253
20.5k
    if (!CBS_get_any_asn1_element(&sequence, nullptr, nullptr, nullptr)) {
254
347
      return 0;
255
347
    }
256
257
20.2k
    count++;
258
20.2k
  }
259
260
3.63k
  return count;
261
3.98k
}
262
263
4.98k
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
264
4.98k
  if (len < 0) {
265
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
266
0
    return nullptr;
267
0
  }
268
269
  // Parse the input as a PKCS#8 PrivateKeyInfo.
270
4.98k
  CBS cbs;
271
4.98k
  CBS_init(&cbs, *inp, (size_t)len);
272
4.98k
  EVP_PKEY *ret = EVP_parse_private_key(&cbs);
273
4.98k
  if (ret != nullptr) {
274
493
    if (out != nullptr) {
275
0
      EVP_PKEY_free(*out);
276
0
      *out = ret;
277
0
    }
278
493
    *inp = CBS_data(&cbs);
279
493
    return ret;
280
493
  }
281
4.48k
  ERR_clear_error();
282
283
  // Count the elements to determine the legacy key format.
284
4.48k
  switch (num_elements(*inp, (size_t)len)) {
285
1.94k
    case 4:
286
1.94k
      return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len);
287
288
615
    case 6:
289
615
      return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len);
290
291
1.93k
    default:
292
1.93k
      return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len);
293
4.48k
  }
294
4.48k
}
295
296
0
int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) {
297
0
  switch (EVP_PKEY_id(key)) {
298
0
    case EVP_PKEY_RSA:
299
0
      return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(key), outp);
300
0
    case EVP_PKEY_DSA:
301
0
      return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(key), outp);
302
0
    case EVP_PKEY_EC:
303
0
      return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(key), outp);
304
0
    default:
305
0
      OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
306
0
      return -1;
307
0
  }
308
0
}
309
310
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, const uint8_t **inp,
311
0
                        long len) {
312
0
  return D2IFromCBS(out, inp, len, [&](CBS *cbs) -> UniquePtr<EVP_PKEY> {
313
0
    UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
314
0
    if (ret == nullptr) {
315
0
      return nullptr;
316
0
    }
317
0
    switch (type) {
318
0
      case EVP_PKEY_RSA: {
319
0
        UniquePtr<RSA> rsa(RSA_parse_public_key(cbs));
320
0
        if (rsa == nullptr) {
321
0
          return nullptr;
322
0
        }
323
0
        EVP_PKEY_assign_RSA(ret.get(), rsa.release());
324
0
        return ret;
325
0
      }
326
327
      // Unlike OpenSSL, we do not support EC keys with this API. The raw EC
328
      // public key serialization requires knowing the group. In OpenSSL,
329
      // calling this function with `EVP_PKEY_EC` and setting `out` to
330
      // nullptr does not work. It requires `*out` to include a
331
      // partially-initialized `EVP_PKEY` to extract the group.
332
0
      default:
333
0
        OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
334
0
        return nullptr;
335
0
    }
336
0
  });
337
0
}
338
339
0
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **out, const uint8_t **inp, long len) {
340
0
  return D2IFromCBS(out, inp, len, EVP_parse_public_key);
341
0
}
342
343
0
int i2d_PUBKEY(const EVP_PKEY *pkey, uint8_t **outp) {
344
0
  if (pkey == nullptr) {
345
0
    return 0;
346
0
  }
347
0
  return I2DFromCBB(
348
0
      /*initial_capacity=*/128, outp,
349
0
      [&](CBB *cbb) -> bool { return EVP_marshal_public_key(cbb, pkey); });
350
0
}
351
352
static bssl::UniquePtr<EVP_PKEY> parse_spki(
353
0
    CBS *cbs, Span<const EVP_PKEY_ALG *const> algs) {
354
0
  CBS spki;
355
0
  if (!CBS_get_asn1_element(cbs, &spki, CBS_ASN1_SEQUENCE)) {
356
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
357
0
    return nullptr;
358
0
  }
359
0
  return UniquePtr<EVP_PKEY>(EVP_PKEY_from_subject_public_key_info(
360
0
      CBS_data(&spki), CBS_len(&spki), algs.data(), algs.size()));
361
0
}
362
363
0
static bssl::UniquePtr<EVP_PKEY> parse_spki(CBS *cbs, const EVP_PKEY_ALG *alg) {
364
0
  return parse_spki(cbs, Span(&alg, 1));
365
0
}
366
367
0
RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len) {
368
0
  return D2IFromCBS(out, inp, len, [](CBS *cbs) -> UniquePtr<RSA> {
369
0
    UniquePtr<EVP_PKEY> pkey = parse_spki(cbs, EVP_pkey_rsa());
370
0
    if (pkey == nullptr) {
371
0
      return nullptr;
372
0
    }
373
0
    return UniquePtr<RSA>(EVP_PKEY_get1_RSA(pkey.get()));
374
0
  });
375
0
}
376
377
0
int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp) {
378
0
  if (rsa == nullptr) {
379
0
    return 0;
380
0
  }
381
382
0
  UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
383
0
  if (pkey == nullptr ||
384
0
      !EVP_PKEY_set1_RSA(pkey.get(), const_cast<RSA *>(rsa))) {
385
0
    return -1;
386
0
  }
387
388
0
  return i2d_PUBKEY(pkey.get(), outp);
389
0
}
390
391
0
DSA *d2i_DSA_PUBKEY(DSA **out, const uint8_t **inp, long len) {
392
0
  return D2IFromCBS(out, inp, len, [](CBS *cbs) -> UniquePtr<DSA> {
393
0
    UniquePtr<EVP_PKEY> pkey = parse_spki(cbs, EVP_pkey_dsa());
394
0
    if (pkey == nullptr) {
395
0
      return nullptr;
396
0
    }
397
0
    return UniquePtr<DSA>(EVP_PKEY_get1_DSA(pkey.get()));
398
0
  });
399
0
}
400
401
0
int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp) {
402
0
  if (dsa == nullptr) {
403
0
    return 0;
404
0
  }
405
406
0
  UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
407
0
  if (pkey == nullptr ||
408
0
      !EVP_PKEY_set1_DSA(pkey.get(), const_cast<DSA *>(dsa))) {
409
0
    return -1;
410
0
  }
411
412
0
  return i2d_PUBKEY(pkey.get(), outp);
413
0
}
414
415
0
EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, long len) {
416
0
  return D2IFromCBS(out, inp, len, [](CBS *cbs) -> UniquePtr<EC_KEY> {
417
0
    const EVP_PKEY_ALG *const algs[] = {EVP_pkey_ec_p224(), EVP_pkey_ec_p256(),
418
0
                                        EVP_pkey_ec_p384(), EVP_pkey_ec_p521()};
419
0
    UniquePtr<EVP_PKEY> pkey = parse_spki(cbs, algs);
420
0
    if (pkey == nullptr) {
421
0
      return nullptr;
422
0
    }
423
0
    return UniquePtr<EC_KEY>(EVP_PKEY_get1_EC_KEY(pkey.get()));
424
0
  });
425
0
}
426
427
0
int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp) {
428
0
  if (ec_key == nullptr) {
429
0
    return 0;
430
0
  }
431
432
0
  UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
433
0
  if (pkey == nullptr ||
434
0
      !EVP_PKEY_set1_EC_KEY(pkey.get(), const_cast<EC_KEY *>(ec_key))) {
435
0
    return -1;
436
0
  }
437
438
0
  return i2d_PUBKEY(pkey.get(), outp);
439
0
}