blob: e4523c3594c74b24aaa241bfe71459a3be2a3839 [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.]
56 */
57/* ====================================================================
58 * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 *
64 * 1. Redistributions of source code must retain the above copyright
65 * notice, this list of conditions and the following disclaimer.
66 *
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in
69 * the documentation and/or other materials provided with the
70 * distribution.
71 *
72 * 3. All advertising materials mentioning features or use of this
73 * software must display the following acknowledgment:
74 * "This product includes software developed by the OpenSSL Project
75 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
76 *
77 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
78 * endorse or promote products derived from this software without
79 * prior written permission. For written permission, please contact
80 * openssl-core@openssl.org.
81 *
82 * 5. Products derived from this software may not be called "OpenSSL"
83 * nor may "OpenSSL" appear in their names without prior written
84 * permission of the OpenSSL Project.
85 *
86 * 6. Redistributions of any form whatsoever must retain the following
87 * acknowledgment:
88 * "This product includes software developed by the OpenSSL Project
89 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
90 *
91 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
92 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
94 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
95 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
96 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
100 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
101 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
102 * OF THE POSSIBILITY OF SUCH DAMAGE.
103 * ====================================================================
104 *
105 * This product includes cryptographic software written by Eric Young
106 * (eay@cryptsoft.com). This product includes software written by Tim
107 * Hudson (tjh@cryptsoft.com).
108 *
109 */
110/* ====================================================================
111 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
112 * ECC cipher suite support in OpenSSL originally developed by
113 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
114
115#include <stdio.h>
116
117#include <openssl/bio.h>
118#include <openssl/bn.h>
David Benjamin676d1e72014-07-08 14:34:10 -0400119#include <openssl/buf.h>
Adam Langley95c29f32014-06-20 12:00:00 -0700120#include <openssl/dh.h>
121#include <openssl/err.h>
122#include <openssl/mem.h>
123#include <openssl/obj.h>
124#include <openssl/pem.h>
125#include <openssl/x509v3.h>
126
127#include "../crypto/dh/internal.h"
128#include "../crypto/directory.h"
129#include "ssl_locl.h"
130
131int SSL_get_ex_data_X509_STORE_CTX_idx(void)
132 {
133 static volatile int ssl_x509_store_ctx_idx= -1;
134 int got_write_lock = 0;
135
136 CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
137
138 if (ssl_x509_store_ctx_idx < 0)
139 {
140 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
141 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
142 got_write_lock = 1;
143
144 if (ssl_x509_store_ctx_idx < 0)
145 {
146 ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index(
147 0,"SSL for verify callback",NULL,NULL,NULL);
148 }
149 }
150
151 if (got_write_lock)
152 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
153 else
154 CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
155
156 return ssl_x509_store_ctx_idx;
157 }
158
159void ssl_cert_set_default_md(CERT *cert)
160 {
161 /* Set digest values to defaults */
162#ifndef OPENSSL_NO_DSA
163 cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
164#endif
Adam Langley95c29f32014-06-20 12:00:00 -0700165 cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
166 cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
Adam Langley95c29f32014-06-20 12:00:00 -0700167#ifndef OPENSSL_NO_ECDSA
168 cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
169#endif
170 }
171
172CERT *ssl_cert_new(void)
173 {
174 CERT *ret;
175
176 ret=(CERT *)OPENSSL_malloc(sizeof(CERT));
177 if (ret == NULL)
178 {
179 OPENSSL_PUT_ERROR(SSL, ssl_cert_new, ERR_R_MALLOC_FAILURE);
180 return(NULL);
181 }
182 memset(ret,0,sizeof(CERT));
183
184 ret->key= &(ret->pkeys[SSL_PKEY_RSA_ENC]);
Adam Langley95c29f32014-06-20 12:00:00 -0700185 ssl_cert_set_default_md(ret);
186 return(ret);
187 }
188
189CERT *ssl_cert_dup(CERT *cert)
190 {
191 CERT *ret;
192 int i;
193
194 ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
195 if (ret == NULL)
196 {
197 OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE);
198 return(NULL);
199 }
200
201 memset(ret, 0, sizeof(CERT));
202
203 ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
204 /* or ret->key = ret->pkeys + (cert->key - cert->pkeys),
205 * if you find that more readable */
206
207 ret->valid = cert->valid;
208 ret->mask_k = cert->mask_k;
209 ret->mask_a = cert->mask_a;
210 ret->export_mask_k = cert->export_mask_k;
211 ret->export_mask_a = cert->export_mask_a;
212
Adam Langley95c29f32014-06-20 12:00:00 -0700213 if (cert->rsa_tmp != NULL)
214 {
215 RSA_up_ref(cert->rsa_tmp);
216 ret->rsa_tmp = cert->rsa_tmp;
217 }
218 ret->rsa_tmp_cb = cert->rsa_tmp_cb;
Adam Langley95c29f32014-06-20 12:00:00 -0700219
220#ifndef OPENSSL_NO_DH
221 if (cert->dh_tmp != NULL)
222 {
223 ret->dh_tmp = DHparams_dup(cert->dh_tmp);
224 if (ret->dh_tmp == NULL)
225 {
226 OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_DH_LIB);
227 goto err;
228 }
229 if (cert->dh_tmp->priv_key)
230 {
231 BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
232 if (!b)
233 {
234 OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB);
235 goto err;
236 }
237 ret->dh_tmp->priv_key = b;
238 }
239 if (cert->dh_tmp->pub_key)
240 {
241 BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
242 if (!b)
243 {
244 OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB);
245 goto err;
246 }
247 ret->dh_tmp->pub_key = b;
248 }
249 }
250 ret->dh_tmp_cb = cert->dh_tmp_cb;
251#endif
252
253#ifndef OPENSSL_NO_ECDH
254 if (cert->ecdh_tmp)
255 {
256 ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
257 if (ret->ecdh_tmp == NULL)
258 {
259 OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_EC_LIB);
260 goto err;
261 }
262 }
263 ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
264 ret->ecdh_tmp_auto = cert->ecdh_tmp_auto;
265#endif
266
267 for (i = 0; i < SSL_PKEY_NUM; i++)
268 {
269 CERT_PKEY *cpk = cert->pkeys + i;
270 CERT_PKEY *rpk = ret->pkeys + i;
271 if (cpk->x509 != NULL)
272 {
273 rpk->x509 = cpk->x509;
274 CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509);
275 }
276
277 if (cpk->privatekey != NULL)
278 {
279 rpk->privatekey = cpk->privatekey;
280 CRYPTO_add(&cpk->privatekey->references, 1,
281 CRYPTO_LOCK_EVP_PKEY);
282
283 switch(i)
284 {
285 /* If there was anything special to do for
286 * certain types of keys, we'd do it here.
287 * (Nothing at the moment, I think.) */
288
289 case SSL_PKEY_RSA_ENC:
290 case SSL_PKEY_RSA_SIGN:
291 /* We have an RSA key. */
292 break;
293
294 case SSL_PKEY_DSA_SIGN:
295 /* We have a DSA key. */
296 break;
297
298 case SSL_PKEY_DH_RSA:
299 case SSL_PKEY_DH_DSA:
300 /* We have a DH key. */
301 break;
302
303 case SSL_PKEY_ECC:
304 /* We have an ECC key */
305 break;
306
307 default:
308 /* Can't happen. */
309 OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, SSL_R_LIBRARY_BUG);
310 }
311 }
312
313 if (cpk->chain)
314 {
315 rpk->chain = X509_chain_up_ref(cpk->chain);
316 if (!rpk->chain)
317 {
318 OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE);
319 goto err;
320 }
321 }
322 rpk->valid_flags = 0;
Adam Langley95c29f32014-06-20 12:00:00 -0700323 }
324
Adam Langley95c29f32014-06-20 12:00:00 -0700325 /* Set digests to defaults. NB: we don't copy existing values as they
326 * will be set during handshake.
327 */
328 ssl_cert_set_default_md(ret);
329 /* Peer sigalgs set to NULL as we get these from handshake too */
330 ret->peer_sigalgs = NULL;
331 ret->peer_sigalgslen = 0;
332 /* Configured sigalgs however we copy across */
333
334 if (cert->conf_sigalgs)
335 {
336 ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen);
337 if (!ret->conf_sigalgs)
338 goto err;
339 memcpy(ret->conf_sigalgs, cert->conf_sigalgs,
340 cert->conf_sigalgslen);
341 ret->conf_sigalgslen = cert->conf_sigalgslen;
342 }
343 else
344 ret->conf_sigalgs = NULL;
345
346 if (cert->client_sigalgs)
347 {
348 ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen);
349 if (!ret->client_sigalgs)
350 goto err;
351 memcpy(ret->client_sigalgs, cert->client_sigalgs,
352 cert->client_sigalgslen);
353 ret->client_sigalgslen = cert->client_sigalgslen;
354 }
355 else
356 ret->client_sigalgs = NULL;
357 /* Shared sigalgs also NULL */
358 ret->shared_sigalgs = NULL;
359 /* Copy any custom client certificate types */
David Benjamin676d1e72014-07-08 14:34:10 -0400360 if (cert->client_certificate_types)
Adam Langley95c29f32014-06-20 12:00:00 -0700361 {
David Benjamin676d1e72014-07-08 14:34:10 -0400362 ret->client_certificate_types = BUF_memdup(
363 cert->client_certificate_types,
364 cert->num_client_certificate_types);
365 if (!ret->client_certificate_types)
Adam Langley95c29f32014-06-20 12:00:00 -0700366 goto err;
David Benjamin676d1e72014-07-08 14:34:10 -0400367 ret->num_client_certificate_types = cert->num_client_certificate_types;
Adam Langley95c29f32014-06-20 12:00:00 -0700368 }
369
370 ret->cert_flags = cert->cert_flags;
371
372 ret->cert_cb = cert->cert_cb;
373 ret->cert_cb_arg = cert->cert_cb_arg;
374
375 if (cert->verify_store)
376 {
377 CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE);
378 ret->verify_store = cert->verify_store;
379 }
380
381 if (cert->chain_store)
382 {
383 CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE);
384 ret->chain_store = cert->chain_store;
385 }
386
387 ret->ciphers_raw = NULL;
388
389 return(ret);
390
391#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
392err:
393#endif
Adam Langley95c29f32014-06-20 12:00:00 -0700394 if (ret->rsa_tmp != NULL)
395 RSA_free(ret->rsa_tmp);
Adam Langley95c29f32014-06-20 12:00:00 -0700396#ifndef OPENSSL_NO_DH
397 if (ret->dh_tmp != NULL)
398 DH_free(ret->dh_tmp);
399#endif
400#ifndef OPENSSL_NO_ECDH
401 if (ret->ecdh_tmp != NULL)
402 EC_KEY_free(ret->ecdh_tmp);
403#endif
404
405 ssl_cert_clear_certs(ret);
406
407 return NULL;
408 }
409
410/* Free up and clear all certificates and chains */
411
412void ssl_cert_clear_certs(CERT *c)
413 {
414 int i;
415 if (c == NULL)
416 return;
417 for (i = 0; i<SSL_PKEY_NUM; i++)
418 {
419 CERT_PKEY *cpk = c->pkeys + i;
420 if (cpk->x509)
421 {
422 X509_free(cpk->x509);
423 cpk->x509 = NULL;
424 }
425 if (cpk->privatekey)
426 {
427 EVP_PKEY_free(cpk->privatekey);
428 cpk->privatekey = NULL;
429 }
430 if (cpk->chain)
431 {
432 sk_X509_pop_free(cpk->chain, X509_free);
433 cpk->chain = NULL;
434 }
Adam Langley95c29f32014-06-20 12:00:00 -0700435 /* Clear all flags apart from explicit sign */
436 cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
437 }
438 }
439
440void ssl_cert_free(CERT *c)
441 {
Adam Langley95c29f32014-06-20 12:00:00 -0700442 if(c == NULL)
443 return;
444
Adam Langley95c29f32014-06-20 12:00:00 -0700445 if (c->rsa_tmp) RSA_free(c->rsa_tmp);
Adam Langley95c29f32014-06-20 12:00:00 -0700446#ifndef OPENSSL_NO_DH
447 if (c->dh_tmp) DH_free(c->dh_tmp);
448#endif
449#ifndef OPENSSL_NO_ECDH
450 if (c->ecdh_tmp) EC_KEY_free(c->ecdh_tmp);
451#endif
452
453 ssl_cert_clear_certs(c);
454 if (c->peer_sigalgs)
455 OPENSSL_free(c->peer_sigalgs);
456 if (c->conf_sigalgs)
457 OPENSSL_free(c->conf_sigalgs);
458 if (c->client_sigalgs)
459 OPENSSL_free(c->client_sigalgs);
460 if (c->shared_sigalgs)
461 OPENSSL_free(c->shared_sigalgs);
David Benjamin676d1e72014-07-08 14:34:10 -0400462 if (c->client_certificate_types)
463 OPENSSL_free(c->client_certificate_types);
Adam Langley95c29f32014-06-20 12:00:00 -0700464 if (c->verify_store)
465 X509_STORE_free(c->verify_store);
466 if (c->chain_store)
467 X509_STORE_free(c->chain_store);
468 if (c->ciphers_raw)
469 OPENSSL_free(c->ciphers_raw);
470 OPENSSL_free(c);
471 }
472
473int ssl_cert_inst(CERT **o)
474 {
475 /* Create a CERT if there isn't already one
476 * (which cannot really happen, as it is initially created in
477 * SSL_CTX_new; but the earlier code usually allows for that one
478 * being non-existant, so we follow that behaviour, as it might
479 * turn out that there actually is a reason for it -- but I'm
480 * not sure that *all* of the existing code could cope with
481 * s->cert being NULL, otherwise we could do without the
482 * initialization in SSL_CTX_new).
483 */
484
485 if (o == NULL)
486 {
487 OPENSSL_PUT_ERROR(SSL, ssl_cert_inst, ERR_R_PASSED_NULL_PARAMETER);
488 return(0);
489 }
490 if (*o == NULL)
491 {
492 if ((*o = ssl_cert_new()) == NULL)
493 {
494 OPENSSL_PUT_ERROR(SSL, ssl_cert_new, ERR_R_MALLOC_FAILURE);
495 return(0);
496 }
497 }
498 return(1);
499 }
500
501int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain)
502 {
503 CERT_PKEY *cpk = c->key;
504 if (!cpk)
505 return 0;
506 if (cpk->chain)
507 sk_X509_pop_free(cpk->chain, X509_free);
508 cpk->chain = chain;
509 return 1;
510 }
511
512int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
513 {
514 STACK_OF(X509) *dchain;
515 if (!chain)
516 return ssl_cert_set0_chain(c, NULL);
517 dchain = X509_chain_up_ref(chain);
518 if (!dchain)
519 return 0;
520 if (!ssl_cert_set0_chain(c, dchain))
521 {
522 sk_X509_pop_free(dchain, X509_free);
523 return 0;
524 }
525 return 1;
526 }
527
528int ssl_cert_add0_chain_cert(CERT *c, X509 *x)
529 {
530 CERT_PKEY *cpk = c->key;
531 if (!cpk)
532 return 0;
533 if (!cpk->chain)
534 cpk->chain = sk_X509_new_null();
535 if (!cpk->chain || !sk_X509_push(cpk->chain, x))
536 return 0;
537 return 1;
538 }
539
540int ssl_cert_add1_chain_cert(CERT *c, X509 *x)
541 {
542 if (!ssl_cert_add0_chain_cert(c, x))
543 return 0;
544 CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
545 return 1;
546 }
547
548int ssl_cert_select_current(CERT *c, X509 *x)
549 {
550 int i;
551 if (x == NULL)
552 return 0;
553 for (i = 0; i < SSL_PKEY_NUM; i++)
554 {
555 if (c->pkeys[i].x509 == x)
556 {
557 c->key = &c->pkeys[i];
558 return 1;
559 }
560 }
561
562 for (i = 0; i < SSL_PKEY_NUM; i++)
563 {
564 if (c->pkeys[i].x509 && !X509_cmp(c->pkeys[i].x509, x))
565 {
566 c->key = &c->pkeys[i];
567 return 1;
568 }
569 }
570 return 0;
571 }
572
573void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg)
574 {
575 c->cert_cb = cb;
576 c->cert_cb_arg = arg;
577 }
578
579SESS_CERT *ssl_sess_cert_new(void)
580 {
581 SESS_CERT *ret;
582
583 ret = OPENSSL_malloc(sizeof *ret);
584 if (ret == NULL)
585 {
586 OPENSSL_PUT_ERROR(SSL, ssl_sess_cert_new, ERR_R_MALLOC_FAILURE);
587 return NULL;
588 }
589
590 memset(ret, 0 ,sizeof *ret);
591 ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
592 ret->references = 1;
593
594 return ret;
595 }
596
597void ssl_sess_cert_free(SESS_CERT *sc)
598 {
599 int i;
600
601 if (sc == NULL)
602 return;
603
604 i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
605#ifdef REF_PRINT
606 REF_PRINT("SESS_CERT", sc);
607#endif
608 if (i > 0)
609 return;
610#ifdef REF_CHECK
611 if (i < 0)
612 {
613 fprintf(stderr,"ssl_sess_cert_free, bad reference count\n");
614 abort(); /* ok */
615 }
616#endif
617
618 /* i == 0 */
619 if (sc->cert_chain != NULL)
620 sk_X509_pop_free(sc->cert_chain, X509_free);
621 for (i = 0; i < SSL_PKEY_NUM; i++)
622 {
623 if (sc->peer_pkeys[i].x509 != NULL)
624 X509_free(sc->peer_pkeys[i].x509);
625#if 0 /* We don't have the peer's private key. These lines are just
626 * here as a reminder that we're still using a not-quite-appropriate
627 * data structure. */
628 if (sc->peer_pkeys[i].privatekey != NULL)
629 EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
630#endif
631 }
632
Adam Langley95c29f32014-06-20 12:00:00 -0700633 if (sc->peer_rsa_tmp != NULL)
634 RSA_free(sc->peer_rsa_tmp);
Adam Langley95c29f32014-06-20 12:00:00 -0700635#ifndef OPENSSL_NO_DH
636 if (sc->peer_dh_tmp != NULL)
637 DH_free(sc->peer_dh_tmp);
638#endif
639#ifndef OPENSSL_NO_ECDH
640 if (sc->peer_ecdh_tmp != NULL)
641 EC_KEY_free(sc->peer_ecdh_tmp);
642#endif
643
644 OPENSSL_free(sc);
645 }
646
647int ssl_set_peer_cert_type(SESS_CERT *sc,int type)
648 {
649 sc->peer_cert_type = type;
650 return(1);
651 }
652
Adam Langley95c29f32014-06-20 12:00:00 -0700653int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk)
654 {
655 X509 *x;
656 int i;
657 X509_STORE *verify_store;
658 X509_STORE_CTX ctx;
659
660 if (s->cert->verify_store)
661 verify_store = s->cert->verify_store;
662 else
663 verify_store = s->ctx->cert_store;
664
665 if ((sk == NULL) || (sk_X509_num(sk) == 0))
666 return(0);
667
668 x=sk_X509_value(sk,0);
669 if(!X509_STORE_CTX_init(&ctx,verify_store,x,sk))
670 {
671 OPENSSL_PUT_ERROR(SSL, ssl_verify_cert_chain, ERR_R_X509_LIB);
672 return(0);
673 }
674 /* Set suite B flags if needed */
675 X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s));
676#if 0
677 if (SSL_get_verify_depth(s) >= 0)
678 X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
679#endif
680 X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s);
681
682 /* We need to inherit the verify parameters. These can be determined by
683 * the context: if its a server it will verify SSL client certificates
684 * or vice versa.
685 */
686
687 X509_STORE_CTX_set_default(&ctx,
688 s->server ? "ssl_client" : "ssl_server");
689 /* Anything non-default in "param" should overwrite anything in the
690 * ctx.
691 */
692 X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
693
Adam Langley95c29f32014-06-20 12:00:00 -0700694 if (s->verify_callback)
695 X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
Adam Langley95c29f32014-06-20 12:00:00 -0700696
697 if (s->ctx->app_verify_callback != NULL)
698#if 1 /* new with OpenSSL 0.9.7 */
699 i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
700#else
701 i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
702#endif
703 else
704 {
705#ifndef OPENSSL_NO_X509_VERIFY
706 i=X509_verify_cert(&ctx);
707#else
708 i=0;
709 ctx.error=X509_V_ERR_APPLICATION_VERIFICATION;
710 OPENSSL_PUT_ERROR(SSL, ssl_verify_cert_chain, SSL_R_NO_VERIFY_CALLBACK);
711#endif
712 }
713
714 s->verify_result=ctx.error;
715 X509_STORE_CTX_cleanup(&ctx);
716
717 return(i);
718 }
719
720static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
721 {
722 if (*ca_list != NULL)
723 sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
724
725 *ca_list=name_list;
726 }
727
728STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
729 {
730 int i;
731 STACK_OF(X509_NAME) *ret;
732 X509_NAME *name;
733
734 ret=sk_X509_NAME_new_null();
735 for (i=0; i<sk_X509_NAME_num(sk); i++)
736 {
737 name=X509_NAME_dup(sk_X509_NAME_value(sk,i));
738 if ((name == NULL) || !sk_X509_NAME_push(ret,name))
739 {
740 sk_X509_NAME_pop_free(ret,X509_NAME_free);
741 return(NULL);
742 }
743 }
744 return(ret);
745 }
746
747void SSL_set_client_CA_list(SSL *s,STACK_OF(X509_NAME) *name_list)
748 {
749 set_client_CA_list(&(s->client_CA),name_list);
750 }
751
752void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,STACK_OF(X509_NAME) *name_list)
753 {
754 set_client_CA_list(&(ctx->client_CA),name_list);
755 }
756
757STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
758 {
759 return(ctx->client_CA);
760 }
761
762STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
763 {
764 if (s->type == SSL_ST_CONNECT)
765 { /* we are in the client */
766 if (((s->version>>8) == SSL3_VERSION_MAJOR) &&
767 (s->s3 != NULL))
768 return(s->s3->tmp.ca_names);
769 else
770 return(NULL);
771 }
772 else
773 {
774 if (s->client_CA != NULL)
775 return(s->client_CA);
776 else
777 return(s->ctx->client_CA);
778 }
779 }
780
781static int add_client_CA(STACK_OF(X509_NAME) **sk,X509 *x)
782 {
783 X509_NAME *name;
784
785 if (x == NULL) return(0);
786 if ((*sk == NULL) && ((*sk=sk_X509_NAME_new_null()) == NULL))
787 return(0);
788
789 if ((name=X509_NAME_dup(X509_get_subject_name(x))) == NULL)
790 return(0);
791
792 if (!sk_X509_NAME_push(*sk,name))
793 {
794 X509_NAME_free(name);
795 return(0);
796 }
797 return(1);
798 }
799
800int SSL_add_client_CA(SSL *ssl,X509 *x)
801 {
802 return(add_client_CA(&(ssl->client_CA),x));
803 }
804
805int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x)
806 {
807 return(add_client_CA(&(ctx->client_CA),x));
808 }
809
Adam Langley28acbbc2014-06-20 12:00:00 -0700810void SSL_get_client_certificate_types(const SSL *s, const unsigned char **ctype,
811 size_t *ctype_num)
812 {
David Benjamin5c57c602014-06-21 12:52:18 -0400813 /* TODO(fork): Remove this function once Chromium is updated
814 * to use the new one. */
815 *ctype_num = SSL_get0_certificate_types((SSL*)s, ctype);
Adam Langley28acbbc2014-06-20 12:00:00 -0700816 }
817
Adam Langley95c29f32014-06-20 12:00:00 -0700818static int xname_cmp(const X509_NAME **a, const X509_NAME **b)
819 {
820 return(X509_NAME_cmp(*a,*b));
821 }
822
823#ifndef OPENSSL_NO_STDIO
824/*!
825 * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
826 * it doesn't really have anything to do with clients (except that a common use
827 * for a stack of CAs is to send it to the client). Actually, it doesn't have
828 * much to do with CAs, either, since it will load any old cert.
829 * \param file the file containing one or more certs.
830 * \return a ::STACK containing the certs.
831 */
832STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
833 {
834 BIO *in;
835 X509 *x=NULL;
836 X509_NAME *xn=NULL;
837 STACK_OF(X509_NAME) *ret = NULL,*sk;
838
839 sk=sk_X509_NAME_new(xname_cmp);
840
841 in=BIO_new(BIO_s_file());
842
843 if ((sk == NULL) || (in == NULL))
844 {
845 OPENSSL_PUT_ERROR(SSL, SSL_load_client_CA_file, ERR_R_MALLOC_FAILURE);
846 goto err;
847 }
848
849 if (!BIO_read_filename(in,file))
850 goto err;
851
852 for (;;)
853 {
854 if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
855 break;
856 if (ret == NULL)
857 {
858 ret = sk_X509_NAME_new_null();
859 if (ret == NULL)
860 {
861 OPENSSL_PUT_ERROR(SSL, SSL_load_client_CA_file, ERR_R_MALLOC_FAILURE);
862 goto err;
863 }
864 }
865 if ((xn=X509_get_subject_name(x)) == NULL) goto err;
866 /* check for duplicates */
867 xn=X509_NAME_dup(xn);
868 if (xn == NULL) goto err;
869 if (sk_X509_NAME_find(sk, NULL, xn))
870 X509_NAME_free(xn);
871 else
872 {
873 sk_X509_NAME_push(sk,xn);
874 sk_X509_NAME_push(ret,xn);
875 }
876 }
877
878 if (0)
879 {
880err:
881 if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free);
882 ret=NULL;
883 }
884 if (sk != NULL) sk_X509_NAME_free(sk);
885 if (in != NULL) BIO_free(in);
886 if (x != NULL) X509_free(x);
887 if (ret != NULL)
888 ERR_clear_error();
889 return(ret);
890 }
891#endif
892
893/*!
894 * Add a file of certs to a stack.
895 * \param stack the stack to add to.
896 * \param file the file to add from. All certs in this file that are not
897 * already in the stack will be added.
898 * \return 1 for success, 0 for failure. Note that in the case of failure some
899 * certs may have been added to \c stack.
900 */
901
902int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
903 const char *file)
904 {
905 BIO *in;
906 X509 *x=NULL;
907 X509_NAME *xn=NULL;
908 int ret=1;
909 int (*oldcmp)(const X509_NAME **a, const X509_NAME **b);
910
911 oldcmp=sk_X509_NAME_set_cmp_func(stack,xname_cmp);
912
913 in=BIO_new(BIO_s_file());
914
915 if (in == NULL)
916 {
917 OPENSSL_PUT_ERROR(SSL, SSL_add_file_cert_subjects_to_stack, ERR_R_MALLOC_FAILURE);
918 goto err;
919 }
920
921 if (!BIO_read_filename(in,file))
922 goto err;
923
924 for (;;)
925 {
926 if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL)
927 break;
928 if ((xn=X509_get_subject_name(x)) == NULL) goto err;
929 xn=X509_NAME_dup(xn);
930 if (xn == NULL) goto err;
931 if (sk_X509_NAME_find(stack, NULL, xn))
932 X509_NAME_free(xn);
933 else
934 sk_X509_NAME_push(stack,xn);
935 }
936
937 ERR_clear_error();
938
939 if (0)
940 {
941err:
942 ret=0;
943 }
944 if(in != NULL)
945 BIO_free(in);
946 if(x != NULL)
947 X509_free(x);
948
949 (void)sk_X509_NAME_set_cmp_func(stack,oldcmp);
950
951 return ret;
952 }
953
954/*!
955 * Add a directory of certs to a stack.
956 * \param stack the stack to append to.
957 * \param dir the directory to append from. All files in this directory will be
958 * examined as potential certs. Any that are acceptable to
959 * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
960 * included.
961 * \return 1 for success, 0 for failure. Note that in the case of failure some
962 * certs may have been added to \c stack.
963 */
964
965int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
966 const char *dir)
967 {
968 OPENSSL_DIR_CTX *d = NULL;
969 const char *filename;
970 int ret = 0;
971
972 CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
973
974 /* Note that a side effect is that the CAs will be sorted by name */
975
976 while((filename = OPENSSL_DIR_read(&d, dir)))
977 {
978 char buf[1024];
979 int r;
980
981 if(strlen(dir)+strlen(filename)+2 > sizeof buf)
982 {
983 OPENSSL_PUT_ERROR(SSL, SSL_add_dir_cert_subjects_to_stack, SSL_R_PATH_TOO_LONG);
984 goto err;
985 }
986
987#ifdef OPENSSL_SYS_VMS
988 r = BIO_snprintf(buf,sizeof buf,"%s%s",dir,filename);
989#else
990 r = BIO_snprintf(buf,sizeof buf,"%s/%s",dir,filename);
991#endif
992 if (r <= 0 || r >= (int)sizeof(buf))
993 goto err;
994 if(!SSL_add_file_cert_subjects_to_stack(stack,buf))
995 goto err;
996 }
997
998 if (errno)
999 {
1000 OPENSSL_PUT_ERROR(SSL, SSL_add_file_cert_subjects_to_stack, ERR_R_SYS_LIB);
1001 ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
1002 goto err;
1003 }
1004
1005 ret = 1;
1006
1007err:
1008 if (d) OPENSSL_DIR_end(&d);
1009 CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
1010 return ret;
1011 }
1012
1013/* Add a certificate to a BUF_MEM structure */
1014
1015static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
1016 {
1017 int n;
1018 unsigned char *p;
1019
1020 n=i2d_X509(x,NULL);
1021 if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
1022 {
1023 OPENSSL_PUT_ERROR(SSL, ssl_add_cert_to_buf, ERR_R_BUF_LIB);
1024 return 0;
1025 }
1026 p=(unsigned char *)&(buf->data[*l]);
1027 l2n3(n,p);
1028 i2d_X509(x,&p);
1029 *l+=n+3;
1030
1031 return 1;
1032 }
1033
1034/* Add certificate chain to internal SSL BUF_MEM strcuture */
1035int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
1036 {
1037 BUF_MEM *buf = s->init_buf;
1038 int no_chain;
1039 int i;
1040
1041 X509 *x;
1042 STACK_OF(X509) *extra_certs;
1043 X509_STORE *chain_store;
1044
1045 if (cpk)
1046 x = cpk->x509;
1047 else
1048 x = NULL;
1049
1050 if (s->cert->chain_store)
1051 chain_store = s->cert->chain_store;
1052 else
1053 chain_store = s->ctx->cert_store;
1054
1055 /* If we have a certificate specific chain use it, else use
1056 * parent ctx.
1057 */
1058 if (cpk && cpk->chain)
1059 extra_certs = cpk->chain;
1060 else
1061 extra_certs = s->ctx->extra_certs;
1062
1063 if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs)
1064 no_chain = 1;
1065 else
1066 no_chain = 0;
1067
1068 /* TLSv1 sends a chain with nothing in it, instead of an alert */
1069 if (!BUF_MEM_grow_clean(buf,10))
1070 {
1071 OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, ERR_R_BUF_LIB);
1072 return 0;
1073 }
1074 if (x != NULL)
1075 {
1076 if (no_chain)
1077 {
1078 if (!ssl_add_cert_to_buf(buf, l, x))
1079 return 0;
1080 }
1081 else
1082 {
1083 X509_STORE_CTX xs_ctx;
1084
1085 if (!X509_STORE_CTX_init(&xs_ctx,chain_store,x,NULL))
1086 {
1087 OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, ERR_R_X509_LIB);
1088 return(0);
1089 }
1090 X509_verify_cert(&xs_ctx);
1091 /* Don't leave errors in the queue */
1092 ERR_clear_error();
1093 for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
1094 {
1095 x = sk_X509_value(xs_ctx.chain, i);
1096
1097 if (!ssl_add_cert_to_buf(buf, l, x))
1098 {
1099 X509_STORE_CTX_cleanup(&xs_ctx);
1100 return 0;
1101 }
1102 }
1103 X509_STORE_CTX_cleanup(&xs_ctx);
1104 }
1105 }
1106 for (i=0; i<sk_X509_num(extra_certs); i++)
1107 {
1108 x=sk_X509_value(extra_certs,i);
1109 if (!ssl_add_cert_to_buf(buf, l, x))
1110 return 0;
1111 }
1112
1113 return 1;
1114 }
1115
1116/* Build a certificate chain for current certificate */
1117int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags)
1118 {
1119 CERT_PKEY *cpk = c->key;
1120 X509_STORE_CTX xs_ctx;
1121 STACK_OF(X509) *chain = NULL, *untrusted = NULL;
1122 X509 *x;
Adam Langleyf669c2d2014-06-20 12:00:00 -07001123 int i, rv = 0;
Adam Langleydff7b9e2014-06-20 12:00:00 -07001124 unsigned long error;
Adam Langley95c29f32014-06-20 12:00:00 -07001125
1126 if (!cpk->x509)
1127 {
1128 OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain, SSL_R_NO_CERTIFICATE_SET);
Adam Langleyf669c2d2014-06-20 12:00:00 -07001129 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -07001130 }
Adam Langleyf669c2d2014-06-20 12:00:00 -07001131 /* Rearranging and check the chain: add everything to a store */
1132 if (flags & SSL_BUILD_CHAIN_FLAG_CHECK)
1133 {
1134 chain_store = X509_STORE_new();
1135 if (!chain_store)
1136 goto err;
1137 for (i = 0; i < sk_X509_num(cpk->chain); i++)
1138 {
1139 x = sk_X509_value(cpk->chain, i);
1140 if (!X509_STORE_add_cert(chain_store, x))
Adam Langleydff7b9e2014-06-20 12:00:00 -07001141 {
1142 error = ERR_peek_last_error();
1143 if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
1144 ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE)
1145 goto err;
1146 ERR_clear_error();
1147 }
Adam Langleyf669c2d2014-06-20 12:00:00 -07001148 }
1149 /* Add EE cert too: it might be self signed */
1150 if (!X509_STORE_add_cert(chain_store, cpk->x509))
Adam Langleydff7b9e2014-06-20 12:00:00 -07001151 {
1152 error = ERR_peek_last_error();
1153 if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
1154 ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE)
1155 goto err;
1156 ERR_clear_error();
1157 }
Adam Langleyf669c2d2014-06-20 12:00:00 -07001158 }
1159 else
1160 {
1161 if (c->chain_store)
1162 chain_store = c->chain_store;
Adam Langley95c29f32014-06-20 12:00:00 -07001163
Adam Langleyf669c2d2014-06-20 12:00:00 -07001164 if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED)
1165 untrusted = cpk->chain;
1166 }
Adam Langley95c29f32014-06-20 12:00:00 -07001167
1168 if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted))
1169 {
1170 OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain, ERR_R_X509_LIB);
Adam Langleyf669c2d2014-06-20 12:00:00 -07001171 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -07001172 }
1173 /* Set suite B flags if needed */
1174 X509_STORE_CTX_set_flags(&xs_ctx, c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS);
1175
1176 i = X509_verify_cert(&xs_ctx);
Adam Langleyf669c2d2014-06-20 12:00:00 -07001177 if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR)
1178 {
Adam Langley64c22232014-06-20 12:00:00 -07001179 if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR)
1180 ERR_clear_error();
Adam Langleyf669c2d2014-06-20 12:00:00 -07001181 i = 1;
Adam Langley64c22232014-06-20 12:00:00 -07001182 rv = 2;
Adam Langleyf669c2d2014-06-20 12:00:00 -07001183 }
Adam Langley95c29f32014-06-20 12:00:00 -07001184 if (i > 0)
1185 chain = X509_STORE_CTX_get1_chain(&xs_ctx);
Adam Langley95c29f32014-06-20 12:00:00 -07001186 if (i <= 0)
1187 {
1188 OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain, SSL_R_CERTIFICATE_VERIFY_FAILED);
Adam Langleyf669c2d2014-06-20 12:00:00 -07001189 i = X509_STORE_CTX_get_error(&xs_ctx);
1190 ERR_add_error_data(2, "Verify error:",
1191 X509_verify_cert_error_string(i));
1192
1193 X509_STORE_CTX_cleanup(&xs_ctx);
1194 goto err;
Adam Langley95c29f32014-06-20 12:00:00 -07001195 }
Adam Langleyf669c2d2014-06-20 12:00:00 -07001196 X509_STORE_CTX_cleanup(&xs_ctx);
Adam Langley95c29f32014-06-20 12:00:00 -07001197 if (cpk->chain)
1198 sk_X509_pop_free(cpk->chain, X509_free);
1199 /* Remove EE certificate from chain */
1200 x = sk_X509_shift(chain);
1201 X509_free(x);
1202 if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT)
1203 {
Adam Langleyf669c2d2014-06-20 12:00:00 -07001204 if (sk_X509_num(chain) > 0)
1205 {
1206 /* See if last cert is self signed */
1207 x = sk_X509_value(chain, sk_X509_num(chain) - 1);
1208 X509_check_purpose(x, -1, 0);
1209 if (x->ex_flags & EXFLAG_SS)
1210 {
1211 x = sk_X509_pop(chain);
1212 X509_free(x);
1213 }
1214 }
Adam Langley95c29f32014-06-20 12:00:00 -07001215 }
1216 cpk->chain = chain;
Adam Langley64c22232014-06-20 12:00:00 -07001217 if (rv == 0)
1218 rv = 1;
Adam Langleyf669c2d2014-06-20 12:00:00 -07001219 err:
1220 if (flags & SSL_BUILD_CHAIN_FLAG_CHECK)
1221 X509_STORE_free(chain_store);
Adam Langley95c29f32014-06-20 12:00:00 -07001222
Adam Langleyf669c2d2014-06-20 12:00:00 -07001223 return rv;
Adam Langley95c29f32014-06-20 12:00:00 -07001224 }
1225
1226int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
1227 {
1228 X509_STORE **pstore;
1229 if (chain)
1230 pstore = &c->chain_store;
1231 else
1232 pstore = &c->verify_store;
1233 if (*pstore)
1234 X509_STORE_free(*pstore);
1235 *pstore = store;
1236 if (ref && store)
1237 CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
1238 return 1;
1239 }
1240