• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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