]>
Commit | Line | Data |
---|---|---|
846e33c7 | 1 | /* |
fecb3aae | 2 | * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. |
aa8f3d76 | 3 | * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved |
675f605d | 4 | * |
2c18d164 | 5 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
846e33c7 RS |
6 | * this file except in compliance with the License. You can obtain a copy |
7 | * in the file LICENSE in the source distribution or at | |
8 | * https://www.openssl.org/source/license.html | |
ca8e5b9b | 9 | */ |
846e33c7 | 10 | |
d02b48c6 | 11 | #include <stdio.h> |
b379fe6c | 12 | #include <sys/types.h> |
17f389bb | 13 | |
677963e5 | 14 | #include "internal/nelem.h" |
68570797 | 15 | #include "internal/o_dir.h" |
ec577822 BM |
16 | #include <openssl/bio.h> |
17 | #include <openssl/pem.h> | |
6dcb100f | 18 | #include <openssl/store.h> |
bb7cd4e3 | 19 | #include <openssl/x509v3.h> |
3c27208f | 20 | #include <openssl/dh.h> |
d095b68d | 21 | #include <openssl/bn.h> |
5c4328f0 | 22 | #include <openssl/crypto.h> |
cd420b0b | 23 | #include "internal/refcount.h" |
706457b7 | 24 | #include "ssl_local.h" |
cd933ebd | 25 | #include "ssl_cert_table.h" |
c2e4e5d2 | 26 | #include "internal/thread_once.h" |
1dc35d44 | 27 | #ifndef OPENSSL_NO_POSIX_IO |
28 | # include <sys/stat.h> | |
29 | # ifdef _WIN32 | |
30 | # define stat _stat | |
31 | # endif | |
32 | #endif | |
33 | ||
34 | #ifndef S_ISDIR | |
35 | # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) | |
36 | #endif | |
d02b48c6 | 37 | |
a230b26e EK |
38 | static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, |
39 | int op, int bits, int nid, void *other, | |
0f113f3e | 40 | void *ex); |
b362ccab | 41 | |
16203f7b AG |
42 | static CRYPTO_ONCE ssl_x509_store_ctx_once = CRYPTO_ONCE_STATIC_INIT; |
43 | static volatile int ssl_x509_store_ctx_idx = -1; | |
0f113f3e | 44 | |
c2e4e5d2 | 45 | DEFINE_RUN_ONCE_STATIC(ssl_x509_store_ctx_init) |
16203f7b AG |
46 | { |
47 | ssl_x509_store_ctx_idx = X509_STORE_CTX_get_ex_new_index(0, | |
a230b26e EK |
48 | "SSL for verify callback", |
49 | NULL, NULL, NULL); | |
c2e4e5d2 | 50 | return ssl_x509_store_ctx_idx >= 0; |
16203f7b | 51 | } |
0f113f3e | 52 | |
16203f7b AG |
53 | int SSL_get_ex_data_X509_STORE_CTX_idx(void) |
54 | { | |
0f113f3e | 55 | |
c2e4e5d2 RL |
56 | if (!RUN_ONCE(&ssl_x509_store_ctx_once, ssl_x509_store_ctx_init)) |
57 | return -1; | |
0f113f3e MC |
58 | return ssl_x509_store_ctx_idx; |
59 | } | |
dfeab068 | 60 | |
ee58915c | 61 | CERT *ssl_cert_new(size_t ssl_pkey_num) |
0f113f3e | 62 | { |
ee58915c MB |
63 | CERT *ret = NULL; |
64 | ||
65 | /* Should never happen */ | |
66 | if (!ossl_assert(ssl_pkey_num >= SSL_PKEY_NUM)) | |
67 | return NULL; | |
0f113f3e | 68 | |
ee58915c | 69 | ret = OPENSSL_zalloc(sizeof(*ret)); |
e077455e | 70 | if (ret == NULL) |
16203f7b | 71 | return NULL; |
0f113f3e | 72 | |
ee58915c MB |
73 | ret->ssl_pkey_num = ssl_pkey_num; |
74 | ret->pkeys = OPENSSL_zalloc(ret->ssl_pkey_num * sizeof(CERT_PKEY)); | |
75 | if (ret->pkeys == NULL) { | |
76 | OPENSSL_free(ret); | |
77 | return NULL; | |
78 | } | |
79 | ||
d0ff28f8 | 80 | ret->key = &(ret->pkeys[SSL_PKEY_RSA]); |
0f113f3e | 81 | ret->references = 1; |
0f113f3e MC |
82 | ret->sec_cb = ssl_security_default_callback; |
83 | ret->sec_level = OPENSSL_TLS_SECURITY_LEVEL; | |
84 | ret->sec_ex = NULL; | |
16203f7b AG |
85 | ret->lock = CRYPTO_THREAD_lock_new(); |
86 | if (ret->lock == NULL) { | |
e077455e | 87 | ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); |
ee58915c | 88 | OPENSSL_free(ret->pkeys); |
16203f7b AG |
89 | OPENSSL_free(ret); |
90 | return NULL; | |
91 | } | |
92 | ||
93 | return ret; | |
0f113f3e | 94 | } |
d02b48c6 | 95 | |
ca8e5b9b | 96 | CERT *ssl_cert_dup(CERT *cert) |
0f113f3e | 97 | { |
b51bce94 | 98 | CERT *ret = OPENSSL_zalloc(sizeof(*ret)); |
ee58915c | 99 | size_t i; |
b67cb09f TS |
100 | #ifndef OPENSSL_NO_COMP_ALG |
101 | int j; | |
102 | #endif | |
0f113f3e | 103 | |
e077455e | 104 | if (ret == NULL) |
16203f7b | 105 | return NULL; |
0f113f3e | 106 | |
ee58915c MB |
107 | ret->ssl_pkey_num = cert->ssl_pkey_num; |
108 | ret->pkeys = OPENSSL_zalloc(ret->ssl_pkey_num * sizeof(CERT_PKEY)); | |
109 | if (ret->pkeys == NULL) | |
110 | return NULL; | |
111 | ||
0e04674e | 112 | ret->references = 1; |
16f8d4eb | 113 | ret->key = &ret->pkeys[cert->key - cert->pkeys]; |
16203f7b | 114 | ret->lock = CRYPTO_THREAD_lock_new(); |
aeb5b955 | 115 | if (ret->lock == NULL) { |
e077455e | 116 | ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); |
16203f7b AG |
117 | OPENSSL_free(ret); |
118 | return NULL; | |
119 | } | |
13c45372 | 120 | |
0f113f3e | 121 | if (cert->dh_tmp != NULL) { |
e2b420fd DSH |
122 | ret->dh_tmp = cert->dh_tmp; |
123 | EVP_PKEY_up_ref(ret->dh_tmp); | |
0f113f3e | 124 | } |
5b64ce89 | 125 | |
0f113f3e | 126 | ret->dh_tmp_cb = cert->dh_tmp_cb; |
13c45372 | 127 | ret->dh_tmp_auto = cert->dh_tmp_auto; |
ca8e5b9b | 128 | |
ee58915c | 129 | for (i = 0; i < ret->ssl_pkey_num; i++) { |
0f113f3e MC |
130 | CERT_PKEY *cpk = cert->pkeys + i; |
131 | CERT_PKEY *rpk = ret->pkeys + i; | |
b67cb09f | 132 | |
0f113f3e MC |
133 | if (cpk->x509 != NULL) { |
134 | rpk->x509 = cpk->x509; | |
05f0fb9f | 135 | X509_up_ref(rpk->x509); |
0f113f3e MC |
136 | } |
137 | ||
138 | if (cpk->privatekey != NULL) { | |
139 | rpk->privatekey = cpk->privatekey; | |
3aeb9348 | 140 | EVP_PKEY_up_ref(cpk->privatekey); |
0f113f3e MC |
141 | } |
142 | ||
143 | if (cpk->chain) { | |
144 | rpk->chain = X509_chain_up_ref(cpk->chain); | |
145 | if (!rpk->chain) { | |
e077455e | 146 | ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); |
0f113f3e MC |
147 | goto err; |
148 | } | |
149 | } | |
b67cb09f | 150 | if (cpk->serverinfo != NULL) { |
0f113f3e | 151 | /* Just copy everything. */ |
b67cb09f TS |
152 | rpk->serverinfo = OPENSSL_memdup(cpk->serverinfo, cpk->serverinfo_length); |
153 | if (rpk->serverinfo == NULL) | |
0f113f3e | 154 | goto err; |
b67cb09f TS |
155 | rpk->serverinfo_length = cpk->serverinfo_length; |
156 | } | |
157 | #ifndef OPENSSL_NO_COMP_ALG | |
158 | for (j = TLSEXT_comp_cert_none; j < TLSEXT_comp_cert_limit; j++) { | |
159 | if (cpk->comp_cert[j] != NULL) { | |
160 | if (!OSSL_COMP_CERT_up_ref(cpk->comp_cert[j])) | |
161 | goto err; | |
162 | rpk->comp_cert[j] = cpk->comp_cert[j]; | |
163 | } | |
0f113f3e | 164 | } |
b67cb09f | 165 | #endif |
0f113f3e MC |
166 | } |
167 | ||
76106e60 | 168 | /* Configured sigalgs copied across */ |
0f113f3e | 169 | if (cert->conf_sigalgs) { |
703bcee0 MC |
170 | ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen |
171 | * sizeof(*cert->conf_sigalgs)); | |
a71edf3b | 172 | if (ret->conf_sigalgs == NULL) |
0f113f3e | 173 | goto err; |
703bcee0 MC |
174 | memcpy(ret->conf_sigalgs, cert->conf_sigalgs, |
175 | cert->conf_sigalgslen * sizeof(*cert->conf_sigalgs)); | |
0f113f3e MC |
176 | ret->conf_sigalgslen = cert->conf_sigalgslen; |
177 | } else | |
178 | ret->conf_sigalgs = NULL; | |
179 | ||
180 | if (cert->client_sigalgs) { | |
703bcee0 MC |
181 | ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen |
182 | * sizeof(*cert->client_sigalgs)); | |
a71edf3b | 183 | if (ret->client_sigalgs == NULL) |
0f113f3e MC |
184 | goto err; |
185 | memcpy(ret->client_sigalgs, cert->client_sigalgs, | |
703bcee0 | 186 | cert->client_sigalgslen * sizeof(*cert->client_sigalgs)); |
0f113f3e MC |
187 | ret->client_sigalgslen = cert->client_sigalgslen; |
188 | } else | |
189 | ret->client_sigalgs = NULL; | |
0f113f3e | 190 | /* Copy any custom client certificate types */ |
75c13e78 DSH |
191 | if (cert->ctype) { |
192 | ret->ctype = OPENSSL_memdup(cert->ctype, cert->ctype_len); | |
193 | if (ret->ctype == NULL) | |
0f113f3e | 194 | goto err; |
75c13e78 | 195 | ret->ctype_len = cert->ctype_len; |
0f113f3e MC |
196 | } |
197 | ||
198 | ret->cert_flags = cert->cert_flags; | |
199 | ||
200 | ret->cert_cb = cert->cert_cb; | |
201 | ret->cert_cb_arg = cert->cert_cb_arg; | |
202 | ||
203 | if (cert->verify_store) { | |
c001ce33 | 204 | X509_STORE_up_ref(cert->verify_store); |
0f113f3e MC |
205 | ret->verify_store = cert->verify_store; |
206 | } | |
207 | ||
208 | if (cert->chain_store) { | |
c001ce33 | 209 | X509_STORE_up_ref(cert->chain_store); |
0f113f3e MC |
210 | ret->chain_store = cert->chain_store; |
211 | } | |
212 | ||
0f113f3e MC |
213 | ret->sec_cb = cert->sec_cb; |
214 | ret->sec_level = cert->sec_level; | |
215 | ret->sec_ex = cert->sec_ex; | |
b362ccab | 216 | |
43ae5eed | 217 | if (!custom_exts_copy(&ret->custext, &cert->custext)) |
0f113f3e | 218 | goto err; |
9076bd25 | 219 | #ifndef OPENSSL_NO_PSK |
df6da24b | 220 | if (cert->psk_identity_hint) { |
7644a9ae | 221 | ret->psk_identity_hint = OPENSSL_strdup(cert->psk_identity_hint); |
df6da24b DSH |
222 | if (ret->psk_identity_hint == NULL) |
223 | goto err; | |
224 | } | |
9076bd25 | 225 | #endif |
16203f7b | 226 | return ret; |
0f113f3e MC |
227 | |
228 | err: | |
229 | ssl_cert_free(ret); | |
9ade64de | 230 | |
0f113f3e MC |
231 | return NULL; |
232 | } | |
ca8e5b9b | 233 | |
a5ee80b9 DSH |
234 | /* Free up and clear all certificates and chains */ |
235 | ||
236 | void ssl_cert_clear_certs(CERT *c) | |
0f113f3e | 237 | { |
ee58915c | 238 | size_t i; |
b67cb09f TS |
239 | #ifndef OPENSSL_NO_COMP_ALG |
240 | int j; | |
241 | #endif | |
242 | ||
0f113f3e MC |
243 | if (c == NULL) |
244 | return; | |
ee58915c | 245 | for (i = 0; i < c->ssl_pkey_num; i++) { |
0f113f3e | 246 | CERT_PKEY *cpk = c->pkeys + i; |
222561fe RS |
247 | X509_free(cpk->x509); |
248 | cpk->x509 = NULL; | |
c5ba2d99 RS |
249 | EVP_PKEY_free(cpk->privatekey); |
250 | cpk->privatekey = NULL; | |
79b2a2f2 | 251 | OSSL_STACK_OF_X509_free(cpk->chain); |
222561fe | 252 | cpk->chain = NULL; |
25aaa98a RS |
253 | OPENSSL_free(cpk->serverinfo); |
254 | cpk->serverinfo = NULL; | |
255 | cpk->serverinfo_length = 0; | |
b67cb09f TS |
256 | #ifndef OPENSSL_NO_COMP_ALG |
257 | for (j = 0; j < TLSEXT_comp_cert_limit; j++) { | |
258 | OSSL_COMP_CERT_free(cpk->comp_cert[j]); | |
259 | cpk->comp_cert[j] = NULL; | |
260 | cpk->cert_comp_used = 0; | |
261 | } | |
262 | #endif | |
0f113f3e MC |
263 | } |
264 | } | |
ca8e5b9b | 265 | |
eb90a483 | 266 | void ssl_cert_free(CERT *c) |
0f113f3e MC |
267 | { |
268 | int i; | |
d02b48c6 | 269 | |
e6e9170d RS |
270 | if (c == NULL) |
271 | return; | |
2f545ae4 | 272 | CRYPTO_DOWN_REF(&c->references, &i, c->lock); |
f3f1cf84 | 273 | REF_PRINT_COUNT("CERT", c); |
0f113f3e MC |
274 | if (i > 0) |
275 | return; | |
f3f1cf84 | 276 | REF_ASSERT_ISNT(i < 0); |
d02b48c6 | 277 | |
e2b420fd | 278 | EVP_PKEY_free(c->dh_tmp); |
d02b48c6 | 279 | |
0f113f3e | 280 | ssl_cert_clear_certs(c); |
25aaa98a RS |
281 | OPENSSL_free(c->conf_sigalgs); |
282 | OPENSSL_free(c->client_sigalgs); | |
75c13e78 | 283 | OPENSSL_free(c->ctype); |
222561fe RS |
284 | X509_STORE_free(c->verify_store); |
285 | X509_STORE_free(c->chain_store); | |
43ae5eed | 286 | custom_exts_free(&c->custext); |
df6da24b DSH |
287 | #ifndef OPENSSL_NO_PSK |
288 | OPENSSL_free(c->psk_identity_hint); | |
289 | #endif | |
ee58915c | 290 | OPENSSL_free(c->pkeys); |
16203f7b | 291 | CRYPTO_THREAD_lock_free(c->lock); |
0f113f3e MC |
292 | OPENSSL_free(c); |
293 | } | |
d02b48c6 | 294 | |
38b051a1 | 295 | int ssl_cert_set0_chain(SSL_CONNECTION *s, SSL_CTX *ctx, STACK_OF(X509) *chain) |
0f113f3e MC |
296 | { |
297 | int i, r; | |
9f0f53b7 | 298 | CERT_PKEY *cpk = s != NULL ? s->cert->key : ctx->cert->key; |
9f0f53b7 | 299 | |
0f113f3e MC |
300 | if (!cpk) |
301 | return 0; | |
0f113f3e | 302 | for (i = 0; i < sk_X509_num(chain); i++) { |
9f0f53b7 MC |
303 | X509 *x = sk_X509_value(chain, i); |
304 | ||
9f0f53b7 | 305 | r = ssl_security_cert(s, ctx, x, 0, 0); |
0f113f3e | 306 | if (r != 1) { |
6849b73c | 307 | ERR_raise(ERR_LIB_SSL, r); |
0f113f3e MC |
308 | return 0; |
309 | } | |
310 | } | |
79b2a2f2 | 311 | OSSL_STACK_OF_X509_free(cpk->chain); |
0f113f3e MC |
312 | cpk->chain = chain; |
313 | return 1; | |
314 | } | |
f71c6e52 | 315 | |
38b051a1 | 316 | int ssl_cert_set1_chain(SSL_CONNECTION *s, SSL_CTX *ctx, STACK_OF(X509) *chain) |
0f113f3e MC |
317 | { |
318 | STACK_OF(X509) *dchain; | |
ee58915c | 319 | |
0f113f3e MC |
320 | if (!chain) |
321 | return ssl_cert_set0_chain(s, ctx, NULL); | |
322 | dchain = X509_chain_up_ref(chain); | |
323 | if (!dchain) | |
324 | return 0; | |
325 | if (!ssl_cert_set0_chain(s, ctx, dchain)) { | |
79b2a2f2 | 326 | OSSL_STACK_OF_X509_free(dchain); |
0f113f3e MC |
327 | return 0; |
328 | } | |
329 | return 1; | |
330 | } | |
f71c6e52 | 331 | |
38b051a1 | 332 | int ssl_cert_add0_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x) |
0f113f3e MC |
333 | { |
334 | int r; | |
335 | CERT_PKEY *cpk = s ? s->cert->key : ctx->cert->key; | |
ee58915c | 336 | |
0f113f3e MC |
337 | if (!cpk) |
338 | return 0; | |
339 | r = ssl_security_cert(s, ctx, x, 0, 0); | |
340 | if (r != 1) { | |
6849b73c | 341 | ERR_raise(ERR_LIB_SSL, r); |
0f113f3e MC |
342 | return 0; |
343 | } | |
344 | if (!cpk->chain) | |
345 | cpk->chain = sk_X509_new_null(); | |
346 | if (!cpk->chain || !sk_X509_push(cpk->chain, x)) | |
347 | return 0; | |
348 | return 1; | |
349 | } | |
f71c6e52 | 350 | |
38b051a1 | 351 | int ssl_cert_add1_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x) |
0f113f3e MC |
352 | { |
353 | if (!ssl_cert_add0_chain_cert(s, ctx, x)) | |
354 | return 0; | |
05f0fb9f | 355 | X509_up_ref(x); |
0f113f3e MC |
356 | return 1; |
357 | } | |
7b6b246f RS |
358 | |
359 | int ssl_cert_select_current(CERT *c, X509 *x) | |
0f113f3e | 360 | { |
ee58915c MB |
361 | size_t i; |
362 | ||
0f113f3e MC |
363 | if (x == NULL) |
364 | return 0; | |
ee58915c | 365 | for (i = 0; i < c->ssl_pkey_num; i++) { |
0f113f3e MC |
366 | CERT_PKEY *cpk = c->pkeys + i; |
367 | if (cpk->x509 == x && cpk->privatekey) { | |
368 | c->key = cpk; | |
369 | return 1; | |
370 | } | |
371 | } | |
372 | ||
ee58915c | 373 | for (i = 0; i < c->ssl_pkey_num; i++) { |
0f113f3e MC |
374 | CERT_PKEY *cpk = c->pkeys + i; |
375 | if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) { | |
376 | c->key = cpk; | |
377 | return 1; | |
378 | } | |
379 | } | |
380 | return 0; | |
381 | } | |
0f78819c DSH |
382 | |
383 | int ssl_cert_set_current(CERT *c, long op) | |
0f113f3e | 384 | { |
ee58915c MB |
385 | size_t i, idx; |
386 | ||
0f113f3e MC |
387 | if (!c) |
388 | return 0; | |
389 | if (op == SSL_CERT_SET_FIRST) | |
390 | idx = 0; | |
391 | else if (op == SSL_CERT_SET_NEXT) { | |
ee58915c MB |
392 | idx = (size_t)(c->key - c->pkeys + 1); |
393 | if (idx >= c->ssl_pkey_num) | |
0f113f3e MC |
394 | return 0; |
395 | } else | |
396 | return 0; | |
ee58915c | 397 | for (i = idx; i < c->ssl_pkey_num; i++) { |
0f113f3e MC |
398 | CERT_PKEY *cpk = c->pkeys + i; |
399 | if (cpk->x509 && cpk->privatekey) { | |
400 | c->key = cpk; | |
401 | return 1; | |
402 | } | |
403 | } | |
404 | return 0; | |
405 | } | |
406 | ||
407 | void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) | |
408 | { | |
409 | c->cert_cb = cb; | |
410 | c->cert_cb_arg = arg; | |
411 | } | |
18d71588 | 412 | |
c1c1bb7c MC |
413 | /* |
414 | * Verify a certificate chain | |
415 | * Return codes: | |
416 | * 1: Verify success | |
417 | * 0: Verify failure or error | |
418 | * -1: Retry required | |
419 | */ | |
38b051a1 | 420 | int ssl_verify_cert_chain(SSL_CONNECTION *s, STACK_OF(X509) *sk) |
0f113f3e MC |
421 | { |
422 | X509 *x; | |
f0e0fd51 | 423 | int i = 0; |
0f113f3e | 424 | X509_STORE *verify_store; |
f0e0fd51 | 425 | X509_STORE_CTX *ctx = NULL; |
919ba009 | 426 | X509_VERIFY_PARAM *param; |
38b051a1 | 427 | SSL_CTX *sctx; |
0f113f3e | 428 | |
f0e0fd51 RS |
429 | if ((sk == NULL) || (sk_X509_num(sk) == 0)) |
430 | return 0; | |
431 | ||
38b051a1 | 432 | sctx = SSL_CONNECTION_GET_CTX(s); |
0f113f3e MC |
433 | if (s->cert->verify_store) |
434 | verify_store = s->cert->verify_store; | |
435 | else | |
38b051a1 | 436 | verify_store = sctx->cert_store; |
0f113f3e | 437 | |
38b051a1 | 438 | ctx = X509_STORE_CTX_new_ex(sctx->libctx, sctx->propq); |
f0e0fd51 | 439 | if (ctx == NULL) { |
e077455e | 440 | ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); |
f0e0fd51 RS |
441 | return 0; |
442 | } | |
0f113f3e MC |
443 | |
444 | x = sk_X509_value(sk, 0); | |
f0e0fd51 | 445 | if (!X509_STORE_CTX_init(ctx, verify_store, x, sk)) { |
6849b73c | 446 | ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); |
f0e0fd51 | 447 | goto end; |
0f113f3e | 448 | } |
f0e0fd51 | 449 | param = X509_STORE_CTX_get0_param(ctx); |
fbb82a60 VD |
450 | /* |
451 | * XXX: Separate @AUTHSECLEVEL and @TLSSECLEVEL would be useful at some | |
452 | * point, for now a single @SECLEVEL sets the same policy for TLS crypto | |
453 | * and PKI authentication. | |
454 | */ | |
38b051a1 TM |
455 | X509_VERIFY_PARAM_set_auth_level(param, |
456 | SSL_get_security_level(SSL_CONNECTION_GET_SSL(s))); | |
919ba009 | 457 | |
0f113f3e | 458 | /* Set suite B flags if needed */ |
f0e0fd51 | 459 | X509_STORE_CTX_set_flags(ctx, tls1_suiteb(s)); |
38b051a1 TM |
460 | if (!X509_STORE_CTX_set_ex_data(ctx, |
461 | SSL_get_ex_data_X509_STORE_CTX_idx(), s)) { | |
a98810bf F |
462 | goto end; |
463 | } | |
0f113f3e | 464 | |
919ba009 VD |
465 | /* Verify via DANE if enabled */ |
466 | if (DANETLS_ENABLED(&s->dane)) | |
f0e0fd51 | 467 | X509_STORE_CTX_set0_dane(ctx, &s->dane); |
919ba009 | 468 | |
0f113f3e MC |
469 | /* |
470 | * We need to inherit the verify parameters. These can be determined by | |
471 | * the context: if its a server it will verify SSL client certificates or | |
472 | * vice versa. | |
473 | */ | |
474 | ||
f0e0fd51 | 475 | X509_STORE_CTX_set_default(ctx, s->server ? "ssl_client" : "ssl_server"); |
0f113f3e | 476 | /* |
919ba009 | 477 | * Anything non-default in "s->param" should overwrite anything in the ctx. |
0f113f3e | 478 | */ |
919ba009 | 479 | X509_VERIFY_PARAM_set1(param, s->param); |
0f113f3e MC |
480 | |
481 | if (s->verify_callback) | |
f0e0fd51 | 482 | X509_STORE_CTX_set_verify_cb(ctx, s->verify_callback); |
0f113f3e | 483 | |
38b051a1 TM |
484 | if (sctx->app_verify_callback != NULL) { |
485 | i = sctx->app_verify_callback(ctx, sctx->app_verify_arg); | |
c1c1bb7c | 486 | } else { |
f0e0fd51 | 487 | i = X509_verify_cert(ctx); |
c1c1bb7c MC |
488 | /* We treat an error in the same way as a failure to verify */ |
489 | if (i < 0) | |
490 | i = 0; | |
491 | } | |
d02b48c6 | 492 | |
f0e0fd51 | 493 | s->verify_result = X509_STORE_CTX_get_error(ctx); |
79b2a2f2 | 494 | OSSL_STACK_OF_X509_free(s->verified_chain); |
696178ed | 495 | s->verified_chain = NULL; |
f0e0fd51 RS |
496 | if (X509_STORE_CTX_get0_chain(ctx) != NULL) { |
497 | s->verified_chain = X509_STORE_CTX_get1_chain(ctx); | |
696178ed | 498 | if (s->verified_chain == NULL) { |
e077455e | 499 | ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); |
696178ed DSH |
500 | i = 0; |
501 | } | |
502 | } | |
919ba009 VD |
503 | |
504 | /* Move peername from the store context params to the SSL handle's */ | |
505 | X509_VERIFY_PARAM_move_peername(s->param, param); | |
506 | ||
a230b26e | 507 | end: |
f0e0fd51 RS |
508 | X509_STORE_CTX_free(ctx); |
509 | return i; | |
0f113f3e | 510 | } |
d02b48c6 | 511 | |
fa7c2637 DSH |
512 | static void set0_CA_list(STACK_OF(X509_NAME) **ca_list, |
513 | STACK_OF(X509_NAME) *name_list) | |
0f113f3e | 514 | { |
222561fe | 515 | sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); |
0f113f3e MC |
516 | *ca_list = name_list; |
517 | } | |
d02b48c6 | 518 | |
86135bed | 519 | STACK_OF(X509_NAME) *SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk) |
0f113f3e MC |
520 | { |
521 | int i; | |
e431363f | 522 | const int num = sk_X509_NAME_num(sk); |
0f113f3e MC |
523 | STACK_OF(X509_NAME) *ret; |
524 | X509_NAME *name; | |
525 | ||
7a908204 | 526 | ret = sk_X509_NAME_new_reserve(NULL, num); |
3c82e437 | 527 | if (ret == NULL) { |
e077455e | 528 | ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); |
3c82e437 F |
529 | return NULL; |
530 | } | |
e431363f | 531 | for (i = 0; i < num; i++) { |
0f113f3e | 532 | name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); |
e431363f | 533 | if (name == NULL) { |
e077455e | 534 | ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); |
0f113f3e | 535 | sk_X509_NAME_pop_free(ret, X509_NAME_free); |
3c82e437 | 536 | return NULL; |
0f113f3e | 537 | } |
e431363f | 538 | sk_X509_NAME_push(ret, name); /* Cannot fail after reserve call */ |
0f113f3e | 539 | } |
32f3b98d | 540 | return ret; |
0f113f3e MC |
541 | } |
542 | ||
fa7c2637 DSH |
543 | void SSL_set0_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) |
544 | { | |
38b051a1 TM |
545 | SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); |
546 | ||
547 | if (sc == NULL) | |
548 | return; | |
549 | ||
550 | set0_CA_list(&sc->ca_names, name_list); | |
fa7c2637 DSH |
551 | } |
552 | ||
553 | void SSL_CTX_set0_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) | |
0f113f3e | 554 | { |
fa7c2637 DSH |
555 | set0_CA_list(&ctx->ca_names, name_list); |
556 | } | |
557 | ||
558 | const STACK_OF(X509_NAME) *SSL_CTX_get0_CA_list(const SSL_CTX *ctx) | |
559 | { | |
560 | return ctx->ca_names; | |
561 | } | |
562 | ||
563 | const STACK_OF(X509_NAME) *SSL_get0_CA_list(const SSL *s) | |
564 | { | |
38b051a1 TM |
565 | const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); |
566 | ||
567 | if (sc == NULL) | |
568 | return NULL; | |
569 | ||
570 | return sc->ca_names != NULL ? sc->ca_names : s->ctx->ca_names; | |
0f113f3e MC |
571 | } |
572 | ||
573 | void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) | |
574 | { | |
98732979 | 575 | set0_CA_list(&ctx->client_ca_names, name_list); |
0f113f3e | 576 | } |
d02b48c6 | 577 | |
0821bcd4 | 578 | STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) |
0f113f3e | 579 | { |
98732979 | 580 | return ctx->client_ca_names; |
fa7c2637 DSH |
581 | } |
582 | ||
583 | void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) | |
584 | { | |
38b051a1 TM |
585 | SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); |
586 | ||
587 | if (sc == NULL) | |
588 | return; | |
589 | ||
590 | set0_CA_list(&sc->client_ca_names, name_list); | |
fa7c2637 DSH |
591 | } |
592 | ||
593 | const STACK_OF(X509_NAME) *SSL_get0_peer_CA_list(const SSL *s) | |
594 | { | |
38b051a1 TM |
595 | const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); |
596 | ||
597 | if (sc == NULL) | |
598 | return NULL; | |
599 | ||
600 | return sc->s3.tmp.peer_ca_names; | |
0f113f3e | 601 | } |
d02b48c6 | 602 | |
0821bcd4 | 603 | STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) |
0f113f3e | 604 | { |
38b051a1 TM |
605 | const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL(s); |
606 | ||
607 | if (sc == NULL) | |
608 | return NULL; | |
609 | ||
610 | if (!sc->server) | |
611 | return sc->s3.tmp.peer_ca_names; | |
612 | return sc->client_ca_names != NULL ? sc->client_ca_names | |
613 | : s->ctx->client_ca_names; | |
0f113f3e MC |
614 | } |
615 | ||
fa7c2637 | 616 | static int add_ca_name(STACK_OF(X509_NAME) **sk, const X509 *x) |
0f113f3e MC |
617 | { |
618 | X509_NAME *name; | |
619 | ||
620 | if (x == NULL) | |
fa7c2637 DSH |
621 | return 0; |
622 | if (*sk == NULL && ((*sk = sk_X509_NAME_new_null()) == NULL)) | |
623 | return 0; | |
0f113f3e MC |
624 | |
625 | if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) | |
fa7c2637 | 626 | return 0; |
0f113f3e MC |
627 | |
628 | if (!sk_X509_NAME_push(*sk, name)) { | |
629 | X509_NAME_free(name); | |
fa7c2637 | 630 | return 0; |
0f113f3e | 631 | } |
fa7c2637 DSH |
632 | return 1; |
633 | } | |
634 | ||
64a48fc7 | 635 | int SSL_add1_to_CA_list(SSL *ssl, const X509 *x) |
fa7c2637 | 636 | { |
38b051a1 TM |
637 | SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); |
638 | ||
639 | if (sc == NULL) | |
640 | return 0; | |
641 | ||
642 | return add_ca_name(&sc->ca_names, x); | |
fa7c2637 DSH |
643 | } |
644 | ||
64a48fc7 | 645 | int SSL_CTX_add1_to_CA_list(SSL_CTX *ctx, const X509 *x) |
fa7c2637 DSH |
646 | { |
647 | return add_ca_name(&ctx->ca_names, x); | |
0f113f3e MC |
648 | } |
649 | ||
64a48fc7 RL |
650 | /* |
651 | * The following two are older names are to be replaced with | |
652 | * SSL(_CTX)_add1_to_CA_list | |
653 | */ | |
0f113f3e MC |
654 | int SSL_add_client_CA(SSL *ssl, X509 *x) |
655 | { | |
38b051a1 TM |
656 | SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); |
657 | ||
658 | if (sc == NULL) | |
659 | return 0; | |
660 | ||
661 | return add_ca_name(&sc->client_ca_names, x); | |
0f113f3e MC |
662 | } |
663 | ||
664 | int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) | |
665 | { | |
98732979 | 666 | return add_ca_name(&ctx->client_ca_names, x); |
0f113f3e MC |
667 | } |
668 | ||
3e41defe | 669 | static int xname_cmp(const X509_NAME *a, const X509_NAME *b) |
0f113f3e | 670 | { |
3e41defe TM |
671 | unsigned char *abuf = NULL, *bbuf = NULL; |
672 | int alen, blen, ret; | |
673 | ||
674 | /* X509_NAME_cmp() itself casts away constness in this way, so | |
675 | * assume it's safe: | |
676 | */ | |
677 | alen = i2d_X509_NAME((X509_NAME *)a, &abuf); | |
678 | blen = i2d_X509_NAME((X509_NAME *)b, &bbuf); | |
679 | ||
680 | if (alen < 0 || blen < 0) | |
681 | ret = -2; | |
682 | else if (alen != blen) | |
683 | ret = alen - blen; | |
684 | else /* alen == blen */ | |
685 | ret = memcmp(abuf, bbuf, alen); | |
686 | ||
687 | OPENSSL_free(abuf); | |
688 | OPENSSL_free(bbuf); | |
689 | ||
690 | return ret; | |
0f113f3e | 691 | } |
d02b48c6 | 692 | |
3e41defe | 693 | static int xname_sk_cmp(const X509_NAME *const *a, const X509_NAME *const *b) |
7823d792 | 694 | { |
3e41defe | 695 | return xname_cmp(*a, *b); |
7823d792 TF |
696 | } |
697 | ||
698 | static unsigned long xname_hash(const X509_NAME *a) | |
699 | { | |
bf973d06 DDO |
700 | /* This returns 0 also if SHA1 is not available */ |
701 | return X509_NAME_hash_ex((X509_NAME *)a, NULL, NULL, NULL); | |
7823d792 TF |
702 | } |
703 | ||
d8652be0 | 704 | STACK_OF(X509_NAME) *SSL_load_client_CA_file_ex(const char *file, |
b4250010 | 705 | OSSL_LIB_CTX *libctx, |
d8652be0 | 706 | const char *propq) |
0f113f3e | 707 | { |
7823d792 | 708 | BIO *in = BIO_new(BIO_s_file()); |
0f113f3e MC |
709 | X509 *x = NULL; |
710 | X509_NAME *xn = NULL; | |
7823d792 | 711 | STACK_OF(X509_NAME) *ret = NULL; |
a230b26e | 712 | LHASH_OF(X509_NAME) *name_hash = lh_X509_NAME_new(xname_hash, xname_cmp); |
b4250010 | 713 | OSSL_LIB_CTX *prev_libctx = NULL; |
0f113f3e | 714 | |
e077455e RL |
715 | if (name_hash == NULL) { |
716 | ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); | |
717 | goto err; | |
718 | } | |
719 | if (in == NULL) { | |
720 | ERR_raise(ERR_LIB_SSL, ERR_R_BIO_LIB); | |
0f113f3e MC |
721 | goto err; |
722 | } | |
723 | ||
d8652be0 | 724 | x = X509_new_ex(libctx, propq); |
6725682d | 725 | if (x == NULL) { |
e077455e | 726 | ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); |
6725682d SL |
727 | goto err; |
728 | } | |
e3f03624 | 729 | if (BIO_read_filename(in, file) <= 0) |
0f113f3e MC |
730 | goto err; |
731 | ||
6725682d | 732 | /* Internally lh_X509_NAME_retrieve() needs the libctx to retrieve SHA1 */ |
b4250010 | 733 | prev_libctx = OSSL_LIB_CTX_set0_default(libctx); |
0f113f3e MC |
734 | for (;;) { |
735 | if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) | |
736 | break; | |
737 | if (ret == NULL) { | |
738 | ret = sk_X509_NAME_new_null(); | |
739 | if (ret == NULL) { | |
e077455e | 740 | ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); |
0f113f3e MC |
741 | goto err; |
742 | } | |
743 | } | |
744 | if ((xn = X509_get_subject_name(x)) == NULL) | |
745 | goto err; | |
746 | /* check for duplicates */ | |
747 | xn = X509_NAME_dup(xn); | |
748 | if (xn == NULL) | |
749 | goto err; | |
7823d792 TF |
750 | if (lh_X509_NAME_retrieve(name_hash, xn) != NULL) { |
751 | /* Duplicate. */ | |
0f113f3e | 752 | X509_NAME_free(xn); |
3c82e437 | 753 | xn = NULL; |
7823d792 | 754 | } else { |
9d6daf99 | 755 | lh_X509_NAME_insert(name_hash, xn); |
3c82e437 F |
756 | if (!sk_X509_NAME_push(ret, xn)) |
757 | goto err; | |
0f113f3e MC |
758 | } |
759 | } | |
66696478 | 760 | goto done; |
0f113f3e | 761 | |
0f113f3e | 762 | err: |
3c82e437 | 763 | X509_NAME_free(xn); |
66696478 RS |
764 | sk_X509_NAME_pop_free(ret, X509_NAME_free); |
765 | ret = NULL; | |
766 | done: | |
6725682d | 767 | /* restore the old libctx */ |
b4250010 | 768 | OSSL_LIB_CTX_set0_default(prev_libctx); |
ca3a82c3 | 769 | BIO_free(in); |
222561fe | 770 | X509_free(x); |
7823d792 | 771 | lh_X509_NAME_free(name_hash); |
0f113f3e MC |
772 | if (ret != NULL) |
773 | ERR_clear_error(); | |
26a7d938 | 774 | return ret; |
0f113f3e | 775 | } |
d02b48c6 | 776 | |
6725682d SL |
777 | STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) |
778 | { | |
d8652be0 | 779 | return SSL_load_client_CA_file_ex(file, NULL, NULL); |
6725682d SL |
780 | } |
781 | ||
661b361b | 782 | int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, |
0f113f3e MC |
783 | const char *file) |
784 | { | |
785 | BIO *in; | |
786 | X509 *x = NULL; | |
787 | X509_NAME *xn = NULL; | |
788 | int ret = 1; | |
789 | int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); | |
790 | ||
7823d792 | 791 | oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_sk_cmp); |
0f113f3e | 792 | |
9982cbbb | 793 | in = BIO_new(BIO_s_file()); |
0f113f3e MC |
794 | |
795 | if (in == NULL) { | |
e077455e | 796 | ERR_raise(ERR_LIB_SSL, ERR_R_BIO_LIB); |
0f113f3e MC |
797 | goto err; |
798 | } | |
799 | ||
e3f03624 | 800 | if (BIO_read_filename(in, file) <= 0) |
0f113f3e MC |
801 | goto err; |
802 | ||
803 | for (;;) { | |
804 | if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) | |
805 | break; | |
806 | if ((xn = X509_get_subject_name(x)) == NULL) | |
807 | goto err; | |
808 | xn = X509_NAME_dup(xn); | |
809 | if (xn == NULL) | |
810 | goto err; | |
3c82e437 F |
811 | if (sk_X509_NAME_find(stack, xn) >= 0) { |
812 | /* Duplicate. */ | |
0f113f3e | 813 | X509_NAME_free(xn); |
3c82e437 F |
814 | } else if (!sk_X509_NAME_push(stack, xn)) { |
815 | X509_NAME_free(xn); | |
816 | goto err; | |
817 | } | |
0f113f3e MC |
818 | } |
819 | ||
820 | ERR_clear_error(); | |
66696478 | 821 | goto done; |
0f113f3e | 822 | |
0f113f3e | 823 | err: |
3c82e437 | 824 | ret = 0; |
66696478 | 825 | done: |
ca3a82c3 | 826 | BIO_free(in); |
25aaa98a | 827 | X509_free(x); |
0f113f3e | 828 | (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); |
0f113f3e MC |
829 | return ret; |
830 | } | |
831 | ||
661b361b | 832 | int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, |
0f113f3e MC |
833 | const char *dir) |
834 | { | |
835 | OPENSSL_DIR_CTX *d = NULL; | |
836 | const char *filename; | |
837 | int ret = 0; | |
eb90a483 | 838 | |
0f113f3e | 839 | /* Note that a side effect is that the CAs will be sorted by name */ |
4083a229 | 840 | |
0f113f3e MC |
841 | while ((filename = OPENSSL_DIR_read(&d, dir))) { |
842 | char buf[1024]; | |
843 | int r; | |
1dc35d44 | 844 | struct stat st; |
4083a229 | 845 | |
cbe29648 | 846 | if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { |
6849b73c | 847 | ERR_raise(ERR_LIB_SSL, SSL_R_PATH_TOO_LONG); |
0f113f3e MC |
848 | goto err; |
849 | } | |
4083a229 | 850 | #ifdef OPENSSL_SYS_VMS |
cbe29648 | 851 | r = BIO_snprintf(buf, sizeof(buf), "%s%s", dir, filename); |
4083a229 | 852 | #else |
cbe29648 | 853 | r = BIO_snprintf(buf, sizeof(buf), "%s/%s", dir, filename); |
4083a229 | 854 | #endif |
1dc35d44 | 855 | /* Skip subdirectories */ |
856 | if (!stat(buf, &st) && S_ISDIR(st.st_mode)) | |
857 | continue; | |
0f113f3e MC |
858 | if (r <= 0 || r >= (int)sizeof(buf)) |
859 | goto err; | |
860 | if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) | |
861 | goto err; | |
862 | } | |
863 | ||
864 | if (errno) { | |
ff988500 | 865 | ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), |
6849b73c RL |
866 | "calling OPENSSL_dir_read(%s)", dir); |
867 | ERR_raise(ERR_LIB_SSL, ERR_R_SYS_LIB); | |
0f113f3e MC |
868 | goto err; |
869 | } | |
870 | ||
871 | ret = 1; | |
872 | ||
873 | err: | |
874 | if (d) | |
875 | OPENSSL_DIR_end(&d); | |
16203f7b | 876 | |
0f113f3e MC |
877 | return ret; |
878 | } | |
285046ec | 879 | |
6dcb100f RL |
880 | static int add_uris_recursive(STACK_OF(X509_NAME) *stack, |
881 | const char *uri, int depth) | |
882 | { | |
883 | int ok = 1; | |
884 | OSSL_STORE_CTX *ctx = NULL; | |
885 | X509 *x = NULL; | |
886 | X509_NAME *xn = NULL; | |
887 | ||
888 | if ((ctx = OSSL_STORE_open(uri, NULL, NULL, NULL, NULL)) == NULL) | |
889 | goto err; | |
890 | ||
891 | while (!OSSL_STORE_eof(ctx) && !OSSL_STORE_error(ctx)) { | |
892 | OSSL_STORE_INFO *info = OSSL_STORE_load(ctx); | |
893 | int infotype = info == 0 ? 0 : OSSL_STORE_INFO_get_type(info); | |
894 | ||
895 | if (info == NULL) | |
896 | continue; | |
897 | ||
898 | if (infotype == OSSL_STORE_INFO_NAME) { | |
899 | /* | |
900 | * This is an entry in the "directory" represented by the current | |
901 | * uri. if |depth| allows, dive into it. | |
902 | */ | |
ee669781 RL |
903 | if (depth > 0) |
904 | ok = add_uris_recursive(stack, OSSL_STORE_INFO_get0_NAME(info), | |
905 | depth - 1); | |
6dcb100f RL |
906 | } else if (infotype == OSSL_STORE_INFO_CERT) { |
907 | if ((x = OSSL_STORE_INFO_get0_CERT(info)) == NULL | |
908 | || (xn = X509_get_subject_name(x)) == NULL | |
909 | || (xn = X509_NAME_dup(xn)) == NULL) | |
910 | goto err; | |
911 | if (sk_X509_NAME_find(stack, xn) >= 0) { | |
912 | /* Duplicate. */ | |
913 | X509_NAME_free(xn); | |
914 | } else if (!sk_X509_NAME_push(stack, xn)) { | |
915 | X509_NAME_free(xn); | |
916 | goto err; | |
917 | } | |
918 | } | |
919 | ||
920 | OSSL_STORE_INFO_free(info); | |
921 | } | |
922 | ||
923 | ERR_clear_error(); | |
924 | goto done; | |
925 | ||
926 | err: | |
927 | ok = 0; | |
928 | done: | |
929 | OSSL_STORE_close(ctx); | |
930 | ||
931 | return ok; | |
932 | } | |
933 | ||
934 | int SSL_add_store_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, | |
935 | const char *store) | |
936 | { | |
937 | int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b) | |
938 | = sk_X509_NAME_set_cmp_func(stack, xname_sk_cmp); | |
939 | int ret = add_uris_recursive(stack, store, 1); | |
940 | ||
941 | (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); | |
942 | return ret; | |
943 | } | |
944 | ||
74ecfab4 | 945 | /* Build a certificate chain for current certificate */ |
38b051a1 | 946 | int ssl_build_cert_chain(SSL_CONNECTION *s, SSL_CTX *ctx, int flags) |
0f113f3e | 947 | { |
38b051a1 | 948 | CERT *c = s != NULL ? s->cert : ctx->cert; |
0f113f3e MC |
949 | CERT_PKEY *cpk = c->key; |
950 | X509_STORE *chain_store = NULL; | |
f0e0fd51 | 951 | X509_STORE_CTX *xs_ctx = NULL; |
0f113f3e MC |
952 | STACK_OF(X509) *chain = NULL, *untrusted = NULL; |
953 | X509 *x; | |
38b051a1 | 954 | SSL_CTX *real_ctx = (s == NULL) ? ctx : SSL_CONNECTION_GET_CTX(s); |
0f113f3e | 955 | int i, rv = 0; |
0f113f3e | 956 | |
38b051a1 | 957 | if (cpk->x509 == NULL) { |
6849b73c | 958 | ERR_raise(ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_SET); |
0f113f3e MC |
959 | goto err; |
960 | } | |
961 | /* Rearranging and check the chain: add everything to a store */ | |
962 | if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) { | |
963 | chain_store = X509_STORE_new(); | |
a71edf3b | 964 | if (chain_store == NULL) |
0f113f3e MC |
965 | goto err; |
966 | for (i = 0; i < sk_X509_num(cpk->chain); i++) { | |
967 | x = sk_X509_value(cpk->chain, i); | |
c0452248 | 968 | if (!X509_STORE_add_cert(chain_store, x)) |
0f113f3e | 969 | goto err; |
0f113f3e | 970 | } |
c0452248 RS |
971 | /* Add EE cert too: it might be self signed */ |
972 | if (!X509_STORE_add_cert(chain_store, cpk->x509)) | |
973 | goto err; | |
0f113f3e | 974 | } else { |
38b051a1 | 975 | if (c->chain_store != NULL) |
0f113f3e | 976 | chain_store = c->chain_store; |
0f113f3e | 977 | else |
38b051a1 | 978 | chain_store = real_ctx->cert_store; |
0f113f3e MC |
979 | |
980 | if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) | |
981 | untrusted = cpk->chain; | |
982 | } | |
983 | ||
4e4ae840 | 984 | xs_ctx = X509_STORE_CTX_new_ex(real_ctx->libctx, real_ctx->propq); |
f0e0fd51 | 985 | if (xs_ctx == NULL) { |
e077455e | 986 | ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); |
f0e0fd51 RS |
987 | goto err; |
988 | } | |
989 | if (!X509_STORE_CTX_init(xs_ctx, chain_store, cpk->x509, untrusted)) { | |
6849b73c | 990 | ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB); |
0f113f3e MC |
991 | goto err; |
992 | } | |
993 | /* Set suite B flags if needed */ | |
f0e0fd51 | 994 | X509_STORE_CTX_set_flags(xs_ctx, |
0f113f3e MC |
995 | c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS); |
996 | ||
f0e0fd51 | 997 | i = X509_verify_cert(xs_ctx); |
0f113f3e MC |
998 | if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) { |
999 | if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) | |
1000 | ERR_clear_error(); | |
1001 | i = 1; | |
1002 | rv = 2; | |
1003 | } | |
1004 | if (i > 0) | |
f0e0fd51 | 1005 | chain = X509_STORE_CTX_get1_chain(xs_ctx); |
0f113f3e | 1006 | if (i <= 0) { |
f0e0fd51 | 1007 | i = X509_STORE_CTX_get_error(xs_ctx); |
c48ffbcc RL |
1008 | ERR_raise_data(ERR_LIB_SSL, SSL_R_CERTIFICATE_VERIFY_FAILED, |
1009 | "Verify error:%s", X509_verify_cert_error_string(i)); | |
0f113f3e | 1010 | |
0f113f3e MC |
1011 | goto err; |
1012 | } | |
0f113f3e MC |
1013 | /* Remove EE certificate from chain */ |
1014 | x = sk_X509_shift(chain); | |
1015 | X509_free(x); | |
1016 | if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) { | |
1017 | if (sk_X509_num(chain) > 0) { | |
1018 | /* See if last cert is self signed */ | |
1019 | x = sk_X509_value(chain, sk_X509_num(chain) - 1); | |
a8d8e06b | 1020 | if (X509_get_extension_flags(x) & EXFLAG_SS) { |
0f113f3e MC |
1021 | x = sk_X509_pop(chain); |
1022 | X509_free(x); | |
1023 | } | |
1024 | } | |
1025 | } | |
1026 | /* | |
1027 | * Check security level of all CA certificates: EE will have been checked | |
1028 | * already. | |
1029 | */ | |
1030 | for (i = 0; i < sk_X509_num(chain); i++) { | |
1031 | x = sk_X509_value(chain, i); | |
1032 | rv = ssl_security_cert(s, ctx, x, 0, 0); | |
1033 | if (rv != 1) { | |
6849b73c | 1034 | ERR_raise(ERR_LIB_SSL, rv); |
79b2a2f2 | 1035 | OSSL_STACK_OF_X509_free(chain); |
0f113f3e MC |
1036 | rv = 0; |
1037 | goto err; | |
1038 | } | |
1039 | } | |
79b2a2f2 | 1040 | OSSL_STACK_OF_X509_free(cpk->chain); |
0f113f3e MC |
1041 | cpk->chain = chain; |
1042 | if (rv == 0) | |
1043 | rv = 1; | |
1044 | err: | |
1045 | if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) | |
1046 | X509_STORE_free(chain_store); | |
f0e0fd51 | 1047 | X509_STORE_CTX_free(xs_ctx); |
0f113f3e MC |
1048 | |
1049 | return rv; | |
1050 | } | |
74ecfab4 DSH |
1051 | |
1052 | int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) | |
0f113f3e MC |
1053 | { |
1054 | X509_STORE **pstore; | |
1055 | if (chain) | |
1056 | pstore = &c->chain_store; | |
1057 | else | |
1058 | pstore = &c->verify_store; | |
222561fe | 1059 | X509_STORE_free(*pstore); |
0f113f3e MC |
1060 | *pstore = store; |
1061 | if (ref && store) | |
c001ce33 | 1062 | X509_STORE_up_ref(store); |
0f113f3e MC |
1063 | return 1; |
1064 | } | |
1065 | ||
948cf521 HL |
1066 | int ssl_cert_get_cert_store(CERT *c, X509_STORE **pstore, int chain) |
1067 | { | |
1068 | *pstore = (chain ? c->chain_store : c->verify_store); | |
1069 | return 1; | |
1070 | } | |
1071 | ||
d7b5c648 P |
1072 | int ssl_get_security_level_bits(const SSL *s, const SSL_CTX *ctx, int *levelp) |
1073 | { | |
1074 | int level; | |
657489e8 HK |
1075 | /* |
1076 | * note that there's a corresponding minbits_table | |
1077 | * in crypto/x509/x509_vfy.c that's used for checking the security level | |
1078 | * of RSA and DSA keys | |
1079 | */ | |
d7b5c648 P |
1080 | static const int minbits_table[5 + 1] = { 0, 80, 112, 128, 192, 256 }; |
1081 | ||
1082 | if (ctx != NULL) | |
1083 | level = SSL_CTX_get_security_level(ctx); | |
1084 | else | |
1085 | level = SSL_get_security_level(s); | |
1086 | ||
1087 | if (level > 5) | |
1088 | level = 5; | |
1089 | else if (level < 0) | |
1090 | level = 0; | |
1091 | ||
1092 | if (levelp != NULL) | |
1093 | *levelp = level; | |
1094 | ||
1095 | return minbits_table[level]; | |
1096 | } | |
1097 | ||
a230b26e EK |
1098 | static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, |
1099 | int op, int bits, int nid, void *other, | |
0f113f3e MC |
1100 | void *ex) |
1101 | { | |
b139a956 | 1102 | int level, minbits, pfs_mask; |
38b051a1 | 1103 | const SSL_CONNECTION *sc; |
a7cf07b4 | 1104 | |
d7b5c648 P |
1105 | minbits = ssl_get_security_level_bits(s, ctx, &level); |
1106 | ||
1107 | if (level == 0) { | |
a7cf07b4 VD |
1108 | /* |
1109 | * No EDH keys weaker than 1024-bits even at level 0, otherwise, | |
1110 | * anything goes. | |
1111 | */ | |
1112 | if (op == SSL_SECOP_TMP_DH && bits < 80) | |
1113 | return 0; | |
0f113f3e | 1114 | return 1; |
a7cf07b4 | 1115 | } |
0f113f3e MC |
1116 | switch (op) { |
1117 | case SSL_SECOP_CIPHER_SUPPORTED: | |
1118 | case SSL_SECOP_CIPHER_SHARED: | |
1119 | case SSL_SECOP_CIPHER_CHECK: | |
1120 | { | |
1121 | const SSL_CIPHER *c = other; | |
1122 | /* No ciphers below security level */ | |
1123 | if (bits < minbits) | |
1124 | return 0; | |
1125 | /* No unauthenticated ciphersuites */ | |
1126 | if (c->algorithm_auth & SSL_aNULL) | |
1127 | return 0; | |
1128 | /* No MD5 mac ciphersuites */ | |
1129 | if (c->algorithm_mac & SSL_MD5) | |
1130 | return 0; | |
1131 | /* SHA1 HMAC is 160 bits of security */ | |
1132 | if (minbits > 160 && c->algorithm_mac & SSL_SHA1) | |
1133 | return 0; | |
0f113f3e | 1134 | /* Level 3: forward secure ciphersuites only */ |
b139a956 | 1135 | pfs_mask = SSL_kDHE | SSL_kECDHE | SSL_kDHEPSK | SSL_kECDHEPSK; |
75b68c9e | 1136 | if (level >= 3 && c->min_tls != TLS1_3_VERSION && |
b139a956 | 1137 | !(c->algorithm_mkey & pfs_mask)) |
0f113f3e MC |
1138 | return 0; |
1139 | break; | |
1140 | } | |
1141 | case SSL_SECOP_VERSION: | |
38b051a1 TM |
1142 | if ((sc = SSL_CONNECTION_FROM_CONST_SSL(s)) == NULL) |
1143 | return 0; | |
1144 | if (!SSL_CONNECTION_IS_DTLS(sc)) { | |
7bf2e4d7 P |
1145 | /* SSLv3, TLS v1.0 and TLS v1.1 only allowed at level 0 */ |
1146 | if (nid <= TLS1_1_VERSION && level > 0) | |
4fa52141 VD |
1147 | return 0; |
1148 | } else { | |
7bf2e4d7 P |
1149 | /* DTLS v1.0 only allowed at level 0 */ |
1150 | if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level > 0) | |
4fa52141 VD |
1151 | return 0; |
1152 | } | |
0f113f3e MC |
1153 | break; |
1154 | ||
1155 | case SSL_SECOP_COMPRESSION: | |
1156 | if (level >= 2) | |
1157 | return 0; | |
1158 | break; | |
1159 | case SSL_SECOP_TICKET: | |
1160 | if (level >= 3) | |
1161 | return 0; | |
1162 | break; | |
1163 | default: | |
1164 | if (bits < minbits) | |
1165 | return 0; | |
1166 | } | |
1167 | return 1; | |
1168 | } | |
b362ccab | 1169 | |
38b051a1 | 1170 | int ssl_security(const SSL_CONNECTION *s, int op, int bits, int nid, void *other) |
0f113f3e | 1171 | { |
38b051a1 TM |
1172 | return s->cert->sec_cb(SSL_CONNECTION_GET_SSL(s), NULL, op, bits, nid, |
1173 | other, s->cert->sec_ex); | |
0f113f3e | 1174 | } |
b362ccab | 1175 | |
e4646a89 | 1176 | int ssl_ctx_security(const SSL_CTX *ctx, int op, int bits, int nid, void *other) |
0f113f3e MC |
1177 | { |
1178 | return ctx->cert->sec_cb(NULL, ctx, op, bits, nid, other, | |
1179 | ctx->cert->sec_ex); | |
1180 | } | |
c04cd728 | 1181 | |
ee58915c | 1182 | int ssl_cert_lookup_by_nid(int nid, size_t *pidx, SSL_CTX *ctx) |
c04cd728 | 1183 | { |
c04cd728 DSH |
1184 | size_t i; |
1185 | ||
c04cd728 DSH |
1186 | for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { |
1187 | if (ssl_cert_info[i].nid == nid) { | |
11d2641f MC |
1188 | *pidx = i; |
1189 | return 1; | |
c04cd728 DSH |
1190 | } |
1191 | } | |
ee58915c MB |
1192 | for (i = 0; i < ctx->sigalg_list_len; i++) { |
1193 | if (ctx->ssl_cert_info[i].nid == nid) { | |
1194 | *pidx = SSL_PKEY_NUM + i; | |
1195 | return 1; | |
1196 | } | |
1197 | } | |
11d2641f MC |
1198 | return 0; |
1199 | } | |
1200 | ||
ee58915c | 1201 | SSL_CERT_LOOKUP *ssl_cert_lookup_by_pkey(const EVP_PKEY *pk, size_t *pidx, SSL_CTX *ctx) |
11d2641f | 1202 | { |
92dc275f | 1203 | size_t i; |
11d2641f | 1204 | |
ee58915c | 1205 | /* check classic pk types */ |
92dc275f | 1206 | for (i = 0; i < OSSL_NELEM(ssl_cert_info); i++) { |
ee58915c | 1207 | SSL_CERT_LOOKUP *tmp_lu = &ssl_cert_info[i]; |
11d2641f | 1208 | |
92dc275f RL |
1209 | if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid)) |
1210 | || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) { | |
1211 | if (pidx != NULL) | |
1212 | *pidx = i; | |
1213 | return tmp_lu; | |
1214 | } | |
1215 | } | |
ee58915c MB |
1216 | /* check provider-loaded pk types */ |
1217 | for (i = 0; ctx->sigalg_list_len; i++) { | |
1218 | SSL_CERT_LOOKUP *tmp_lu = &(ctx->ssl_cert_info[i]); | |
1219 | ||
1220 | if (EVP_PKEY_is_a(pk, OBJ_nid2sn(tmp_lu->nid)) | |
1221 | || EVP_PKEY_is_a(pk, OBJ_nid2ln(tmp_lu->nid))) { | |
1222 | if (pidx != NULL) | |
1223 | *pidx = SSL_PKEY_NUM + i; | |
1224 | return &ctx->ssl_cert_info[i]; | |
1225 | } | |
1226 | } | |
11d2641f | 1227 | |
92dc275f | 1228 | return NULL; |
c04cd728 DSH |
1229 | } |
1230 | ||
ee58915c | 1231 | SSL_CERT_LOOKUP *ssl_cert_lookup_by_idx(size_t idx, SSL_CTX *ctx) |
c04cd728 | 1232 | { |
ee58915c | 1233 | if (idx >= (OSSL_NELEM(ssl_cert_info) + ctx->sigalg_list_len)) |
b2555168 | 1234 | return NULL; |
ee58915c MB |
1235 | else if (idx >= (OSSL_NELEM(ssl_cert_info))) |
1236 | return &(ctx->ssl_cert_info[idx - SSL_PKEY_NUM]); | |
c04cd728 DSH |
1237 | return &ssl_cert_info[idx]; |
1238 | } |