1 /* 2 * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved. 3 * 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 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include <openssl/x509v3.h> 13 #include "crypto/x509.h" 14 15 static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b); 16 static void trtable_free(X509_TRUST *p); 17 18 static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); 19 static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); 20 static int trust_compat(X509_TRUST *trust, X509 *x, int flags); 21 22 static int obj_trust(int id, X509 *x, int flags); 23 static int (*default_trust) (int id, X509 *x, int flags) = obj_trust; 24 25 /* 26 * WARNING: the following table should be kept in order of trust and without 27 * any gaps so we can just subtract the minimum trust value to get an index 28 * into the table 29 */ 30 31 static X509_TRUST trstandard[] = { 32 {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL}, 33 {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, 34 NULL}, 35 {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, 36 NULL}, 37 {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, 38 NULL}, 39 {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, 40 NULL}, 41 {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, 42 NULL}, 43 {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, 44 NULL}, 45 {X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL} 46 }; 47 48 #define X509_TRUST_COUNT OSSL_NELEM(trstandard) 49 50 static STACK_OF(X509_TRUST) *trtable = NULL; 51 52 static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b) 53 { 54 return (*a)->trust - (*b)->trust; 55 } 56 57 int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, 58 int) { 59 int (*oldtrust) (int, X509 *, int); 60 oldtrust = default_trust; 61 default_trust = trust; 62 return oldtrust; 63 } 64 65 int X509_check_trust(X509 *x, int id, int flags) 66 { 67 X509_TRUST *pt; 68 int idx; 69 70 /* We get this as a default value */ 71 if (id == X509_TRUST_DEFAULT) 72 return obj_trust(NID_anyExtendedKeyUsage, x, 73 flags | X509_TRUST_DO_SS_COMPAT); 74 idx = X509_TRUST_get_by_id(id); 75 if (idx < 0) 76 return default_trust(id, x, flags); 77 pt = X509_TRUST_get0(idx); 78 return pt->check_trust(pt, x, flags); 79 } 80 81 int X509_TRUST_get_count(void) 82 { 83 if (!trtable) 84 return X509_TRUST_COUNT; 85 return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; 86 } 87 88 X509_TRUST *X509_TRUST_get0(int idx) 89 { 90 if (idx < 0) 91 return NULL; 92 if (idx < (int)X509_TRUST_COUNT) 93 return trstandard + idx; 94 return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); 95 } 96 97 int X509_TRUST_get_by_id(int id) 98 { 99 X509_TRUST tmp; 100 int idx; 101 102 if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) 103 return id - X509_TRUST_MIN; 104 if (trtable == NULL) 105 return -1; 106 tmp.trust = id; 107 idx = sk_X509_TRUST_find(trtable, &tmp); 108 if (idx < 0) 109 return -1; 110 return idx + X509_TRUST_COUNT; 111 } 112 113 int X509_TRUST_set(int *t, int trust) 114 { 115 if (X509_TRUST_get_by_id(trust) < 0) { 116 ERR_raise(ERR_LIB_X509, X509_R_INVALID_TRUST); 117 return 0; 118 } 119 *t = trust; 120 return 1; 121 } 122 123 int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), 124 const char *name, int arg1, void *arg2) 125 { 126 int idx; 127 X509_TRUST *trtmp; 128 /* 129 * This is set according to what we change: application can't set it 130 */ 131 flags &= ~X509_TRUST_DYNAMIC; 132 /* This will always be set for application modified trust entries */ 133 flags |= X509_TRUST_DYNAMIC_NAME; 134 /* Get existing entry if any */ 135 idx = X509_TRUST_get_by_id(id); 136 /* Need a new entry */ 137 if (idx < 0) { 138 if ((trtmp = OPENSSL_malloc(sizeof(*trtmp))) == NULL) { 139 ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 140 return 0; 141 } 142 trtmp->flags = X509_TRUST_DYNAMIC; 143 } else 144 trtmp = X509_TRUST_get0(idx); 145 146 /* OPENSSL_free existing name if dynamic */ 147 if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) 148 OPENSSL_free(trtmp->name); 149 /* dup supplied name */ 150 if ((trtmp->name = OPENSSL_strdup(name)) == NULL) { 151 ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 152 goto err; 153 } 154 /* Keep the dynamic flag of existing entry */ 155 trtmp->flags &= X509_TRUST_DYNAMIC; 156 /* Set all other flags */ 157 trtmp->flags |= flags; 158 159 trtmp->trust = id; 160 trtmp->check_trust = ck; 161 trtmp->arg1 = arg1; 162 trtmp->arg2 = arg2; 163 164 /* If its a new entry manage the dynamic table */ 165 if (idx < 0) { 166 if (trtable == NULL 167 && (trtable = sk_X509_TRUST_new(tr_cmp)) == NULL) { 168 ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 169 goto err;; 170 } 171 if (!sk_X509_TRUST_push(trtable, trtmp)) { 172 ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 173 goto err; 174 } 175 } 176 return 1; 177 err: 178 if (idx < 0) { 179 OPENSSL_free(trtmp->name); 180 OPENSSL_free(trtmp); 181 } 182 return 0; 183 } 184 185 static void trtable_free(X509_TRUST *p) 186 { 187 if (p == NULL) 188 return; 189 if (p->flags & X509_TRUST_DYNAMIC) { 190 if (p->flags & X509_TRUST_DYNAMIC_NAME) 191 OPENSSL_free(p->name); 192 OPENSSL_free(p); 193 } 194 } 195 196 void X509_TRUST_cleanup(void) 197 { 198 sk_X509_TRUST_pop_free(trtable, trtable_free); 199 trtable = NULL; 200 } 201 202 int X509_TRUST_get_flags(const X509_TRUST *xp) 203 { 204 return xp->flags; 205 } 206 207 char *X509_TRUST_get0_name(const X509_TRUST *xp) 208 { 209 return xp->name; 210 } 211 212 int X509_TRUST_get_trust(const X509_TRUST *xp) 213 { 214 return xp->trust; 215 } 216 217 static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) 218 { 219 /* 220 * Declare the chain verified if the desired trust OID is not rejected in 221 * any auxiliary trust info for this certificate, and the OID is either 222 * expressly trusted, or else either "anyEKU" is trusted, or the 223 * certificate is self-signed and X509_TRUST_NO_SS_COMPAT is not set. 224 */ 225 flags |= X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU; 226 return obj_trust(trust->arg1, x, flags); 227 } 228 229 static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) 230 { 231 /* 232 * Declare the chain verified only if the desired trust OID is not 233 * rejected and is expressly trusted. Neither "anyEKU" nor "compat" 234 * trust in self-signed certificates apply. 235 */ 236 flags &= ~(X509_TRUST_DO_SS_COMPAT | X509_TRUST_OK_ANY_EKU); 237 return obj_trust(trust->arg1, x, flags); 238 } 239 240 static int trust_compat(X509_TRUST *trust, X509 *x, int flags) 241 { 242 /* Call for side-effect of setting EXFLAG_SS for self-signed-certs */ 243 if (X509_check_purpose(x, -1, 0) != 1) 244 return X509_TRUST_UNTRUSTED; 245 if ((flags & X509_TRUST_NO_SS_COMPAT) == 0 && (x->ex_flags & EXFLAG_SS)) 246 return X509_TRUST_TRUSTED; 247 else 248 return X509_TRUST_UNTRUSTED; 249 } 250 251 static int obj_trust(int id, X509 *x, int flags) 252 { 253 X509_CERT_AUX *ax = x->aux; 254 int i; 255 256 if (ax && ax->reject) { 257 for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { 258 ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->reject, i); 259 int nid = OBJ_obj2nid(obj); 260 261 if (nid == id || (nid == NID_anyExtendedKeyUsage && 262 (flags & X509_TRUST_OK_ANY_EKU))) 263 return X509_TRUST_REJECTED; 264 } 265 } 266 267 if (ax && ax->trust) { 268 for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { 269 ASN1_OBJECT *obj = sk_ASN1_OBJECT_value(ax->trust, i); 270 int nid = OBJ_obj2nid(obj); 271 272 if (nid == id || (nid == NID_anyExtendedKeyUsage && 273 (flags & X509_TRUST_OK_ANY_EKU))) 274 return X509_TRUST_TRUSTED; 275 } 276 /* 277 * Reject when explicit trust EKU are set and none match. 278 * 279 * Returning untrusted is enough for for full chains that end in 280 * self-signed roots, because when explicit trust is specified it 281 * suppresses the default blanket trust of self-signed objects. 282 * 283 * But for partial chains, this is not enough, because absent a similar 284 * trust-self-signed policy, non matching EKUs are indistinguishable 285 * from lack of EKU constraints. 286 * 287 * Therefore, failure to match any trusted purpose must trigger an 288 * explicit reject. 289 */ 290 return X509_TRUST_REJECTED; 291 } 292 293 if ((flags & X509_TRUST_DO_SS_COMPAT) == 0) 294 return X509_TRUST_UNTRUSTED; 295 296 /* 297 * Not rejected, and there is no list of accepted uses, try compat. 298 */ 299 return trust_compat(NULL, x, flags); 300 } 301