Coverage Report

Created: 2026-04-02 07:09

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
235k
                                                size_t num_algs) {
39
  // Parse the SubjectPublicKeyInfo.
40
235k
  CBS cbs, spki, algorithm, oid, key;
41
235k
  CBS_init(&cbs, in, len);
42
235k
  if (!CBS_get_asn1(&cbs, &spki, CBS_ASN1_SEQUENCE) ||
43
235k
      !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
44
234k
      !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
45
234k
      !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) ||
46
234k
      CBS_len(&spki) != 0 ||  //
47
234k
      CBS_len(&cbs) != 0) {
48
166
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
49
166
    return nullptr;
50
166
  }
51
52
234k
  UniquePtr<EvpPkey> ret(FromOpaque(EVP_PKEY_new()));
53
234k
  if (ret == nullptr) {
54
0
    return nullptr;
55
0
  }
56
1.09M
  for (const EVP_PKEY_ALG *alg : Span(algs, num_algs)) {
57
1.09M
    if (alg->method->pub_decode == nullptr ||
58
1.09M
        Span(alg->method->oid, alg->method->oid_len) != oid) {
59
825k
      continue;
60
825k
    }
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
265k
    CBS key_bytes = key;
65
265k
    uint8_t padding;
66
265k
    if (!CBS_get_u8(&key_bytes, &padding) || padding != 0) {
67
115
      OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
68
115
      return nullptr;
69
115
    }
70
265k
    CBS params = algorithm;
71
265k
    switch (alg->method->pub_decode(alg, ret.get(), &params, &key_bytes)) {
72
58.0k
      case evp_decode_error:
73
58.0k
        return nullptr;
74
148k
      case evp_decode_ok:
75
148k
        return ret.release();
76
58.0k
      case evp_decode_unsupported:
77
        // Continue trying other algorithms.
78
58.0k
        break;
79
265k
    }
80
265k
  }
81
82
27.7k
  OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
83
27.7k
  return nullptr;
84
234k
}
85
86
2.95k
int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) {
87
2.95k
  auto *impl = FromOpaque(key);
88
2.95k
  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
2.95k
  if (impl->pkey == nullptr) {
93
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET);
94
0
    return 0;
95
0
  }
96
97
2.95k
  return impl->ameth->pub_encode(cbb, impl);
98
2.95k
}
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
15.9k
                                         size_t num_algs) {
103
  // Parse the PrivateKeyInfo.
104
15.9k
  CBS cbs, pkcs8, oid, algorithm, key;
105
15.9k
  uint64_t version;
106
15.9k
  CBS_init(&cbs, in, len);
107
15.9k
  if (!CBS_get_asn1(&cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
108
15.9k
      !CBS_get_asn1_uint64(&pkcs8, &version) || version != 0 ||
109
11.0k
      !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
110
9.02k
      !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
111
8.98k
      !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING) ||
112
      // A PrivateKeyInfo ends with a SET of Attributes which we ignore.
113
8.93k
      CBS_len(&cbs) != 0) {
114
7.05k
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
115
7.05k
    return nullptr;
116
7.05k
  }
117
118
8.93k
  UniquePtr<EvpPkey> ret(FromOpaque(EVP_PKEY_new()));
119
8.93k
  if (ret == nullptr) {
120
0
    return nullptr;
121
0
  }
122
48.7k
  for (const EVP_PKEY_ALG *alg : Span(algs, num_algs)) {
123
48.7k
    if (alg->method->priv_decode == nullptr ||
124
48.7k
        Span(alg->method->oid, alg->method->oid_len) != oid) {
125
36.4k
      continue;
126
36.4k
    }
127
12.2k
    CBS params = algorithm, key_copy = key;
128
12.2k
    switch (alg->method->priv_decode(alg, ret.get(), &params, &key_copy)) {
129
5.98k
      case evp_decode_error:
130
5.98k
        return nullptr;
131
2.25k
      case evp_decode_ok:
132
2.25k
        return ret.release();
133
4.04k
      case evp_decode_unsupported:
134
        // Continue trying other algorithms.
135
4.04k
        break;
136
12.2k
    }
137
12.2k
  }
138
139
691
  OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
140
691
  return nullptr;
141
8.93k
}
142
143
1.80k
int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) {
144
1.80k
  auto *impl = FromOpaque(key);
145
1.80k
  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
1.80k
  if (impl->pkey == nullptr) {
150
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET);
151
0
    return 0;
152
0
  }
153
154
1.80k
  return impl->ameth->priv_encode(cbb, impl);
155
1.80k
}
156
157
2.57k
EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
158
2.57k
  CBS elem;
159
2.57k
  if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) {
160
539
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
161
539
    return nullptr;
162
539
  }
163
164
2.03k
  auto algs = GetDefaultEVPAlgorithms();
165
2.03k
  return EVP_PKEY_from_subject_public_key_info(CBS_data(&elem), CBS_len(&elem),
166
2.03k
                                               algs.data(), algs.size());
167
2.57k
}
168
169
18.1k
EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
170
18.1k
  CBS elem;
171
18.1k
  if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) {
172
2.17k
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
173
2.17k
    return nullptr;
174
2.17k
  }
175
176
15.9k
  auto algs = GetDefaultEVPAlgorithms();
177
15.9k
  return EVP_PKEY_from_private_key_info(CBS_data(&elem), CBS_len(&elem),
178
15.9k
                                        algs.data(), algs.size());
179
18.1k
}
180
181
4.07k
static bssl::UniquePtr<EVP_PKEY> old_priv_decode(CBS *cbs, int type) {
182
4.07k
  UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
183
4.07k
  if (ret == nullptr) {
184
0
    return nullptr;
185
0
  }
186
187
4.07k
  switch (type) {
188
1.74k
    case EVP_PKEY_EC: {
189
1.74k
      UniquePtr<EC_KEY> ec_key(EC_KEY_parse_private_key(cbs, nullptr));
190
1.74k
      if (ec_key == nullptr) {
191
1.74k
        return nullptr;
192
1.74k
      }
193
1
      EVP_PKEY_assign_EC_KEY(ret.get(), ec_key.release());
194
1
      return ret;
195
1.74k
    }
196
622
    case EVP_PKEY_DSA: {
197
622
      UniquePtr<DSA> dsa(DSA_parse_private_key(cbs));
198
622
      if (dsa == nullptr) {
199
619
        return nullptr;
200
619
      }
201
3
      EVP_PKEY_assign_DSA(ret.get(), dsa.release());
202
3
      return ret;
203
622
    }
204
1.70k
    case EVP_PKEY_RSA: {
205
1.70k
      UniquePtr<RSA> rsa(RSA_parse_private_key(cbs));
206
1.70k
      if (rsa == nullptr) {
207
1.70k
        return nullptr;
208
1.70k
      }
209
1
      EVP_PKEY_assign_RSA(ret.get(), rsa.release());
210
1
      return ret;
211
1.70k
    }
212
0
    default:
213
0
      OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
214
0
      return nullptr;
215
4.07k
  }
216
4.07k
}
217
218
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
219
4.07k
                         long len) {
220
4.07k
  return D2IFromCBS(out, inp, len, [&](CBS *cbs) -> UniquePtr<EVP_PKEY> {
221
    // Parse with the legacy format.
222
4.07k
    CBS copy = *cbs;
223
4.07k
    UniquePtr<EVP_PKEY> ret = old_priv_decode(cbs, type);
224
4.07k
    if (ret == nullptr) {
225
      // Try again with PKCS#8.
226
4.06k
      ERR_clear_error();
227
4.06k
      *cbs = copy;
228
4.06k
      ret.reset(EVP_parse_private_key(cbs));
229
4.06k
      if (ret == nullptr) {
230
4.06k
        return nullptr;
231
4.06k
      }
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
5
    return ret;
238
4.07k
  });
239
4.07k
}
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.07k
static size_t num_elements(const uint8_t *in, size_t in_len) {
244
4.07k
  CBS cbs, sequence;
245
4.07k
  CBS_init(&cbs, in, (size_t)in_len);
246
247
4.07k
  if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) {
248
454
    return 0;
249
454
  }
250
251
3.62k
  size_t count = 0;
252
22.0k
  while (CBS_len(&sequence) > 0) {
253
18.7k
    if (!CBS_get_any_asn1_element(&sequence, nullptr, nullptr, nullptr)) {
254
303
      return 0;
255
303
    }
256
257
18.4k
    count++;
258
18.4k
  }
259
260
3.31k
  return count;
261
3.62k
}
262
263
4.51k
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
264
4.51k
  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.51k
  CBS cbs;
271
4.51k
  CBS_init(&cbs, *inp, (size_t)len);
272
4.51k
  EVP_PKEY *ret = EVP_parse_private_key(&cbs);
273
4.51k
  if (ret != nullptr) {
274
436
    if (out != nullptr) {
275
0
      EVP_PKEY_free(*out);
276
0
      *out = ret;
277
0
    }
278
436
    *inp = CBS_data(&cbs);
279
436
    return ret;
280
436
  }
281
4.07k
  ERR_clear_error();
282
283
  // Count the elements to determine the legacy key format.
284
4.07k
  switch (num_elements(*inp, (size_t)len)) {
285
1.74k
    case 4:
286
1.74k
      return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len);
287
288
622
    case 6:
289
622
      return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len);
290
291
1.70k
    default:
292
1.70k
      return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len);
293
4.07k
  }
294
4.07k
}
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
}