Coverage Report

Created: 2026-02-14 06:34

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
202k
                                                size_t num_algs) {
39
  // Parse the SubjectPublicKeyInfo.
40
202k
  CBS cbs, spki, algorithm, oid, key;
41
202k
  CBS_init(&cbs, in, len);
42
202k
  if (!CBS_get_asn1(&cbs, &spki, CBS_ASN1_SEQUENCE) ||
43
202k
      !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) ||
44
202k
      !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
45
202k
      !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) ||
46
202k
      CBS_len(&spki) != 0 ||  //
47
202k
      CBS_len(&cbs) != 0) {
48
132
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
49
132
    return nullptr;
50
132
  }
51
52
202k
  UniquePtr<EvpPkey> ret(FromOpaque(EVP_PKEY_new()));
53
202k
  if (ret == nullptr) {
54
0
    return nullptr;
55
0
  }
56
948k
  for (const EVP_PKEY_ALG *alg : Span(algs, num_algs)) {
57
948k
    if (alg->method->pub_decode == nullptr ||
58
948k
        Span(alg->method->oid, alg->method->oid_len) != oid) {
59
718k
      continue;
60
718k
    }
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
229k
    CBS key_bytes = key;
65
229k
    uint8_t padding;
66
229k
    if (!CBS_get_u8(&key_bytes, &padding) || padding != 0) {
67
112
      OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
68
112
      return nullptr;
69
112
    }
70
229k
    CBS params = algorithm;
71
229k
    switch (alg->method->pub_decode(alg, ret.get(), &params, &key_bytes)) {
72
57.5k
      case evp_decode_error:
73
57.5k
        return nullptr;
74
118k
      case evp_decode_ok:
75
118k
        return ret.release();
76
53.9k
      case evp_decode_unsupported:
77
        // Continue trying other algorithms.
78
53.9k
        break;
79
229k
    }
80
229k
  }
81
82
26.6k
  OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
83
26.6k
  return nullptr;
84
202k
}
85
86
2.53k
int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) {
87
2.53k
  auto *impl = FromOpaque(key);
88
2.53k
  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
93
2.53k
  return impl->ameth->pub_encode(cbb, impl);
94
2.53k
}
95
96
EVP_PKEY *EVP_PKEY_from_private_key_info(const uint8_t *in, size_t len,
97
                                         const EVP_PKEY_ALG *const *algs,
98
15.7k
                                         size_t num_algs) {
99
  // Parse the PrivateKeyInfo.
100
15.7k
  CBS cbs, pkcs8, oid, algorithm, key;
101
15.7k
  uint64_t version;
102
15.7k
  CBS_init(&cbs, in, len);
103
15.7k
  if (!CBS_get_asn1(&cbs, &pkcs8, CBS_ASN1_SEQUENCE) ||
104
15.7k
      !CBS_get_asn1_uint64(&pkcs8, &version) || version != 0 ||
105
10.6k
      !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) ||
106
7.97k
      !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) ||
107
7.94k
      !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING) ||
108
      // A PrivateKeyInfo ends with a SET of Attributes which we ignore.
109
7.89k
      CBS_len(&cbs) != 0) {
110
7.81k
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
111
7.81k
    return nullptr;
112
7.81k
  }
113
114
7.89k
  UniquePtr<EvpPkey> ret(FromOpaque(EVP_PKEY_new()));
115
7.89k
  if (ret == nullptr) {
116
0
    return nullptr;
117
0
  }
118
43.3k
  for (const EVP_PKEY_ALG *alg : Span(algs, num_algs)) {
119
43.3k
    if (alg->method->priv_decode == nullptr ||
120
43.3k
        Span(alg->method->oid, alg->method->oid_len) != oid) {
121
32.4k
      continue;
122
32.4k
    }
123
10.8k
    CBS params = algorithm, key_copy = key;
124
10.8k
    switch (alg->method->priv_decode(alg, ret.get(), &params, &key_copy)) {
125
5.36k
      case evp_decode_error:
126
5.36k
        return nullptr;
127
1.94k
      case evp_decode_ok:
128
1.94k
        return ret.release();
129
3.59k
      case evp_decode_unsupported:
130
        // Continue trying other algorithms.
131
3.59k
        break;
132
10.8k
    }
133
10.8k
  }
134
135
591
  OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
136
591
  return nullptr;
137
7.89k
}
138
139
1.48k
int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) {
140
1.48k
  auto *impl = FromOpaque(key);
141
1.48k
  if (impl->ameth == nullptr || impl->ameth->priv_encode == nullptr) {
142
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
143
0
    return 0;
144
0
  }
145
146
1.48k
  return impl->ameth->priv_encode(cbb, impl);
147
1.48k
}
148
149
2.39k
EVP_PKEY *EVP_parse_public_key(CBS *cbs) {
150
2.39k
  CBS elem;
151
2.39k
  if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) {
152
510
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
153
510
    return nullptr;
154
510
  }
155
156
1.88k
  auto algs = GetDefaultEVPAlgorithms();
157
1.88k
  return EVP_PKEY_from_subject_public_key_info(CBS_data(&elem), CBS_len(&elem),
158
1.88k
                                               algs.data(), algs.size());
159
2.39k
}
160
161
17.7k
EVP_PKEY *EVP_parse_private_key(CBS *cbs) {
162
17.7k
  CBS elem;
163
17.7k
  if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) {
164
2.00k
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
165
2.00k
    return nullptr;
166
2.00k
  }
167
168
15.7k
  auto algs = GetDefaultEVPAlgorithms();
169
15.7k
  return EVP_PKEY_from_private_key_info(CBS_data(&elem), CBS_len(&elem),
170
15.7k
                                        algs.data(), algs.size());
171
17.7k
}
172
173
4.49k
static bssl::UniquePtr<EVP_PKEY> old_priv_decode(CBS *cbs, int type) {
174
4.49k
  UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
175
4.49k
  if (ret == nullptr) {
176
0
    return nullptr;
177
0
  }
178
179
4.49k
  switch (type) {
180
1.83k
    case EVP_PKEY_EC: {
181
1.83k
      UniquePtr<EC_KEY> ec_key(EC_KEY_parse_private_key(cbs, nullptr));
182
1.83k
      if (ec_key == nullptr) {
183
1.83k
        return nullptr;
184
1.83k
      }
185
1
      EVP_PKEY_assign_EC_KEY(ret.get(), ec_key.release());
186
1
      return ret;
187
1.83k
    }
188
665
    case EVP_PKEY_DSA: {
189
665
      UniquePtr<DSA> dsa(DSA_parse_private_key(cbs));
190
665
      if (dsa == nullptr) {
191
662
        return nullptr;
192
662
      }
193
3
      EVP_PKEY_assign_DSA(ret.get(), dsa.release());
194
3
      return ret;
195
665
    }
196
1.99k
    case EVP_PKEY_RSA: {
197
1.99k
      UniquePtr<RSA> rsa(RSA_parse_private_key(cbs));
198
1.99k
      if (rsa == nullptr) {
199
1.99k
        return nullptr;
200
1.99k
      }
201
1
      EVP_PKEY_assign_RSA(ret.get(), rsa.release());
202
1
      return ret;
203
1.99k
    }
204
0
    default:
205
0
      OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
206
0
      return nullptr;
207
4.49k
  }
208
4.49k
}
209
210
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
211
4.49k
                         long len) {
212
4.49k
  return D2IFromCBS(out, inp, len, [&](CBS *cbs) -> UniquePtr<EVP_PKEY> {
213
    // Parse with the legacy format.
214
4.49k
    CBS copy = *cbs;
215
4.49k
    UniquePtr<EVP_PKEY> ret = old_priv_decode(cbs, type);
216
4.49k
    if (ret == nullptr) {
217
      // Try again with PKCS#8.
218
4.48k
      ERR_clear_error();
219
4.48k
      *cbs = copy;
220
4.48k
      ret.reset(EVP_parse_private_key(cbs));
221
4.48k
      if (ret == nullptr) {
222
4.48k
        return nullptr;
223
4.48k
      }
224
0
      if (EVP_PKEY_id(ret.get()) != type) {
225
0
        OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
226
0
        return nullptr;
227
0
      }
228
0
    }
229
5
    return ret;
230
4.49k
  });
231
4.49k
}
232
233
// num_elements parses one SEQUENCE from |in| and returns the number of elements
234
// in it. On parse error, it returns zero.
235
4.49k
static size_t num_elements(const uint8_t *in, size_t in_len) {
236
4.49k
  CBS cbs, sequence;
237
4.49k
  CBS_init(&cbs, in, (size_t)in_len);
238
239
4.49k
  if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) {
240
454
    return 0;
241
454
  }
242
243
4.03k
  size_t count = 0;
244
25.6k
  while (CBS_len(&sequence) > 0) {
245
21.8k
    if (!CBS_get_any_asn1_element(&sequence, nullptr, nullptr, nullptr)) {
246
306
      return 0;
247
306
    }
248
249
21.5k
    count++;
250
21.5k
  }
251
252
3.73k
  return count;
253
4.03k
}
254
255
4.92k
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
256
4.92k
  if (len < 0) {
257
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
258
0
    return nullptr;
259
0
  }
260
261
  // Parse the input as a PKCS#8 PrivateKeyInfo.
262
4.92k
  CBS cbs;
263
4.92k
  CBS_init(&cbs, *inp, (size_t)len);
264
4.92k
  EVP_PKEY *ret = EVP_parse_private_key(&cbs);
265
4.92k
  if (ret != nullptr) {
266
436
    if (out != nullptr) {
267
0
      EVP_PKEY_free(*out);
268
0
      *out = ret;
269
0
    }
270
436
    *inp = CBS_data(&cbs);
271
436
    return ret;
272
436
  }
273
4.49k
  ERR_clear_error();
274
275
  // Count the elements to determine the legacy key format.
276
4.49k
  switch (num_elements(*inp, (size_t)len)) {
277
1.83k
    case 4:
278
1.83k
      return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len);
279
280
665
    case 6:
281
665
      return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len);
282
283
1.99k
    default:
284
1.99k
      return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len);
285
4.49k
  }
286
4.49k
}
287
288
0
int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) {
289
0
  switch (EVP_PKEY_id(key)) {
290
0
    case EVP_PKEY_RSA:
291
0
      return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(key), outp);
292
0
    case EVP_PKEY_DSA:
293
0
      return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(key), outp);
294
0
    case EVP_PKEY_EC:
295
0
      return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(key), outp);
296
0
    default:
297
0
      OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
298
0
      return -1;
299
0
  }
300
0
}
301
302
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, const uint8_t **inp,
303
0
                        long len) {
304
0
  return D2IFromCBS(out, inp, len, [&](CBS *cbs) -> UniquePtr<EVP_PKEY> {
305
0
    UniquePtr<EVP_PKEY> ret(EVP_PKEY_new());
306
0
    if (ret == nullptr) {
307
0
      return nullptr;
308
0
    }
309
0
    switch (type) {
310
0
      case EVP_PKEY_RSA: {
311
0
        UniquePtr<RSA> rsa(RSA_parse_public_key(cbs));
312
0
        if (rsa == nullptr) {
313
0
          return nullptr;
314
0
        }
315
0
        EVP_PKEY_assign_RSA(ret.get(), rsa.release());
316
0
        return ret;
317
0
      }
318
319
      // Unlike OpenSSL, we do not support EC keys with this API. The raw EC
320
      // public key serialization requires knowing the group. In OpenSSL,
321
      // calling this function with |EVP_PKEY_EC| and setting |out| to
322
      // nullptr does not work. It requires |*out| to include a
323
      // partially-initialized |EVP_PKEY| to extract the group.
324
0
      default:
325
0
        OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
326
0
        return nullptr;
327
0
    }
328
0
  });
329
0
}
330
331
0
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **out, const uint8_t **inp, long len) {
332
0
  return D2IFromCBS(out, inp, len, EVP_parse_public_key);
333
0
}
334
335
0
int i2d_PUBKEY(const EVP_PKEY *pkey, uint8_t **outp) {
336
0
  if (pkey == nullptr) {
337
0
    return 0;
338
0
  }
339
0
  return I2DFromCBB(
340
0
      /*initial_capacity=*/128, outp,
341
0
      [&](CBB *cbb) -> bool { return EVP_marshal_public_key(cbb, pkey); });
342
0
}
343
344
static bssl::UniquePtr<EVP_PKEY> parse_spki(
345
0
    CBS *cbs, Span<const EVP_PKEY_ALG *const> algs) {
346
0
  CBS spki;
347
0
  if (!CBS_get_asn1_element(cbs, &spki, CBS_ASN1_SEQUENCE)) {
348
0
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
349
0
    return nullptr;
350
0
  }
351
0
  return UniquePtr<EVP_PKEY>(EVP_PKEY_from_subject_public_key_info(
352
0
      CBS_data(&spki), CBS_len(&spki), algs.data(), algs.size()));
353
0
}
354
355
0
static bssl::UniquePtr<EVP_PKEY> parse_spki(CBS *cbs, const EVP_PKEY_ALG *alg) {
356
0
  return parse_spki(cbs, Span(&alg, 1));
357
0
}
358
359
0
RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len) {
360
0
  return D2IFromCBS(out, inp, len, [](CBS *cbs) -> UniquePtr<RSA> {
361
0
    UniquePtr<EVP_PKEY> pkey = parse_spki(cbs, EVP_pkey_rsa());
362
0
    if (pkey == nullptr) {
363
0
      return nullptr;
364
0
    }
365
0
    return UniquePtr<RSA>(EVP_PKEY_get1_RSA(pkey.get()));
366
0
  });
367
0
}
368
369
0
int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp) {
370
0
  if (rsa == nullptr) {
371
0
    return 0;
372
0
  }
373
374
0
  UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
375
0
  if (pkey == nullptr ||
376
0
      !EVP_PKEY_set1_RSA(pkey.get(), const_cast<RSA *>(rsa))) {
377
0
    return -1;
378
0
  }
379
380
0
  return i2d_PUBKEY(pkey.get(), outp);
381
0
}
382
383
0
DSA *d2i_DSA_PUBKEY(DSA **out, const uint8_t **inp, long len) {
384
0
  return D2IFromCBS(out, inp, len, [](CBS *cbs) -> UniquePtr<DSA> {
385
0
    UniquePtr<EVP_PKEY> pkey = parse_spki(cbs, EVP_pkey_dsa());
386
0
    if (pkey == nullptr) {
387
0
      return nullptr;
388
0
    }
389
0
    return UniquePtr<DSA>(EVP_PKEY_get1_DSA(pkey.get()));
390
0
  });
391
0
}
392
393
0
int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp) {
394
0
  if (dsa == nullptr) {
395
0
    return 0;
396
0
  }
397
398
0
  UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
399
0
  if (pkey == nullptr ||
400
0
      !EVP_PKEY_set1_DSA(pkey.get(), const_cast<DSA *>(dsa))) {
401
0
    return -1;
402
0
  }
403
404
0
  return i2d_PUBKEY(pkey.get(), outp);
405
0
}
406
407
0
EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, long len) {
408
0
  return D2IFromCBS(out, inp, len, [](CBS *cbs) -> UniquePtr<EC_KEY> {
409
0
    const EVP_PKEY_ALG *const algs[] = {EVP_pkey_ec_p224(), EVP_pkey_ec_p256(),
410
0
                                        EVP_pkey_ec_p384(), EVP_pkey_ec_p521()};
411
0
    UniquePtr<EVP_PKEY> pkey = parse_spki(cbs, algs);
412
0
    if (pkey == nullptr) {
413
0
      return nullptr;
414
0
    }
415
0
    return UniquePtr<EC_KEY>(EVP_PKEY_get1_EC_KEY(pkey.get()));
416
0
  });
417
0
}
418
419
0
int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp) {
420
0
  if (ec_key == nullptr) {
421
0
    return 0;
422
0
  }
423
424
0
  UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
425
0
  if (pkey == nullptr ||
426
0
      !EVP_PKEY_set1_EC_KEY(pkey.get(), const_cast<EC_KEY *>(ec_key))) {
427
0
    return -1;
428
0
  }
429
430
0
  return i2d_PUBKEY(pkey.get(), outp);
431
0
}