Coverage Report

Created: 2025-09-05 06:13

/src/boringssl/crypto/x509/x_all.cc
Line
Count
Source (jump to first uncovered line)
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/x509.h>
16
17
#include <limits.h>
18
19
#include <openssl/asn1.h>
20
#include <openssl/bytestring.h>
21
#include <openssl/digest.h>
22
#include <openssl/dsa.h>
23
#include <openssl/evp.h>
24
#include <openssl/mem.h>
25
#include <openssl/rsa.h>
26
#include <openssl/span.h>
27
#include <openssl/stack.h>
28
29
#include "../asn1/internal.h"
30
#include "../internal.h"
31
#include "internal.h"
32
33
34
0
int X509_verify(X509 *x509, EVP_PKEY *pkey) {
35
0
  if (X509_ALGOR_cmp(&x509->sig_alg, &x509->tbs_sig_alg)) {
36
0
    OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH);
37
0
    return 0;
38
0
  }
39
  // This uses the cached TBSCertificate encoding, if any.
40
0
  bssl::ScopedCBB cbb;
41
0
  if (!CBB_init(cbb.get(), 128) || !x509_marshal_tbs_cert(cbb.get(), x509)) {
42
0
    return 0;
43
0
  }
44
0
  return x509_verify_signature(
45
0
      &x509->sig_alg, &x509->signature,
46
0
      bssl::Span(CBB_data(cbb.get()), CBB_len(cbb.get())), pkey);
47
0
}
48
49
0
int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) {
50
0
  return ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), req->sig_alg,
51
0
                          req->signature, req->req_info, pkey);
52
0
}
53
54
0
int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) {
55
0
  bssl::ScopedEVP_MD_CTX ctx;
56
0
  if (!EVP_DigestSignInit(ctx.get(), nullptr, md, nullptr, pkey)) {
57
0
    return 0;
58
0
  }
59
0
  return X509_sign_ctx(x, ctx.get());
60
0
}
61
62
0
int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) {
63
  // Historically, this function called |EVP_MD_CTX_cleanup| on return. Some
64
  // callers rely on this to avoid memory leaks.
65
0
  bssl::Cleanup cleanup = [&] { EVP_MD_CTX_cleanup(ctx); };
66
67
  // Fill in the two copies of AlgorithmIdentifier. Note one of these modifies
68
  // the TBSCertificate.
69
0
  if (!x509_digest_sign_algorithm(ctx, &x->tbs_sig_alg) ||
70
0
      !x509_digest_sign_algorithm(ctx, &x->sig_alg)) {
71
0
    return 0;
72
0
  }
73
74
  // Discard the cached encoding. (We just modified it.)
75
0
  CRYPTO_BUFFER_free(x->buf);
76
0
  x->buf = nullptr;
77
78
0
  bssl::ScopedCBB cbb;
79
0
  if (!CBB_init(cbb.get(), 128) || !x509_marshal_tbs_cert(cbb.get(), x)) {
80
0
    return 0;
81
0
  }
82
0
  return x509_sign_to_bit_string(
83
0
      ctx, &x->signature, bssl::Span(CBB_data(cbb.get()), CBB_len(cbb.get())));
84
0
}
85
86
0
int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) {
87
0
  asn1_encoding_clear(&x->req_info->enc);
88
0
  return ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL,
89
0
                        x->signature, x->req_info, pkey, md);
90
0
}
91
92
0
int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) {
93
0
  asn1_encoding_clear(&x->req_info->enc);
94
0
  return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL,
95
0
                            x->signature, x->req_info, ctx);
96
0
}
97
98
0
int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) {
99
0
  asn1_encoding_clear(&x->crl->enc);
100
0
  return ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg,
101
0
                        x->sig_alg, x->signature, x->crl, pkey, md);
102
0
}
103
104
0
int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) {
105
0
  asn1_encoding_clear(&x->crl->enc);
106
0
  return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg,
107
0
                            x->sig_alg, x->signature, x->crl, ctx);
108
0
}
109
110
0
int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) {
111
0
  return ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL,
112
0
                        x->signature, x->spkac, pkey, md);
113
0
}
114
115
0
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey) {
116
0
  return ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), spki->sig_algor,
117
0
                          spki->signature, spki->spkac, pkey);
118
0
}
119
120
0
X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) {
121
0
  return reinterpret_cast<X509_CRL *>(
122
0
      ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl));
123
0
}
124
125
0
int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) {
126
0
  return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl);
127
0
}
128
129
0
X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) {
130
0
  return reinterpret_cast<X509_CRL *>(
131
0
      ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl));
132
0
}
133
134
0
int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) {
135
0
  return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl);
136
0
}
137
138
0
X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) {
139
0
  return reinterpret_cast<X509_REQ *>(
140
0
      ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req));
141
0
}
142
143
0
int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) {
144
0
  return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req);
145
0
}
146
147
0
X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) {
148
0
  return reinterpret_cast<X509_REQ *>(
149
0
      ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req));
150
0
}
151
152
0
int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) {
153
0
  return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req);
154
0
}
155
156
157
#define IMPLEMENT_D2I_FP(type, name, bio_func) \
158
0
  type *name(FILE *fp, type **obj) {           \
159
0
    BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE);    \
160
0
    if (bio == NULL) {                         \
161
0
      return NULL;                             \
162
0
    }                                          \
163
0
    type *ret = bio_func(bio, obj);            \
164
0
    BIO_free(bio);                             \
165
0
    return ret;                                \
166
0
  }
Unexecuted instantiation: d2i_X509_fp
Unexecuted instantiation: d2i_RSAPrivateKey_fp
Unexecuted instantiation: d2i_RSAPublicKey_fp
Unexecuted instantiation: d2i_RSA_PUBKEY_fp
Unexecuted instantiation: d2i_DSAPrivateKey_fp
Unexecuted instantiation: d2i_DSA_PUBKEY_fp
Unexecuted instantiation: d2i_ECPrivateKey_fp
Unexecuted instantiation: d2i_EC_PUBKEY_fp
Unexecuted instantiation: d2i_PKCS8_fp
Unexecuted instantiation: d2i_PKCS8_PRIV_KEY_INFO_fp
Unexecuted instantiation: d2i_PrivateKey_fp
Unexecuted instantiation: d2i_PUBKEY_fp
167
168
#define IMPLEMENT_I2D_FP(type, name, bio_func) \
169
0
  int name(FILE *fp, type *obj) {              \
170
0
    BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE);    \
171
0
    if (bio == NULL) {                         \
172
0
      return 0;                                \
173
0
    }                                          \
174
0
    int ret = bio_func(bio, obj);              \
175
0
    BIO_free(bio);                             \
176
0
    return ret;                                \
177
0
  }
Unexecuted instantiation: i2d_X509_fp
Unexecuted instantiation: i2d_RSAPrivateKey_fp
Unexecuted instantiation: i2d_RSAPublicKey_fp
Unexecuted instantiation: i2d_RSA_PUBKEY_fp
Unexecuted instantiation: i2d_DSAPrivateKey_fp
Unexecuted instantiation: i2d_DSA_PUBKEY_fp
Unexecuted instantiation: i2d_ECPrivateKey_fp
Unexecuted instantiation: i2d_EC_PUBKEY_fp
Unexecuted instantiation: i2d_PKCS8_fp
Unexecuted instantiation: i2d_PKCS8_PRIV_KEY_INFO_fp
Unexecuted instantiation: i2d_PrivateKey_fp
Unexecuted instantiation: i2d_PUBKEY_fp
178
179
IMPLEMENT_D2I_FP(X509, d2i_X509_fp, d2i_X509_bio)
180
IMPLEMENT_I2D_FP(X509, i2d_X509_fp, i2d_X509_bio)
181
182
IMPLEMENT_D2I_FP(RSA, d2i_RSAPrivateKey_fp, d2i_RSAPrivateKey_bio)
183
IMPLEMENT_I2D_FP(RSA, i2d_RSAPrivateKey_fp, i2d_RSAPrivateKey_bio)
184
185
IMPLEMENT_D2I_FP(RSA, d2i_RSAPublicKey_fp, d2i_RSAPublicKey_bio)
186
IMPLEMENT_I2D_FP(RSA, i2d_RSAPublicKey_fp, i2d_RSAPublicKey_bio)
187
188
IMPLEMENT_D2I_FP(RSA, d2i_RSA_PUBKEY_fp, d2i_RSA_PUBKEY_bio)
189
IMPLEMENT_I2D_FP(RSA, i2d_RSA_PUBKEY_fp, i2d_RSA_PUBKEY_bio)
190
191
#define IMPLEMENT_D2I_BIO(type, name, d2i_func)         \
192
0
  type *name(BIO *bio, type **obj) {                    \
193
0
    uint8_t *data;                                      \
194
0
    size_t len;                                         \
195
0
    if (!BIO_read_asn1(bio, &data, &len, 100 * 1024)) { \
196
0
      return NULL;                                      \
197
0
    }                                                   \
198
0
    const uint8_t *ptr = data;                          \
199
0
    type *ret = d2i_func(obj, &ptr, (long)len);         \
200
0
    OPENSSL_free(data);                                 \
201
0
    return ret;                                         \
202
0
  }
Unexecuted instantiation: d2i_X509_bio
Unexecuted instantiation: d2i_RSAPrivateKey_bio
Unexecuted instantiation: d2i_RSAPublicKey_bio
Unexecuted instantiation: d2i_RSA_PUBKEY_bio
Unexecuted instantiation: d2i_DSAPrivateKey_bio
Unexecuted instantiation: d2i_DSA_PUBKEY_bio
Unexecuted instantiation: d2i_ECPrivateKey_bio
Unexecuted instantiation: d2i_EC_PUBKEY_bio
Unexecuted instantiation: d2i_PKCS8_bio
Unexecuted instantiation: d2i_PKCS8_PRIV_KEY_INFO_bio
Unexecuted instantiation: d2i_PrivateKey_bio
Unexecuted instantiation: d2i_PUBKEY_bio
Unexecuted instantiation: d2i_DHparams_bio
203
204
#define IMPLEMENT_I2D_BIO(type, name, i2d_func) \
205
0
  int name(BIO *bio, type *obj) {               \
206
0
    uint8_t *data = NULL;                       \
207
0
    int len = i2d_func(obj, &data);             \
208
0
    if (len < 0) {                              \
209
0
      return 0;                                 \
210
0
    }                                           \
211
0
    int ret = BIO_write_all(bio, data, len);    \
212
0
    OPENSSL_free(data);                         \
213
0
    return ret;                                 \
214
0
  }
Unexecuted instantiation: i2d_X509_bio
Unexecuted instantiation: i2d_RSAPrivateKey_bio
Unexecuted instantiation: i2d_RSAPublicKey_bio
Unexecuted instantiation: i2d_RSA_PUBKEY_bio
Unexecuted instantiation: i2d_DSAPrivateKey_bio
Unexecuted instantiation: i2d_DSA_PUBKEY_bio
Unexecuted instantiation: i2d_ECPrivateKey_bio
Unexecuted instantiation: i2d_EC_PUBKEY_bio
Unexecuted instantiation: i2d_PKCS8_bio
Unexecuted instantiation: i2d_PKCS8_PRIV_KEY_INFO_bio
Unexecuted instantiation: i2d_PrivateKey_bio
Unexecuted instantiation: i2d_PUBKEY_bio
Unexecuted instantiation: i2d_DHparams_bio
215
216
IMPLEMENT_D2I_BIO(X509, d2i_X509_bio, d2i_X509)
217
IMPLEMENT_I2D_BIO(X509, i2d_X509_bio, i2d_X509)
218
219
IMPLEMENT_D2I_BIO(RSA, d2i_RSAPrivateKey_bio, d2i_RSAPrivateKey)
220
IMPLEMENT_I2D_BIO(RSA, i2d_RSAPrivateKey_bio, i2d_RSAPrivateKey)
221
222
IMPLEMENT_D2I_BIO(RSA, d2i_RSAPublicKey_bio, d2i_RSAPublicKey)
223
IMPLEMENT_I2D_BIO(RSA, i2d_RSAPublicKey_bio, i2d_RSAPublicKey)
224
225
IMPLEMENT_D2I_BIO(RSA, d2i_RSA_PUBKEY_bio, d2i_RSA_PUBKEY)
226
IMPLEMENT_I2D_BIO(RSA, i2d_RSA_PUBKEY_bio, i2d_RSA_PUBKEY)
227
228
IMPLEMENT_D2I_FP(DSA, d2i_DSAPrivateKey_fp, d2i_DSAPrivateKey_bio)
229
IMPLEMENT_I2D_FP(DSA, i2d_DSAPrivateKey_fp, i2d_DSAPrivateKey_bio)
230
231
IMPLEMENT_D2I_FP(DSA, d2i_DSA_PUBKEY_fp, d2i_DSA_PUBKEY_bio)
232
IMPLEMENT_I2D_FP(DSA, i2d_DSA_PUBKEY_fp, i2d_DSA_PUBKEY_bio)
233
234
IMPLEMENT_D2I_BIO(DSA, d2i_DSAPrivateKey_bio, d2i_DSAPrivateKey)
235
IMPLEMENT_I2D_BIO(DSA, i2d_DSAPrivateKey_bio, i2d_DSAPrivateKey)
236
237
IMPLEMENT_D2I_BIO(DSA, d2i_DSA_PUBKEY_bio, d2i_DSA_PUBKEY)
238
IMPLEMENT_I2D_BIO(DSA, i2d_DSA_PUBKEY_bio, i2d_DSA_PUBKEY)
239
240
IMPLEMENT_D2I_FP(EC_KEY, d2i_ECPrivateKey_fp, d2i_ECPrivateKey_bio)
241
IMPLEMENT_I2D_FP(EC_KEY, i2d_ECPrivateKey_fp, i2d_ECPrivateKey_bio)
242
243
IMPLEMENT_D2I_FP(EC_KEY, d2i_EC_PUBKEY_fp, d2i_EC_PUBKEY_bio)
244
IMPLEMENT_I2D_FP(EC_KEY, i2d_EC_PUBKEY_fp, i2d_EC_PUBKEY_bio)
245
246
IMPLEMENT_D2I_BIO(EC_KEY, d2i_ECPrivateKey_bio, d2i_ECPrivateKey)
247
IMPLEMENT_I2D_BIO(EC_KEY, i2d_ECPrivateKey_bio, i2d_ECPrivateKey)
248
249
IMPLEMENT_D2I_BIO(EC_KEY, d2i_EC_PUBKEY_bio, d2i_EC_PUBKEY)
250
IMPLEMENT_I2D_BIO(EC_KEY, i2d_EC_PUBKEY_bio, i2d_EC_PUBKEY)
251
252
int X509_pubkey_digest(const X509 *data, const EVP_MD *type, unsigned char *md,
253
0
                       unsigned int *len) {
254
0
  ASN1_BIT_STRING *key;
255
0
  key = X509_get0_pubkey_bitstr(data);
256
0
  if (!key) {
257
0
    return 0;
258
0
  }
259
0
  return EVP_Digest(key->data, key->length, md, len, type, NULL);
260
0
}
261
262
int X509_digest(const X509 *x509, const EVP_MD *md, uint8_t *out,
263
2.20k
                unsigned *out_len) {
264
2.20k
  uint8_t *der = NULL;
265
  // TODO(https://crbug.com/boringssl/407): This function is not const-correct.
266
2.20k
  int der_len = i2d_X509((X509 *)x509, &der);
267
2.20k
  if (der_len < 0) {
268
0
    return 0;
269
0
  }
270
271
2.20k
  int ret = EVP_Digest(der, der_len, out, out_len, md, NULL);
272
2.20k
  OPENSSL_free(der);
273
2.20k
  return ret;
274
2.20k
}
275
276
int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, unsigned char *md,
277
0
                    unsigned int *len) {
278
0
  return (
279
0
      ASN1_item_digest(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len));
280
0
}
281
282
int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, unsigned char *md,
283
0
                    unsigned int *len) {
284
0
  return (
285
0
      ASN1_item_digest(ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len));
286
0
}
287
288
int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
289
0
                     unsigned char *md, unsigned int *len) {
290
0
  return (
291
0
      ASN1_item_digest(ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len));
292
0
}
293
294
IMPLEMENT_D2I_FP(X509_SIG, d2i_PKCS8_fp, d2i_PKCS8_bio)
295
IMPLEMENT_I2D_FP(X509_SIG, i2d_PKCS8_fp, i2d_PKCS8_bio)
296
297
IMPLEMENT_D2I_BIO(X509_SIG, d2i_PKCS8_bio, d2i_X509_SIG)
298
IMPLEMENT_I2D_BIO(X509_SIG, i2d_PKCS8_bio, i2d_X509_SIG)
299
300
IMPLEMENT_D2I_FP(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_fp,
301
                 d2i_PKCS8_PRIV_KEY_INFO_bio)
302
IMPLEMENT_I2D_FP(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_fp,
303
                 i2d_PKCS8_PRIV_KEY_INFO_bio)
304
305
0
int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) {
306
0
  PKCS8_PRIV_KEY_INFO *p8inf;
307
0
  int ret;
308
0
  p8inf = EVP_PKEY2PKCS8(key);
309
0
  if (!p8inf) {
310
0
    return 0;
311
0
  }
312
0
  ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf);
313
0
  PKCS8_PRIV_KEY_INFO_free(p8inf);
314
0
  return ret;
315
0
}
316
317
IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PrivateKey_fp, d2i_PrivateKey_bio)
318
IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PrivateKey_fp, i2d_PrivateKey_bio)
319
320
IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PUBKEY_fp, d2i_PUBKEY_bio)
321
IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PUBKEY_fp, i2d_PUBKEY_bio)
322
323
IMPLEMENT_D2I_BIO(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_bio,
324
                  d2i_PKCS8_PRIV_KEY_INFO)
325
IMPLEMENT_I2D_BIO(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_bio,
326
                  i2d_PKCS8_PRIV_KEY_INFO)
327
328
0
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) {
329
0
  PKCS8_PRIV_KEY_INFO *p8inf;
330
0
  int ret;
331
0
  p8inf = EVP_PKEY2PKCS8(key);
332
0
  if (!p8inf) {
333
0
    return 0;
334
0
  }
335
0
  ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
336
0
  PKCS8_PRIV_KEY_INFO_free(p8inf);
337
0
  return ret;
338
0
}
339
340
IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PrivateKey_bio, d2i_AutoPrivateKey)
341
IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PrivateKey_bio, i2d_PrivateKey)
342
343
IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PUBKEY_bio, d2i_PUBKEY)
344
IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PUBKEY_bio, i2d_PUBKEY)
345
346
IMPLEMENT_D2I_BIO(DH, d2i_DHparams_bio, d2i_DHparams)
347
IMPLEMENT_I2D_BIO(const DH, i2d_DHparams_bio, i2d_DHparams)