Coverage Report

Created: 2025-11-03 06:30

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