1 /*
2 * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <string.h>
11
12 #include <openssl/digest.h>
13 #include <openssl/err.h>
14 #include <openssl/mem.h>
15 #include <openssl/obj.h>
16 #include <openssl/thread.h>
17 #include <openssl/x509.h>
18
19 #include "../internal.h"
20 #include "internal.h"
21
22
23 struct x509_purpose_st {
24 int purpose;
25 int trust; // Default trust ID
26 int (*check_purpose)(const struct x509_purpose_st *, const X509 *, int);
27 const char *sname;
28 } /* X509_PURPOSE */;
29
30 #define V1_ROOT (EXFLAG_V1 | EXFLAG_SS)
31 #define ku_reject(x, usage) \
32 (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
33 #define xku_reject(x, usage) \
34 (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
35
36 static int check_ca(const X509 *x);
37 static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
38 int ca);
39 static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
40 int ca);
41 static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
42 int ca);
43 static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
44 int ca);
45 static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
46 int ca);
47 static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
48 int ca);
49 static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
50 int ca);
51 static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca);
52
53 // X509_TRUST_NONE is not a valid |X509_TRUST_*| constant. It is used by
54 // |X509_PURPOSE_ANY| to indicate that it has no corresponding trust type and
55 // cannot be used with |X509_STORE_CTX_set_purpose|.
56 #define X509_TRUST_NONE (-1)
57
58 static const X509_PURPOSE xstandard[] = {
59 {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, check_purpose_ssl_client,
60 "sslclient"},
61 {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, check_purpose_ssl_server,
62 "sslserver"},
63 {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER,
64 check_purpose_ns_ssl_server, "nssslserver"},
65 {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, check_purpose_smime_sign,
66 "smimesign"},
67 {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, check_purpose_smime_encrypt,
68 "smimeencrypt"},
69 {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, check_purpose_crl_sign,
70 "crlsign"},
71 {X509_PURPOSE_ANY, X509_TRUST_NONE, no_check, "any"},
72 // |X509_PURPOSE_OCSP_HELPER| performs no actual checks. OpenSSL's OCSP
73 // implementation relied on the caller performing EKU and KU checks.
74 {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, no_check, "ocsphelper"},
75 {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, check_purpose_timestamp_sign,
76 "timestampsign"},
77 };
78
X509_check_purpose(X509 * x,int id,int ca)79 int X509_check_purpose(X509 *x, int id, int ca) {
80 // This differs from OpenSSL, which uses -1 to indicate a fatal error and 0 to
81 // indicate an invalid certificate. BoringSSL uses 0 for both.
82 if (!x509v3_cache_extensions(x)) {
83 return 0;
84 }
85
86 if (id == -1) {
87 return 1;
88 }
89 const X509_PURPOSE *pt = X509_PURPOSE_get0(id);
90 if (pt == NULL) {
91 return 0;
92 }
93 // Historically, |check_purpose| implementations other than |X509_PURPOSE_ANY|
94 // called |check_ca|. This is redundant with the |X509_V_ERR_INVALID_CA|
95 // logic, but |X509_check_purpose| is public API, so we preserve this
96 // behavior.
97 if (ca && id != X509_PURPOSE_ANY && !check_ca(x)) {
98 return 0;
99 }
100 return pt->check_purpose(pt, x, ca);
101 }
102
X509_PURPOSE_get0(int id)103 const X509_PURPOSE *X509_PURPOSE_get0(int id) {
104 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(xstandard); i++) {
105 if (xstandard[i].purpose == id) {
106 return &xstandard[i];
107 }
108 }
109 return NULL;
110 }
111
X509_PURPOSE_get_by_sname(const char * sname)112 int X509_PURPOSE_get_by_sname(const char *sname) {
113 for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(xstandard); i++) {
114 if (strcmp(xstandard[i].sname, sname) == 0) {
115 return xstandard[i].purpose;
116 }
117 }
118 return -1;
119 }
120
X509_PURPOSE_get_id(const X509_PURPOSE * xp)121 int X509_PURPOSE_get_id(const X509_PURPOSE *xp) { return xp->purpose; }
122
X509_PURPOSE_get_trust(const X509_PURPOSE * xp)123 int X509_PURPOSE_get_trust(const X509_PURPOSE *xp) { return xp->trust; }
124
X509_supported_extension(const X509_EXTENSION * ex)125 int X509_supported_extension(const X509_EXTENSION *ex) {
126 int nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex));
127 return nid == NID_key_usage || //
128 nid == NID_subject_alt_name || //
129 nid == NID_basic_constraints || //
130 nid == NID_certificate_policies || //
131 nid == NID_ext_key_usage || //
132 nid == NID_policy_constraints || //
133 nid == NID_name_constraints || //
134 nid == NID_policy_mappings || //
135 nid == NID_inhibit_any_policy;
136 }
137
setup_dp(X509 * x,DIST_POINT * dp)138 static int setup_dp(X509 *x, DIST_POINT *dp) {
139 if (!dp->distpoint || (dp->distpoint->type != 1)) {
140 return 1;
141 }
142 X509_NAME *iname = NULL;
143 for (size_t i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
144 GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
145 if (gen->type == GEN_DIRNAME) {
146 iname = gen->d.directoryName;
147 break;
148 }
149 }
150 if (!iname) {
151 iname = X509_get_issuer_name(x);
152 }
153
154 return DIST_POINT_set_dpname(dp->distpoint, iname);
155 }
156
setup_crldp(X509 * x)157 static int setup_crldp(X509 *x) {
158 int j;
159 x->crldp = reinterpret_cast<STACK_OF(DIST_POINT) *>(
160 X509_get_ext_d2i(x, NID_crl_distribution_points, &j, NULL));
161 if (x->crldp == NULL && j != -1) {
162 return 0;
163 }
164 for (size_t i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
165 if (!setup_dp(x, sk_DIST_POINT_value(x->crldp, i))) {
166 return 0;
167 }
168 }
169 return 1;
170 }
171
x509v3_cache_extensions(X509 * x)172 int x509v3_cache_extensions(X509 *x) {
173 BASIC_CONSTRAINTS *bs;
174 ASN1_BIT_STRING *usage;
175 EXTENDED_KEY_USAGE *extusage;
176 size_t i;
177 int j;
178
179 CRYPTO_MUTEX_lock_read(&x->lock);
180 const int is_set = x->ex_flags & EXFLAG_SET;
181 CRYPTO_MUTEX_unlock_read(&x->lock);
182
183 if (is_set) {
184 return (x->ex_flags & EXFLAG_INVALID) == 0;
185 }
186
187 CRYPTO_MUTEX_lock_write(&x->lock);
188 if (x->ex_flags & EXFLAG_SET) {
189 CRYPTO_MUTEX_unlock_write(&x->lock);
190 return (x->ex_flags & EXFLAG_INVALID) == 0;
191 }
192
193 if (!X509_digest(x, EVP_sha256(), x->cert_hash, NULL)) {
194 x->ex_flags |= EXFLAG_INVALID;
195 }
196 // V1 should mean no extensions ...
197 if (X509_get_version(x) == X509_VERSION_1) {
198 x->ex_flags |= EXFLAG_V1;
199 }
200 // Handle basic constraints
201 if ((bs = reinterpret_cast<BASIC_CONSTRAINTS *>(
202 X509_get_ext_d2i(x, NID_basic_constraints, &j, NULL)))) {
203 if (bs->ca) {
204 x->ex_flags |= EXFLAG_CA;
205 }
206 if (bs->pathlen) {
207 if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) || !bs->ca) {
208 x->ex_flags |= EXFLAG_INVALID;
209 x->ex_pathlen = 0;
210 } else {
211 // TODO(davidben): |ASN1_INTEGER_get| returns -1 on overflow,
212 // which currently acts as if the constraint isn't present. This
213 // works (an overflowing path length constraint may as well be
214 // infinity), but Chromium's verifier simply treats values above
215 // 255 as an error.
216 x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
217 }
218 } else {
219 x->ex_pathlen = -1;
220 }
221 BASIC_CONSTRAINTS_free(bs);
222 x->ex_flags |= EXFLAG_BCONS;
223 } else if (j != -1) {
224 x->ex_flags |= EXFLAG_INVALID;
225 }
226 // Handle key usage
227 if ((usage = reinterpret_cast<ASN1_BIT_STRING *>(
228 X509_get_ext_d2i(x, NID_key_usage, &j, NULL)))) {
229 if (usage->length > 0) {
230 x->ex_kusage = usage->data[0];
231 if (usage->length > 1) {
232 x->ex_kusage |= usage->data[1] << 8;
233 }
234 } else {
235 x->ex_kusage = 0;
236 }
237 x->ex_flags |= EXFLAG_KUSAGE;
238 ASN1_BIT_STRING_free(usage);
239 } else if (j != -1) {
240 x->ex_flags |= EXFLAG_INVALID;
241 }
242 x->ex_xkusage = 0;
243 if ((extusage = reinterpret_cast<EXTENDED_KEY_USAGE *>(
244 X509_get_ext_d2i(x, NID_ext_key_usage, &j, NULL)))) {
245 x->ex_flags |= EXFLAG_XKUSAGE;
246 for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
247 switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
248 case NID_server_auth:
249 x->ex_xkusage |= XKU_SSL_SERVER;
250 break;
251
252 case NID_client_auth:
253 x->ex_xkusage |= XKU_SSL_CLIENT;
254 break;
255
256 case NID_email_protect:
257 x->ex_xkusage |= XKU_SMIME;
258 break;
259
260 case NID_code_sign:
261 x->ex_xkusage |= XKU_CODE_SIGN;
262 break;
263
264 case NID_ms_sgc:
265 case NID_ns_sgc:
266 x->ex_xkusage |= XKU_SGC;
267 break;
268
269 case NID_OCSP_sign:
270 x->ex_xkusage |= XKU_OCSP_SIGN;
271 break;
272
273 case NID_time_stamp:
274 x->ex_xkusage |= XKU_TIMESTAMP;
275 break;
276
277 case NID_dvcs:
278 x->ex_xkusage |= XKU_DVCS;
279 break;
280
281 case NID_anyExtendedKeyUsage:
282 x->ex_xkusage |= XKU_ANYEKU;
283 break;
284 }
285 }
286 sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
287 } else if (j != -1) {
288 x->ex_flags |= EXFLAG_INVALID;
289 }
290
291 x->skid = reinterpret_cast<ASN1_OCTET_STRING *>(
292 X509_get_ext_d2i(x, NID_subject_key_identifier, &j, NULL));
293 if (x->skid == NULL && j != -1) {
294 x->ex_flags |= EXFLAG_INVALID;
295 }
296 x->akid = reinterpret_cast<AUTHORITY_KEYID *>(
297 X509_get_ext_d2i(x, NID_authority_key_identifier, &j, NULL));
298 if (x->akid == NULL && j != -1) {
299 x->ex_flags |= EXFLAG_INVALID;
300 }
301 // Does subject name match issuer ?
302 if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
303 x->ex_flags |= EXFLAG_SI;
304 // If SKID matches AKID also indicate self signed
305 if (X509_check_akid(x, x->akid) == X509_V_OK &&
306 !ku_reject(x, X509v3_KU_KEY_CERT_SIGN)) {
307 x->ex_flags |= EXFLAG_SS;
308 }
309 }
310 x->altname = reinterpret_cast<STACK_OF(GENERAL_NAME) *>(
311 X509_get_ext_d2i(x, NID_subject_alt_name, &j, NULL));
312 if (x->altname == NULL && j != -1) {
313 x->ex_flags |= EXFLAG_INVALID;
314 }
315 x->nc = reinterpret_cast<NAME_CONSTRAINTS *>(
316 X509_get_ext_d2i(x, NID_name_constraints, &j, NULL));
317 if (x->nc == NULL && j != -1) {
318 x->ex_flags |= EXFLAG_INVALID;
319 }
320 if (!setup_crldp(x)) {
321 x->ex_flags |= EXFLAG_INVALID;
322 }
323
324 for (j = 0; j < X509_get_ext_count(x); j++) {
325 const X509_EXTENSION *ex = X509_get_ext(x, j);
326 if (!X509_EXTENSION_get_critical(ex)) {
327 continue;
328 }
329 if (!X509_supported_extension(ex)) {
330 x->ex_flags |= EXFLAG_CRITICAL;
331 break;
332 }
333 }
334 x->ex_flags |= EXFLAG_SET;
335
336 CRYPTO_MUTEX_unlock_write(&x->lock);
337 return (x->ex_flags & EXFLAG_INVALID) == 0;
338 }
339
340 // check_ca returns one if |x| should be considered a CA certificate and zero
341 // otherwise.
check_ca(const X509 * x)342 static int check_ca(const X509 *x) {
343 // keyUsage if present should allow cert signing
344 if (ku_reject(x, X509v3_KU_KEY_CERT_SIGN)) {
345 return 0;
346 }
347 // Version 1 certificates are considered CAs and don't have extensions.
348 if ((x->ex_flags & V1_ROOT) == V1_ROOT) {
349 return 1;
350 }
351 // Otherwise, it's only a CA if basicConstraints says so.
352 return ((x->ex_flags & EXFLAG_BCONS) && (x->ex_flags & EXFLAG_CA));
353 }
354
X509_check_ca(X509 * x)355 int X509_check_ca(X509 *x) {
356 if (!x509v3_cache_extensions(x)) {
357 return 0;
358 }
359 return check_ca(x);
360 }
361
362 // check_purpose returns one if |x| is a valid part of a certificate path for
363 // extended key usage |required_xku| and at least one of key usages in
364 // |required_kus|. |ca| indicates whether |x| is a CA or end-entity certificate.
check_purpose(const X509 * x,int ca,int required_xku,int required_kus)365 static int check_purpose(const X509 *x, int ca, int required_xku,
366 int required_kus) {
367 // Check extended key usage on the entire chain.
368 if (required_xku != 0 && xku_reject(x, required_xku)) {
369 return 0;
370 }
371
372 // Check key usages only on the end-entity certificate.
373 return ca || !ku_reject(x, required_kus);
374 }
375
check_purpose_ssl_client(const X509_PURPOSE * xp,const X509 * x,int ca)376 static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x,
377 int ca) {
378 // We need to do digital signatures or key agreement.
379 //
380 // TODO(davidben): We do not implement any TLS client certificate modes based
381 // on key agreement.
382 return check_purpose(x, ca, XKU_SSL_CLIENT,
383 X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_KEY_AGREEMENT);
384 }
385
386 // Key usage needed for TLS/SSL server: digital signature, encipherment or
387 // key agreement. The ssl code can check this more thoroughly for individual
388 // key types.
389 #define X509v3_KU_TLS \
390 (X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_KEY_ENCIPHERMENT | \
391 X509v3_KU_KEY_AGREEMENT)
392
check_purpose_ssl_server(const X509_PURPOSE * xp,const X509 * x,int ca)393 static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
394 int ca) {
395 return check_purpose(x, ca, XKU_SSL_SERVER, X509v3_KU_TLS);
396 }
397
check_purpose_ns_ssl_server(const X509_PURPOSE * xp,const X509 * x,int ca)398 static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x,
399 int ca) {
400 // We need to encipher or Netscape complains.
401 return check_purpose(x, ca, XKU_SSL_SERVER, X509v3_KU_KEY_ENCIPHERMENT);
402 }
403
check_purpose_smime_sign(const X509_PURPOSE * xp,const X509 * x,int ca)404 static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x,
405 int ca) {
406 return check_purpose(x, ca, XKU_SMIME,
407 X509v3_KU_DIGITAL_SIGNATURE | X509v3_KU_NON_REPUDIATION);
408 }
409
check_purpose_smime_encrypt(const X509_PURPOSE * xp,const X509 * x,int ca)410 static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x,
411 int ca) {
412 return check_purpose(x, ca, XKU_SMIME, X509v3_KU_KEY_ENCIPHERMENT);
413 }
414
check_purpose_crl_sign(const X509_PURPOSE * xp,const X509 * x,int ca)415 static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
416 int ca) {
417 return check_purpose(x, ca, /*required_xku=*/0, X509v3_KU_CRL_SIGN);
418 }
419
check_purpose_timestamp_sign(const X509_PURPOSE * xp,const X509 * x,int ca)420 static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
421 int ca) {
422 if (ca) {
423 return 1;
424 }
425
426 // Check the optional key usage field:
427 // if Key Usage is present, it must be one of digitalSignature
428 // and/or nonRepudiation (other values are not consistent and shall
429 // be rejected).
430 if ((x->ex_flags & EXFLAG_KUSAGE) &&
431 ((x->ex_kusage &
432 ~(X509v3_KU_NON_REPUDIATION | X509v3_KU_DIGITAL_SIGNATURE)) ||
433 !(x->ex_kusage &
434 (X509v3_KU_NON_REPUDIATION | X509v3_KU_DIGITAL_SIGNATURE)))) {
435 return 0;
436 }
437
438 // Only time stamp key usage is permitted and it's required.
439 //
440 // TODO(davidben): Should we check EKUs up the chain like the other cases?
441 if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) {
442 return 0;
443 }
444
445 // Extended Key Usage MUST be critical
446 int i_ext = X509_get_ext_by_NID(x, NID_ext_key_usage, -1);
447 if (i_ext >= 0) {
448 const X509_EXTENSION *ext = X509_get_ext(x, i_ext);
449 if (!X509_EXTENSION_get_critical(ext)) {
450 return 0;
451 }
452 }
453
454 return 1;
455 }
456
no_check(const X509_PURPOSE * xp,const X509 * x,int ca)457 static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) { return 1; }
458
X509_check_issued(X509 * issuer,X509 * subject)459 int X509_check_issued(X509 *issuer, X509 *subject) {
460 if (X509_NAME_cmp(X509_get_subject_name(issuer),
461 X509_get_issuer_name(subject))) {
462 return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
463 }
464 if (!x509v3_cache_extensions(issuer) || !x509v3_cache_extensions(subject)) {
465 return X509_V_ERR_UNSPECIFIED;
466 }
467
468 if (subject->akid) {
469 int ret = X509_check_akid(issuer, subject->akid);
470 if (ret != X509_V_OK) {
471 return ret;
472 }
473 }
474
475 if (ku_reject(issuer, X509v3_KU_KEY_CERT_SIGN)) {
476 return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
477 }
478 return X509_V_OK;
479 }
480
X509_check_akid(X509 * issuer,const AUTHORITY_KEYID * akid)481 int X509_check_akid(X509 *issuer, const AUTHORITY_KEYID *akid) {
482 if (!akid) {
483 return X509_V_OK;
484 }
485
486 // Check key ids (if present)
487 if (akid->keyid && issuer->skid &&
488 ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid)) {
489 return X509_V_ERR_AKID_SKID_MISMATCH;
490 }
491 // Check serial number
492 if (akid->serial &&
493 ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) {
494 return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
495 }
496 // Check issuer name
497 if (akid->issuer) {
498 // Ugh, for some peculiar reason AKID includes SEQUENCE OF
499 // GeneralName. So look for a DirName. There may be more than one but
500 // we only take any notice of the first.
501 GENERAL_NAMES *gens;
502 GENERAL_NAME *gen;
503 X509_NAME *nm = NULL;
504 size_t i;
505 gens = akid->issuer;
506 for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
507 gen = sk_GENERAL_NAME_value(gens, i);
508 if (gen->type == GEN_DIRNAME) {
509 nm = gen->d.dirn;
510 break;
511 }
512 }
513 if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) {
514 return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
515 }
516 }
517 return X509_V_OK;
518 }
519
X509_get_extension_flags(X509 * x)520 uint32_t X509_get_extension_flags(X509 *x) {
521 // Ignore the return value. On failure, |x->ex_flags| will include
522 // |EXFLAG_INVALID|.
523 x509v3_cache_extensions(x);
524 return x->ex_flags;
525 }
526
X509_get_key_usage(X509 * x)527 uint32_t X509_get_key_usage(X509 *x) {
528 if (!x509v3_cache_extensions(x)) {
529 return 0;
530 }
531 if (x->ex_flags & EXFLAG_KUSAGE) {
532 return x->ex_kusage;
533 }
534 // If there is no extension, key usage is unconstrained, so set all bits to
535 // one. Note that, although we use |UINT32_MAX|, |ex_kusage| only contains the
536 // first 16 bits when the extension is present.
537 return UINT32_MAX;
538 }
539
X509_get_extended_key_usage(X509 * x)540 uint32_t X509_get_extended_key_usage(X509 *x) {
541 if (!x509v3_cache_extensions(x)) {
542 return 0;
543 }
544 if (x->ex_flags & EXFLAG_XKUSAGE) {
545 return x->ex_xkusage;
546 }
547 // If there is no extension, extended key usage is unconstrained, so set all
548 // bits to one.
549 return UINT32_MAX;
550 }
551
X509_get0_subject_key_id(X509 * x509)552 const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x509) {
553 if (!x509v3_cache_extensions(x509)) {
554 return NULL;
555 }
556 return x509->skid;
557 }
558
X509_get0_authority_key_id(X509 * x509)559 const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x509) {
560 if (!x509v3_cache_extensions(x509)) {
561 return NULL;
562 }
563 return x509->akid != NULL ? x509->akid->keyid : NULL;
564 }
565
X509_get0_authority_issuer(X509 * x509)566 const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x509) {
567 if (!x509v3_cache_extensions(x509)) {
568 return NULL;
569 }
570 return x509->akid != NULL ? x509->akid->issuer : NULL;
571 }
572
X509_get0_authority_serial(X509 * x509)573 const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509) {
574 if (!x509v3_cache_extensions(x509)) {
575 return NULL;
576 }
577 return x509->akid != NULL ? x509->akid->serial : NULL;
578 }
579
X509_get_pathlen(X509 * x509)580 long X509_get_pathlen(X509 *x509) {
581 if (!x509v3_cache_extensions(x509) || (x509->ex_flags & EXFLAG_BCONS) == 0) {
582 return -1;
583 }
584 return x509->ex_pathlen;
585 }
586