Coverage Report

Created: 2023-03-26 06:22

/src/hostap/src/tls/pkcs8.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * PKCS #8 (Private-key information syntax)
3
 * Copyright (c) 2006-2009, Jouni Malinen <j@w1.fi>
4
 *
5
 * This software may be distributed under the terms of the BSD license.
6
 * See README for more details.
7
 */
8
9
#include "includes.h"
10
11
#include "common.h"
12
#include "asn1.h"
13
#include "bignum.h"
14
#include "rsa.h"
15
#include "pkcs5.h"
16
#include "pkcs8.h"
17
18
19
struct crypto_private_key * pkcs8_key_import(const u8 *buf, size_t len)
20
0
{
21
0
  struct asn1_hdr hdr;
22
0
  const u8 *pos, *end;
23
0
  struct bignum *zero;
24
0
  struct asn1_oid oid;
25
0
  char obuf[80];
26
27
  /* PKCS #8, Chapter 6 */
28
29
  /* PrivateKeyInfo ::= SEQUENCE */
30
0
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
31
0
    asn1_unexpected(&hdr,
32
0
        "PKCS #8: Does not start with PKCS #8 header (SEQUENCE)");
33
0
    return NULL;
34
0
  }
35
0
  pos = hdr.payload;
36
0
  end = pos + hdr.length;
37
38
  /* version Version (Version ::= INTEGER) */
39
0
  if (asn1_get_next(pos, end - pos, &hdr) < 0 || !asn1_is_integer(&hdr)) {
40
0
    asn1_unexpected(&hdr, "PKCS #8: Expected INTEGER");
41
0
    return NULL;
42
0
  }
43
44
0
  zero = bignum_init();
45
0
  if (zero == NULL)
46
0
    return NULL;
47
48
0
  if (bignum_set_unsigned_bin(zero, hdr.payload, hdr.length) < 0) {
49
0
    wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse INTEGER");
50
0
    bignum_deinit(zero);
51
0
    return NULL;
52
0
  }
53
0
  pos = hdr.payload + hdr.length;
54
55
0
  if (bignum_cmp_d(zero, 0) != 0) {
56
0
    wpa_printf(MSG_DEBUG, "PKCS #8: Expected zero INTEGER in the "
57
0
         "beginning of private key; not found; assume "
58
0
         "PKCS #8 not used");
59
0
    bignum_deinit(zero);
60
0
    return NULL;
61
0
  }
62
0
  bignum_deinit(zero);
63
64
  /* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
65
   * (PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier) */
66
0
  if (asn1_get_next(pos, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
67
0
    asn1_unexpected(&hdr,
68
0
        "PKCS #8: Expected SEQUENCE (AlgorithmIdentifier); assume PKCS #8 not used");
69
0
    return NULL;
70
0
  }
71
72
0
  if (asn1_get_oid(hdr.payload, hdr.length, &oid, &pos)) {
73
0
    wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse OID "
74
0
         "(algorithm); assume PKCS #8 not used");
75
0
    return NULL;
76
0
  }
77
78
0
  asn1_oid_to_str(&oid, obuf, sizeof(obuf));
79
0
  wpa_printf(MSG_DEBUG, "PKCS #8: algorithm=%s", obuf);
80
81
0
  if (oid.len != 7 ||
82
0
      oid.oid[0] != 1 /* iso */ ||
83
0
      oid.oid[1] != 2 /* member-body */ ||
84
0
      oid.oid[2] != 840 /* us */ ||
85
0
      oid.oid[3] != 113549 /* rsadsi */ ||
86
0
      oid.oid[4] != 1 /* pkcs */ ||
87
0
      oid.oid[5] != 1 /* pkcs-1 */ ||
88
0
      oid.oid[6] != 1 /* rsaEncryption */) {
89
0
    wpa_printf(MSG_DEBUG, "PKCS #8: Unsupported private key "
90
0
         "algorithm %s", obuf);
91
0
    return NULL;
92
0
  }
93
94
0
  pos = hdr.payload + hdr.length;
95
96
  /* privateKey PrivateKey (PrivateKey ::= OCTET STRING) */
97
0
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
98
0
      !asn1_is_octetstring(&hdr)) {
99
0
    asn1_unexpected(&hdr,
100
0
        "PKCS #8: Expected OCTETSTRING (privateKey)");
101
0
    return NULL;
102
0
  }
103
0
  wpa_printf(MSG_DEBUG, "PKCS #8: Try to parse RSAPrivateKey");
104
105
0
  return (struct crypto_private_key *)
106
0
    crypto_rsa_import_private_key(hdr.payload, hdr.length);
107
0
}
108
109
110
struct crypto_private_key *
111
pkcs8_enc_key_import(const u8 *buf, size_t len, const char *passwd)
112
0
{
113
0
  struct asn1_hdr hdr;
114
0
  const u8 *pos, *end, *enc_alg;
115
0
  size_t enc_alg_len;
116
0
  u8 *data;
117
0
  size_t data_len;
118
119
0
  if (passwd == NULL)
120
0
    return NULL;
121
122
  /*
123
   * PKCS #8, Chapter 7
124
   * EncryptedPrivateKeyInfo ::= SEQUENCE {
125
   *   encryptionAlgorithm EncryptionAlgorithmIdentifier,
126
   *   encryptedData EncryptedData }
127
   * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
128
   * EncryptedData ::= OCTET STRING
129
   */
130
131
0
  if (asn1_get_next(buf, len, &hdr) < 0 || !asn1_is_sequence(&hdr)) {
132
0
    asn1_unexpected(&hdr,
133
0
        "PKCS #8: Does not start with PKCS #8 header (SEQUENCE); assume encrypted PKCS #8 not used");
134
0
    return NULL;
135
0
  }
136
0
  pos = hdr.payload;
137
0
  end = pos + hdr.length;
138
139
  /* encryptionAlgorithm EncryptionAlgorithmIdentifier */
140
0
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
141
0
      !asn1_is_sequence(&hdr)) {
142
0
    asn1_unexpected(&hdr,
143
0
        "PKCS #8: Expected SEQUENCE (AlgorithmIdentifier); assume encrypted PKCS #8 not used");
144
0
    return NULL;
145
0
  }
146
0
  enc_alg = hdr.payload;
147
0
  enc_alg_len = hdr.length;
148
0
  pos = hdr.payload + hdr.length;
149
150
  /* encryptedData EncryptedData */
151
0
  if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
152
0
      !asn1_is_octetstring(&hdr)) {
153
0
    asn1_unexpected(&hdr,
154
0
        "PKCS #8: Expected OCTETSTRING (encryptedData)");
155
0
    return NULL;
156
0
  }
157
158
0
  data = pkcs5_decrypt(enc_alg, enc_alg_len, hdr.payload, hdr.length,
159
0
           passwd, &data_len);
160
0
  if (data) {
161
0
    struct crypto_private_key *key;
162
0
    key = pkcs8_key_import(data, data_len);
163
0
    os_free(data);
164
0
    return key;
165
0
  }
166
167
0
  return NULL;
168
0
}