2 * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
11 #include "internal/cryptlib.h"
12 #include <openssl/x509v3.h>
13 #include "crypto/x509.h"
15 DEFINE_STACK_OF(ASN1_OBJECT)
17 static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b);
18 static void trtable_free(X509_TRUST *p);
20 static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags);
21 static int trust_1oid(X509_TRUST *trust, X509 *x, int flags);
22 static int trust_compat(X509_TRUST *trust, X509 *x, int flags);
24 static int obj_trust(int id, X509 *x, int flags);
25 static int (*default_trust) (int id, X509 *x, int flags) = obj_trust;
28 * WARNING: the following table should be kept in order of trust and without
29 * any gaps so we can just subtract the minimum trust value to get an index
33 static X509_TRUST trstandard[] = {
34 {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL},
35 {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth,
37 {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth,
39 {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect,
41 {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign,
43 {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign,
45 {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP,
47 {X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL}
50 #define X509_TRUST_COUNT OSSL_NELEM(trstandard)
52 static STACK_OF(X509_TRUST) *trtable = NULL;
54 static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b)
56 return (*a)->trust - (*b)->trust;
59 int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
61 int (*oldtrust) (int, X509 *, int);
62 oldtrust = default_trust;
63 default_trust = trust;
67 int X509_check_trust(X509 *x, int id, int flags)
72 /* We get this as a default value */
73 if (id == X509_TRUST_DEFAULT)
74 return obj_trust(NID_anyExtendedKeyUsage, x,
75 flags | X509_TRUST_DO_SS_COMPAT);
76 idx = X509_TRUST_get_by_id(id);
78 return default_trust(id, x, flags);
79 pt = X509_TRUST_get0(idx);
80 return pt->check_trust(pt, x, flags);
83 int X509_TRUST_get_count(void)
86 return X509_TRUST_COUNT;
87 return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT;
90 X509_TRUST *X509_TRUST_get0(int idx)
94 if (idx < (int)X509_TRUST_COUNT)
95 return trstandard + idx;
96 return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT);
99 int X509_TRUST_get_by_id(int id)
104 if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX))
105 return id - X509_TRUST_MIN;
109 idx = sk_X509_TRUST_find(trtable, &tmp);
112 return idx + X509_TRUST_COUNT;
115 int X509_TRUST_set(int *t, int trust)
117 if (X509_TRUST_get_by_id(trust) == -1) {
118 X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST);
125 int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
126 const char *name, int arg1, void *arg2)
131 * This is set according to what we change: application can't set it
133 flags &= ~X509_TRUST_DYNAMIC;
134 /* This will always be set for application modified trust entries */
135 flags |= X509_TRUST_DYNAMIC_NAME;
136 /* Get existing entry if any */
137 idx = X509_TRUST_get_by_id(id);
138 /* Need a new entry */
140 if ((trtmp = OPENSSL_malloc(sizeof(*trtmp))) == NULL) {
141 X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
144 trtmp->flags = X509_TRUST_DYNAMIC;
146 trtmp = X509_TRUST_get0(idx);
148 /* OPENSSL_free existing name if dynamic */
149 if (trtmp->flags & X509_TRUST_DYNAMIC_NAME)
150 OPENSSL_free(trtmp->name);
151 /* dup supplied name */
152 if ((trtmp->name = OPENSSL_strdup(name)) == NULL) {
153 X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
156 /* Keep the dynamic flag of existing entry */
157 trtmp->flags &= X509_TRUST_DYNAMIC;
158 /* Set all other flags */
159 trtmp->flags |= flags;
162 trtmp->check_trust = ck;
166 /* If its a new entry manage the dynamic table */
169 && (trtable = sk_X509_TRUST_new(tr_cmp)) == NULL) {
170 X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
173 if (!sk_X509_TRUST_push(trtable, trtmp)) {
174 X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE);
181 OPENSSL_free(trtmp->name);
187 static void trtable_free(X509_TRUST *p)
191 if (p->flags & X509_TRUST_DYNAMIC) {
192 if (p->flags & X509_TRUST_DYNAMIC_NAME)
193 OPENSSL_free(p->name);
198 void X509_TRUST_cleanup(void)
200 sk_X509_TRUST_pop_free(trtable, trtable_free);
204 int X509_TRUST_get_flags(const X509_TRUST *xp)
209 char *X509_TRUST_get0_name(const X509_TRUST *xp)
214 int X509_TRUST_get_trust(const X509_TRUST *xp)
219 static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags)
222 * Declare the chain verified if the desired trust OID is not rejected in
223 * any auxiliary trust info for this certificate, and the OID is either
224 * expressly trusted, or else either "anyEKU" is trusted, or the
225 * certificate is self-signed.
227 flags |= X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU;
228 return obj_trust(trust->arg1, x, flags);
231 static int trust_1oid(X509_TRUST *trust, X509 *x, int flags)
234 * Declare the chain verified only if the desired trust OID is not
235 * rejected and is expressly trusted. Neither "anyEKU" nor "compat"
236 * trust in self-signed certificates apply.
238 flags &= ~(X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU);
239 return obj_trust(trust->arg1, x, flags);
242 static int trust_compat(X509_TRUST *trust, X509 *x, int flags)
244 /* Call for side-effect of computing hash and caching extensions */
245 if (X509_check_purpose(x, -1, 0) != 1)
246 return X509_TRUST_UNTRUSTED;
247 if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && (x->ex_flags & EXFLAG_SS))
248 return X509_TRUST_TRUSTED;
250 return X509_TRUST_UNTRUSTED;
253 static int obj_trust(int id, X509 *x, int flags)
255 X509_CERT_AUX *ax = x->aux;
258 if (ax && ax->reject) {
259 for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) {
260 ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->reject, i);
261 int nid = OBJ_obj2nid(obj);
263 if (nid == id || (nid == NID_anyExtendedKeyUsage &&
264 (flags & X509_TRUST_OK_ANY_EKU)))
265 return X509_TRUST_REJECTED;
269 if (ax && ax->trust) {
270 for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) {
271 ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->trust, i);
272 int nid = OBJ_obj2nid(obj);
274 if (nid == id || (nid == NID_anyExtendedKeyUsage &&
275 (flags & X509_TRUST_OK_ANY_EKU)))
276 return X509_TRUST_TRUSTED;
279 * Reject when explicit trust EKU are set and none match.
281 * Returning untrusted is enough for for full chains that end in
282 * self-signed roots, because when explicit trust is specified it
283 * suppresses the default blanket trust of self-signed objects.
285 * But for partial chains, this is not enough, because absent a similar
286 * trust-self-signed policy, non matching EKUs are indistinguishable
287 * from lack of EKU constraints.
289 * Therefore, failure to match any trusted purpose must trigger an
292 return X509_TRUST_REJECTED;
295 if ((flags & X509_TRUST_DO_SS_COMPAT) == 0)
296 return X509_TRUST_UNTRUSTED;
299 * Not rejected, and there is no list of accepted uses, try compat.
301 return trust_compat(NULL, x, flags);