1280297Sjkim/*
2280297Sjkim * ! \file ssl/ssl_cert.c
3280297Sjkim */
455714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
555714Skris * All rights reserved.
655714Skris *
755714Skris * This package is an SSL implementation written
855714Skris * by Eric Young (eay@cryptsoft.com).
955714Skris * The implementation was written so as to conform with Netscapes SSL.
10280297Sjkim *
1155714Skris * This library is free for commercial and non-commercial use as long as
1255714Skris * the following conditions are aheared to.  The following conditions
1355714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1455714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1555714Skris * included with this distribution is covered by the same copyright terms
1655714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
17280297Sjkim *
1855714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1955714Skris * the code are not to be removed.
2055714Skris * If this package is used in a product, Eric Young should be given attribution
2155714Skris * as the author of the parts of the library used.
2255714Skris * This can be in the form of a textual message at program startup or
2355714Skris * in documentation (online or textual) provided with the package.
24280297Sjkim *
2555714Skris * Redistribution and use in source and binary forms, with or without
2655714Skris * modification, are permitted provided that the following conditions
2755714Skris * are met:
2855714Skris * 1. Redistributions of source code must retain the copyright
2955714Skris *    notice, this list of conditions and the following disclaimer.
3055714Skris * 2. Redistributions in binary form must reproduce the above copyright
3155714Skris *    notice, this list of conditions and the following disclaimer in the
3255714Skris *    documentation and/or other materials provided with the distribution.
3355714Skris * 3. All advertising materials mentioning features or use of this software
3455714Skris *    must display the following acknowledgement:
3555714Skris *    "This product includes cryptographic software written by
3655714Skris *     Eric Young (eay@cryptsoft.com)"
3755714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3855714Skris *    being used are not cryptographic related :-).
39280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from
4055714Skris *    the apps directory (application code) you must include an acknowledgement:
4155714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
42280297Sjkim *
4355714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4455714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4555714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4655714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4755714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4855714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4955714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5055714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5155714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5255714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5355714Skris * SUCH DAMAGE.
54280297Sjkim *
5555714Skris * The licence and distribution terms for any publically available version or
5655714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5755714Skris * copied and put under another distribution licence
5855714Skris * [including the GNU Public Licence.]
5955714Skris */
6055714Skris/* ====================================================================
61238405Sjkim * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
6255714Skris *
6355714Skris * Redistribution and use in source and binary forms, with or without
6455714Skris * modification, are permitted provided that the following conditions
6555714Skris * are met:
6655714Skris *
6755714Skris * 1. Redistributions of source code must retain the above copyright
68280297Sjkim *    notice, this list of conditions and the following disclaimer.
6955714Skris *
7055714Skris * 2. Redistributions in binary form must reproduce the above copyright
7155714Skris *    notice, this list of conditions and the following disclaimer in
7255714Skris *    the documentation and/or other materials provided with the
7355714Skris *    distribution.
7455714Skris *
7555714Skris * 3. All advertising materials mentioning features or use of this
7655714Skris *    software must display the following acknowledgment:
7755714Skris *    "This product includes software developed by the OpenSSL Project
78162911Ssimon *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
7955714Skris *
8055714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
8155714Skris *    endorse or promote products derived from this software without
8255714Skris *    prior written permission. For written permission, please contact
83162911Ssimon *    openssl-core@openssl.org.
8455714Skris *
8555714Skris * 5. Products derived from this software may not be called "OpenSSL"
8655714Skris *    nor may "OpenSSL" appear in their names without prior written
8755714Skris *    permission of the OpenSSL Project.
8855714Skris *
8955714Skris * 6. Redistributions of any form whatsoever must retain the following
9055714Skris *    acknowledgment:
9155714Skris *    "This product includes software developed by the OpenSSL Project
92162911Ssimon *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
9355714Skris *
9455714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9555714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9655714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9755714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9855714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9955714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
10055714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10155714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10255714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10355714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10455714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10555714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
10655714Skris * ====================================================================
107162911Ssimon *
108162911Ssimon * This product includes cryptographic software written by Eric Young
109162911Ssimon * (eay@cryptsoft.com).  This product includes software written by Tim
110162911Ssimon * Hudson (tjh@cryptsoft.com).
111162911Ssimon *
11255714Skris */
113160814Ssimon/* ====================================================================
114160814Ssimon * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
115280297Sjkim * ECC cipher suite support in OpenSSL originally developed by
116160814Ssimon * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
117160814Ssimon */
11855714Skris
11955714Skris#include <stdio.h>
12059191Skris
121109998Smarkm#include "e_os.h"
12259191Skris#ifndef NO_SYS_TYPES_H
12359191Skris# include <sys/types.h>
12459191Skris#endif
12559191Skris
126160814Ssimon#include "o_dir.h"
12755714Skris#include <openssl/objects.h>
12855714Skris#include <openssl/bio.h>
12955714Skris#include <openssl/pem.h>
13059191Skris#include <openssl/x509v3.h>
131160814Ssimon#ifndef OPENSSL_NO_DH
132280297Sjkim# include <openssl/dh.h>
133160814Ssimon#endif
134160814Ssimon#include <openssl/bn.h>
13555714Skris#include "ssl_locl.h"
13655714Skris
13755714Skrisint SSL_get_ex_data_X509_STORE_CTX_idx(void)
138280297Sjkim{
139280297Sjkim    static volatile int ssl_x509_store_ctx_idx = -1;
140280297Sjkim    int got_write_lock = 0;
14155714Skris
142290207Sjkim    if (((size_t)&ssl_x509_store_ctx_idx &
143290207Sjkim         (sizeof(ssl_x509_store_ctx_idx) - 1))
144290207Sjkim        == 0) {                 /* check alignment, practically always true */
145290207Sjkim        int ret;
146162911Ssimon
147290207Sjkim        if ((ret = ssl_x509_store_ctx_idx) < 0) {
148290207Sjkim            CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
149290207Sjkim            if ((ret = ssl_x509_store_ctx_idx) < 0) {
150290207Sjkim                ret = ssl_x509_store_ctx_idx =
151290207Sjkim                    X509_STORE_CTX_get_ex_new_index(0,
152290207Sjkim                                                    "SSL for verify callback",
153290207Sjkim                                                    NULL, NULL, NULL);
154290207Sjkim            }
155290207Sjkim            CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
156290207Sjkim        }
157162911Ssimon
158290207Sjkim        return ret;
159290207Sjkim    } else {                    /* commonly eliminated */
160290207Sjkim
161290207Sjkim        CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
162290207Sjkim
163280297Sjkim        if (ssl_x509_store_ctx_idx < 0) {
164290207Sjkim            CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
165290207Sjkim            CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
166290207Sjkim            got_write_lock = 1;
167290207Sjkim
168290207Sjkim            if (ssl_x509_store_ctx_idx < 0) {
169290207Sjkim                ssl_x509_store_ctx_idx =
170290207Sjkim                    X509_STORE_CTX_get_ex_new_index(0,
171290207Sjkim                                                    "SSL for verify callback",
172290207Sjkim                                                    NULL, NULL, NULL);
173290207Sjkim            }
174280297Sjkim        }
17555714Skris
176290207Sjkim        if (got_write_lock)
177290207Sjkim            CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
178290207Sjkim        else
179290207Sjkim            CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
180280297Sjkim
181290207Sjkim        return ssl_x509_store_ctx_idx;
182290207Sjkim    }
183280297Sjkim}
184280297Sjkim
185290207Sjkimvoid ssl_cert_set_default_md(CERT *cert)
186280297Sjkim{
187280297Sjkim    /* Set digest values to defaults */
188238405Sjkim#ifndef OPENSSL_NO_DSA
189280297Sjkim    cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
190238405Sjkim#endif
191238405Sjkim#ifndef OPENSSL_NO_RSA
192280297Sjkim    cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
193280297Sjkim    cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
194238405Sjkim#endif
195238405Sjkim#ifndef OPENSSL_NO_ECDSA
196280297Sjkim    cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
197238405Sjkim#endif
198280297Sjkim}
199238405Sjkim
20055714SkrisCERT *ssl_cert_new(void)
201280297Sjkim{
202280297Sjkim    CERT *ret;
20355714Skris
204280297Sjkim    ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
205280297Sjkim    if (ret == NULL) {
206280297Sjkim        SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE);
207280297Sjkim        return (NULL);
208280297Sjkim    }
209280297Sjkim    memset(ret, 0, sizeof(CERT));
21055714Skris
211280297Sjkim    ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]);
212280297Sjkim    ret->references = 1;
213280297Sjkim    ssl_cert_set_default_md(ret);
214280297Sjkim    return (ret);
215280297Sjkim}
21655714Skris
21755714SkrisCERT *ssl_cert_dup(CERT *cert)
218280297Sjkim{
219280297Sjkim    CERT *ret;
220280297Sjkim    int i;
22155714Skris
222280297Sjkim    ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
223280297Sjkim    if (ret == NULL) {
224280297Sjkim        SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
225280297Sjkim        return (NULL);
226280297Sjkim    }
22755714Skris
228280297Sjkim    memset(ret, 0, sizeof(CERT));
22955714Skris
230291719Sjkim    ret->references = 1;
231280297Sjkim    ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
232280297Sjkim    /*
233280297Sjkim     * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that
234280297Sjkim     * more readable
235280297Sjkim     */
23655714Skris
237280297Sjkim    ret->valid = cert->valid;
238280297Sjkim    ret->mask_k = cert->mask_k;
239280297Sjkim    ret->mask_a = cert->mask_a;
240280297Sjkim    ret->export_mask_k = cert->export_mask_k;
241280297Sjkim    ret->export_mask_a = cert->export_mask_a;
24255714Skris
243109998Smarkm#ifndef OPENSSL_NO_RSA
244280297Sjkim    if (cert->rsa_tmp != NULL) {
245280297Sjkim        RSA_up_ref(cert->rsa_tmp);
246280297Sjkim        ret->rsa_tmp = cert->rsa_tmp;
247280297Sjkim    }
248280297Sjkim    ret->rsa_tmp_cb = cert->rsa_tmp_cb;
24955714Skris#endif
25055714Skris
251109998Smarkm#ifndef OPENSSL_NO_DH
252280297Sjkim    if (cert->dh_tmp != NULL) {
253280297Sjkim        ret->dh_tmp = DHparams_dup(cert->dh_tmp);
254280297Sjkim        if (ret->dh_tmp == NULL) {
255280297Sjkim            SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
256280297Sjkim            goto err;
257280297Sjkim        }
258280297Sjkim        if (cert->dh_tmp->priv_key) {
259280297Sjkim            BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
260280297Sjkim            if (!b) {
261280297Sjkim                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
262280297Sjkim                goto err;
263280297Sjkim            }
264280297Sjkim            ret->dh_tmp->priv_key = b;
265280297Sjkim        }
266280297Sjkim        if (cert->dh_tmp->pub_key) {
267280297Sjkim            BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
268280297Sjkim            if (!b) {
269280297Sjkim                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
270280297Sjkim                goto err;
271280297Sjkim            }
272280297Sjkim            ret->dh_tmp->pub_key = b;
273280297Sjkim        }
274280297Sjkim    }
275280297Sjkim    ret->dh_tmp_cb = cert->dh_tmp_cb;
27655714Skris#endif
27755714Skris
278160814Ssimon#ifndef OPENSSL_NO_ECDH
279280297Sjkim    if (cert->ecdh_tmp) {
280280297Sjkim        ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
281280297Sjkim        if (ret->ecdh_tmp == NULL) {
282280297Sjkim            SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
283280297Sjkim            goto err;
284280297Sjkim        }
285280297Sjkim    }
286280297Sjkim    ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
287290207Sjkim    ret->ecdh_tmp_auto = cert->ecdh_tmp_auto;
288160814Ssimon#endif
289160814Ssimon
290280297Sjkim    for (i = 0; i < SSL_PKEY_NUM; i++) {
291290207Sjkim        CERT_PKEY *cpk = cert->pkeys + i;
292290207Sjkim        CERT_PKEY *rpk = ret->pkeys + i;
293290207Sjkim        if (cpk->x509 != NULL) {
294290207Sjkim            rpk->x509 = cpk->x509;
295290207Sjkim            CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509);
296280297Sjkim        }
29755714Skris
298290207Sjkim        if (cpk->privatekey != NULL) {
299290207Sjkim            rpk->privatekey = cpk->privatekey;
300290207Sjkim            CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY);
301280297Sjkim        }
302290207Sjkim
303290207Sjkim        if (cpk->chain) {
304290207Sjkim            rpk->chain = X509_chain_up_ref(cpk->chain);
305290207Sjkim            if (!rpk->chain) {
306290207Sjkim                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
307290207Sjkim                goto err;
308290207Sjkim            }
309290207Sjkim        }
310290207Sjkim        rpk->valid_flags = 0;
311290207Sjkim#ifndef OPENSSL_NO_TLSEXT
312290207Sjkim        if (cert->pkeys[i].serverinfo != NULL) {
313290207Sjkim            /* Just copy everything. */
314290207Sjkim            ret->pkeys[i].serverinfo =
315290207Sjkim                OPENSSL_malloc(cert->pkeys[i].serverinfo_length);
316290207Sjkim            if (ret->pkeys[i].serverinfo == NULL) {
317290207Sjkim                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
318312826Sjkim                goto err;
319290207Sjkim            }
320290207Sjkim            ret->pkeys[i].serverinfo_length =
321290207Sjkim                cert->pkeys[i].serverinfo_length;
322290207Sjkim            memcpy(ret->pkeys[i].serverinfo,
323290207Sjkim                   cert->pkeys[i].serverinfo,
324290207Sjkim                   cert->pkeys[i].serverinfo_length);
325290207Sjkim        }
326290207Sjkim#endif
327280297Sjkim    }
32855714Skris
329280297Sjkim    /*
330280297Sjkim     * Set digests to defaults. NB: we don't copy existing values as they
331280297Sjkim     * will be set during handshake.
332280297Sjkim     */
333280297Sjkim    ssl_cert_set_default_md(ret);
334290207Sjkim    /* Peer sigalgs set to NULL as we get these from handshake too */
335290207Sjkim    ret->peer_sigalgs = NULL;
336290207Sjkim    ret->peer_sigalgslen = 0;
337290207Sjkim    /* Configured sigalgs however we copy across */
338280297Sjkim
339290207Sjkim    if (cert->conf_sigalgs) {
340290207Sjkim        ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen);
341290207Sjkim        if (!ret->conf_sigalgs)
342290207Sjkim            goto err;
343290207Sjkim        memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen);
344290207Sjkim        ret->conf_sigalgslen = cert->conf_sigalgslen;
345290207Sjkim    } else
346290207Sjkim        ret->conf_sigalgs = NULL;
347290207Sjkim
348290207Sjkim    if (cert->client_sigalgs) {
349290207Sjkim        ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen);
350290207Sjkim        if (!ret->client_sigalgs)
351290207Sjkim            goto err;
352290207Sjkim        memcpy(ret->client_sigalgs, cert->client_sigalgs,
353290207Sjkim               cert->client_sigalgslen);
354290207Sjkim        ret->client_sigalgslen = cert->client_sigalgslen;
355290207Sjkim    } else
356290207Sjkim        ret->client_sigalgs = NULL;
357290207Sjkim    /* Shared sigalgs also NULL */
358290207Sjkim    ret->shared_sigalgs = NULL;
359290207Sjkim    /* Copy any custom client certificate types */
360290207Sjkim    if (cert->ctypes) {
361290207Sjkim        ret->ctypes = OPENSSL_malloc(cert->ctype_num);
362290207Sjkim        if (!ret->ctypes)
363290207Sjkim            goto err;
364290207Sjkim        memcpy(ret->ctypes, cert->ctypes, cert->ctype_num);
365290207Sjkim        ret->ctype_num = cert->ctype_num;
366290207Sjkim    }
367290207Sjkim
368290207Sjkim    ret->cert_flags = cert->cert_flags;
369290207Sjkim
370290207Sjkim    ret->cert_cb = cert->cert_cb;
371290207Sjkim    ret->cert_cb_arg = cert->cert_cb_arg;
372290207Sjkim
373290207Sjkim    if (cert->verify_store) {
374290207Sjkim        CRYPTO_add(&cert->verify_store->references, 1,
375290207Sjkim                   CRYPTO_LOCK_X509_STORE);
376290207Sjkim        ret->verify_store = cert->verify_store;
377290207Sjkim    }
378290207Sjkim
379290207Sjkim    if (cert->chain_store) {
380290207Sjkim        CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE);
381290207Sjkim        ret->chain_store = cert->chain_store;
382290207Sjkim    }
383290207Sjkim
384290207Sjkim    ret->ciphers_raw = NULL;
385290207Sjkim
386290207Sjkim#ifndef OPENSSL_NO_TLSEXT
387290207Sjkim    if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext))
388290207Sjkim        goto err;
389290207Sjkim    if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext))
390290207Sjkim        goto err;
391290207Sjkim#endif
392290207Sjkim
393280297Sjkim    return (ret);
394280297Sjkim
395280297Sjkim err:
396109998Smarkm#ifndef OPENSSL_NO_RSA
397280297Sjkim    if (ret->rsa_tmp != NULL)
398280297Sjkim        RSA_free(ret->rsa_tmp);
39955714Skris#endif
400109998Smarkm#ifndef OPENSSL_NO_DH
401280297Sjkim    if (ret->dh_tmp != NULL)
402280297Sjkim        DH_free(ret->dh_tmp);
40355714Skris#endif
404160814Ssimon#ifndef OPENSSL_NO_ECDH
405280297Sjkim    if (ret->ecdh_tmp != NULL)
406280297Sjkim        EC_KEY_free(ret->ecdh_tmp);
407160814Ssimon#endif
40855714Skris
409290207Sjkim#ifndef OPENSSL_NO_TLSEXT
410290207Sjkim    custom_exts_free(&ret->cli_ext);
411290207Sjkim    custom_exts_free(&ret->srv_ext);
412290207Sjkim#endif
41355714Skris
414290207Sjkim    ssl_cert_clear_certs(ret);
415325335Sjkim    OPENSSL_free(ret);
416290207Sjkim
417280297Sjkim    return NULL;
418280297Sjkim}
41955714Skris
420290207Sjkim/* Free up and clear all certificates and chains */
421290207Sjkim
422290207Sjkimvoid ssl_cert_clear_certs(CERT *c)
423290207Sjkim{
424290207Sjkim    int i;
425290207Sjkim    if (c == NULL)
426290207Sjkim        return;
427290207Sjkim    for (i = 0; i < SSL_PKEY_NUM; i++) {
428290207Sjkim        CERT_PKEY *cpk = c->pkeys + i;
429290207Sjkim        if (cpk->x509) {
430290207Sjkim            X509_free(cpk->x509);
431290207Sjkim            cpk->x509 = NULL;
432290207Sjkim        }
433290207Sjkim        if (cpk->privatekey) {
434290207Sjkim            EVP_PKEY_free(cpk->privatekey);
435290207Sjkim            cpk->privatekey = NULL;
436290207Sjkim        }
437290207Sjkim        if (cpk->chain) {
438290207Sjkim            sk_X509_pop_free(cpk->chain, X509_free);
439290207Sjkim            cpk->chain = NULL;
440290207Sjkim        }
441290207Sjkim#ifndef OPENSSL_NO_TLSEXT
442290207Sjkim        if (cpk->serverinfo) {
443290207Sjkim            OPENSSL_free(cpk->serverinfo);
444290207Sjkim            cpk->serverinfo = NULL;
445290207Sjkim            cpk->serverinfo_length = 0;
446290207Sjkim        }
447290207Sjkim#endif
448290207Sjkim        /* Clear all flags apart from explicit sign */
449290207Sjkim        cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN;
450290207Sjkim    }
451290207Sjkim}
452290207Sjkim
45355714Skrisvoid ssl_cert_free(CERT *c)
454280297Sjkim{
455280297Sjkim    int i;
45655714Skris
457280297Sjkim    if (c == NULL)
458280297Sjkim        return;
45955714Skris
460280297Sjkim    i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT);
46155714Skris#ifdef REF_PRINT
462280297Sjkim    REF_PRINT("CERT", c);
46355714Skris#endif
464280297Sjkim    if (i > 0)
465280297Sjkim        return;
46655714Skris#ifdef REF_CHECK
467280297Sjkim    if (i < 0) {
468280297Sjkim        fprintf(stderr, "ssl_cert_free, bad reference count\n");
469280297Sjkim        abort();                /* ok */
470280297Sjkim    }
47155714Skris#endif
47255714Skris
473109998Smarkm#ifndef OPENSSL_NO_RSA
474280297Sjkim    if (c->rsa_tmp)
475280297Sjkim        RSA_free(c->rsa_tmp);
47655714Skris#endif
477109998Smarkm#ifndef OPENSSL_NO_DH
478280297Sjkim    if (c->dh_tmp)
479280297Sjkim        DH_free(c->dh_tmp);
48055714Skris#endif
481160814Ssimon#ifndef OPENSSL_NO_ECDH
482280297Sjkim    if (c->ecdh_tmp)
483280297Sjkim        EC_KEY_free(c->ecdh_tmp);
484160814Ssimon#endif
48555714Skris
486290207Sjkim    ssl_cert_clear_certs(c);
487290207Sjkim    if (c->peer_sigalgs)
488290207Sjkim        OPENSSL_free(c->peer_sigalgs);
489290207Sjkim    if (c->conf_sigalgs)
490290207Sjkim        OPENSSL_free(c->conf_sigalgs);
491290207Sjkim    if (c->client_sigalgs)
492290207Sjkim        OPENSSL_free(c->client_sigalgs);
493290207Sjkim    if (c->shared_sigalgs)
494290207Sjkim        OPENSSL_free(c->shared_sigalgs);
495290207Sjkim    if (c->ctypes)
496290207Sjkim        OPENSSL_free(c->ctypes);
497290207Sjkim    if (c->verify_store)
498290207Sjkim        X509_STORE_free(c->verify_store);
499290207Sjkim    if (c->chain_store)
500290207Sjkim        X509_STORE_free(c->chain_store);
501290207Sjkim    if (c->ciphers_raw)
502290207Sjkim        OPENSSL_free(c->ciphers_raw);
503290207Sjkim#ifndef OPENSSL_NO_TLSEXT
504290207Sjkim    custom_exts_free(&c->cli_ext);
505290207Sjkim    custom_exts_free(&c->srv_ext);
506298998Sjkim    if (c->alpn_proposed)
507298998Sjkim        OPENSSL_free(c->alpn_proposed);
50855714Skris#endif
509280297Sjkim    OPENSSL_free(c);
510280297Sjkim}
51155714Skris
51255714Skrisint ssl_cert_inst(CERT **o)
513280297Sjkim{
514280297Sjkim    /*
515280297Sjkim     * Create a CERT if there isn't already one (which cannot really happen,
516280297Sjkim     * as it is initially created in SSL_CTX_new; but the earlier code
517280297Sjkim     * usually allows for that one being non-existant, so we follow that
518280297Sjkim     * behaviour, as it might turn out that there actually is a reason for it
519280297Sjkim     * -- but I'm not sure that *all* of the existing code could cope with
520280297Sjkim     * s->cert being NULL, otherwise we could do without the initialization
521280297Sjkim     * in SSL_CTX_new).
522280297Sjkim     */
52355714Skris
524280297Sjkim    if (o == NULL) {
525280297Sjkim        SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
526280297Sjkim        return (0);
527280297Sjkim    }
528280297Sjkim    if (*o == NULL) {
529280297Sjkim        if ((*o = ssl_cert_new()) == NULL) {
530280297Sjkim            SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
531280297Sjkim            return (0);
532280297Sjkim        }
533280297Sjkim    }
534280297Sjkim    return (1);
535280297Sjkim}
53655714Skris
537290207Sjkimint ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain)
538290207Sjkim{
539290207Sjkim    CERT_PKEY *cpk = c->key;
540290207Sjkim    if (!cpk)
541290207Sjkim        return 0;
542290207Sjkim    if (cpk->chain)
543290207Sjkim        sk_X509_pop_free(cpk->chain, X509_free);
544290207Sjkim    cpk->chain = chain;
545290207Sjkim    return 1;
546290207Sjkim}
547290207Sjkim
548290207Sjkimint ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
549290207Sjkim{
550290207Sjkim    STACK_OF(X509) *dchain;
551290207Sjkim    if (!chain)
552290207Sjkim        return ssl_cert_set0_chain(c, NULL);
553290207Sjkim    dchain = X509_chain_up_ref(chain);
554290207Sjkim    if (!dchain)
555290207Sjkim        return 0;
556290207Sjkim    if (!ssl_cert_set0_chain(c, dchain)) {
557290207Sjkim        sk_X509_pop_free(dchain, X509_free);
558290207Sjkim        return 0;
559290207Sjkim    }
560290207Sjkim    return 1;
561290207Sjkim}
562290207Sjkim
563290207Sjkimint ssl_cert_add0_chain_cert(CERT *c, X509 *x)
564290207Sjkim{
565290207Sjkim    CERT_PKEY *cpk = c->key;
566290207Sjkim    if (!cpk)
567290207Sjkim        return 0;
568290207Sjkim    if (!cpk->chain)
569290207Sjkim        cpk->chain = sk_X509_new_null();
570290207Sjkim    if (!cpk->chain || !sk_X509_push(cpk->chain, x))
571290207Sjkim        return 0;
572290207Sjkim    return 1;
573290207Sjkim}
574290207Sjkim
575290207Sjkimint ssl_cert_add1_chain_cert(CERT *c, X509 *x)
576290207Sjkim{
577290207Sjkim    if (!ssl_cert_add0_chain_cert(c, x))
578290207Sjkim        return 0;
579290207Sjkim    CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
580290207Sjkim    return 1;
581290207Sjkim}
582290207Sjkim
583290207Sjkimint ssl_cert_select_current(CERT *c, X509 *x)
584290207Sjkim{
585290207Sjkim    int i;
586290207Sjkim    if (x == NULL)
587290207Sjkim        return 0;
588290207Sjkim    for (i = 0; i < SSL_PKEY_NUM; i++) {
589290207Sjkim        CERT_PKEY *cpk = c->pkeys + i;
590290207Sjkim        if (cpk->x509 == x && cpk->privatekey) {
591290207Sjkim            c->key = cpk;
592290207Sjkim            return 1;
593290207Sjkim        }
594290207Sjkim    }
595290207Sjkim
596290207Sjkim    for (i = 0; i < SSL_PKEY_NUM; i++) {
597290207Sjkim        CERT_PKEY *cpk = c->pkeys + i;
598290207Sjkim        if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) {
599290207Sjkim            c->key = cpk;
600290207Sjkim            return 1;
601290207Sjkim        }
602290207Sjkim    }
603290207Sjkim    return 0;
604290207Sjkim}
605290207Sjkim
606290207Sjkimint ssl_cert_set_current(CERT *c, long op)
607290207Sjkim{
608290207Sjkim    int i, idx;
609290207Sjkim    if (!c)
610290207Sjkim        return 0;
611290207Sjkim    if (op == SSL_CERT_SET_FIRST)
612290207Sjkim        idx = 0;
613290207Sjkim    else if (op == SSL_CERT_SET_NEXT) {
614290207Sjkim        idx = (int)(c->key - c->pkeys + 1);
615290207Sjkim        if (idx >= SSL_PKEY_NUM)
616290207Sjkim            return 0;
617290207Sjkim    } else
618290207Sjkim        return 0;
619290207Sjkim    for (i = idx; i < SSL_PKEY_NUM; i++) {
620290207Sjkim        CERT_PKEY *cpk = c->pkeys + i;
621290207Sjkim        if (cpk->x509 && cpk->privatekey) {
622290207Sjkim            c->key = cpk;
623290207Sjkim            return 1;
624290207Sjkim        }
625290207Sjkim    }
626290207Sjkim    return 0;
627290207Sjkim}
628290207Sjkim
629290207Sjkimvoid ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg)
630290207Sjkim{
631290207Sjkim    c->cert_cb = cb;
632290207Sjkim    c->cert_cb_arg = arg;
633290207Sjkim}
634290207Sjkim
63555714SkrisSESS_CERT *ssl_sess_cert_new(void)
636280297Sjkim{
637280297Sjkim    SESS_CERT *ret;
63855714Skris
639331638Sjkim    ret = OPENSSL_malloc(sizeof(*ret));
640280297Sjkim    if (ret == NULL) {
641280297Sjkim        SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
642280297Sjkim        return NULL;
643280297Sjkim    }
64455714Skris
645331638Sjkim    memset(ret, 0, sizeof(*ret));
646280297Sjkim    ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
647280297Sjkim    ret->references = 1;
64855714Skris
649280297Sjkim    return ret;
650280297Sjkim}
65155714Skris
65255714Skrisvoid ssl_sess_cert_free(SESS_CERT *sc)
653280297Sjkim{
654280297Sjkim    int i;
65555714Skris
656280297Sjkim    if (sc == NULL)
657280297Sjkim        return;
65855714Skris
659280297Sjkim    i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
66055714Skris#ifdef REF_PRINT
661280297Sjkim    REF_PRINT("SESS_CERT", sc);
66255714Skris#endif
663280297Sjkim    if (i > 0)
664280297Sjkim        return;
66555714Skris#ifdef REF_CHECK
666280297Sjkim    if (i < 0) {
667280297Sjkim        fprintf(stderr, "ssl_sess_cert_free, bad reference count\n");
668280297Sjkim        abort();                /* ok */
669280297Sjkim    }
67055714Skris#endif
67155714Skris
672280297Sjkim    /* i == 0 */
673280297Sjkim    if (sc->cert_chain != NULL)
674280297Sjkim        sk_X509_pop_free(sc->cert_chain, X509_free);
675280297Sjkim    for (i = 0; i < SSL_PKEY_NUM; i++) {
676280297Sjkim        if (sc->peer_pkeys[i].x509 != NULL)
677280297Sjkim            X509_free(sc->peer_pkeys[i].x509);
678280297Sjkim#if 0                           /* We don't have the peer's private key.
679280297Sjkim                                 * These lines are just * here as a reminder
680280297Sjkim                                 * that we're still using a
681280297Sjkim                                 * not-quite-appropriate * data structure. */
682280297Sjkim        if (sc->peer_pkeys[i].privatekey != NULL)
683280297Sjkim            EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
68455714Skris#endif
685280297Sjkim    }
68655714Skris
687109998Smarkm#ifndef OPENSSL_NO_RSA
688280297Sjkim    if (sc->peer_rsa_tmp != NULL)
689280297Sjkim        RSA_free(sc->peer_rsa_tmp);
69055714Skris#endif
691109998Smarkm#ifndef OPENSSL_NO_DH
692280297Sjkim    if (sc->peer_dh_tmp != NULL)
693280297Sjkim        DH_free(sc->peer_dh_tmp);
69455714Skris#endif
695160814Ssimon#ifndef OPENSSL_NO_ECDH
696280297Sjkim    if (sc->peer_ecdh_tmp != NULL)
697280297Sjkim        EC_KEY_free(sc->peer_ecdh_tmp);
698160814Ssimon#endif
69955714Skris
700280297Sjkim    OPENSSL_free(sc);
701280297Sjkim}
70255714Skris
703280297Sjkimint ssl_set_peer_cert_type(SESS_CERT *sc, int type)
704280297Sjkim{
705280297Sjkim    sc->peer_cert_type = type;
706280297Sjkim    return (1);
707280297Sjkim}
70855714Skris
709280297Sjkimint ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
710280297Sjkim{
711280297Sjkim    X509 *x;
712280297Sjkim    int i;
713290207Sjkim    X509_STORE *verify_store;
714280297Sjkim    X509_STORE_CTX ctx;
71555714Skris
716290207Sjkim    if (s->cert->verify_store)
717290207Sjkim        verify_store = s->cert->verify_store;
718290207Sjkim    else
719290207Sjkim        verify_store = s->ctx->cert_store;
720290207Sjkim
721280297Sjkim    if ((sk == NULL) || (sk_X509_num(sk) == 0))
722280297Sjkim        return (0);
72355714Skris
724280297Sjkim    x = sk_X509_value(sk, 0);
725290207Sjkim    if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) {
726280297Sjkim        SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB);
727280297Sjkim        return (0);
728280297Sjkim    }
729290207Sjkim    /* Set suite B flags if needed */
730290207Sjkim    X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s));
731160814Ssimon#if 0
732280297Sjkim    if (SSL_get_verify_depth(s) >= 0)
733280297Sjkim        X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
734160814Ssimon#endif
735280297Sjkim    X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
736109998Smarkm
737280297Sjkim    /*
738280297Sjkim     * We need to inherit the verify parameters. These can be determined by
739280297Sjkim     * the context: if its a server it will verify SSL client certificates or
740280297Sjkim     * vice versa.
741280297Sjkim     */
74255714Skris
743280297Sjkim    X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server");
744280297Sjkim    /*
745280297Sjkim     * Anything non-default in "param" should overwrite anything in the ctx.
746280297Sjkim     */
747280297Sjkim    X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
74859191Skris
749280297Sjkim    if (s->verify_callback)
750280297Sjkim        X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
75189837Skris
752280297Sjkim    if (s->ctx->app_verify_callback != NULL)
753280297Sjkim#if 1                           /* new with OpenSSL 0.9.7 */
754280297Sjkim        i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
755109998Smarkm#else
756280297Sjkim        i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
757109998Smarkm#endif
758280297Sjkim    else {
759109998Smarkm#ifndef OPENSSL_NO_X509_VERIFY
760280297Sjkim        i = X509_verify_cert(&ctx);
76155714Skris#else
762280297Sjkim        i = 0;
763280297Sjkim        ctx.error = X509_V_ERR_APPLICATION_VERIFICATION;
764280297Sjkim        SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK);
76555714Skris#endif
766280297Sjkim    }
76755714Skris
768280297Sjkim    s->verify_result = ctx.error;
769280297Sjkim    X509_STORE_CTX_cleanup(&ctx);
77055714Skris
771280297Sjkim    return (i);
772280297Sjkim}
77355714Skris
774280297Sjkimstatic void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
775280297Sjkim                               STACK_OF(X509_NAME) *name_list)
776280297Sjkim{
777280297Sjkim    if (*ca_list != NULL)
778280297Sjkim        sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
77955714Skris
780280297Sjkim    *ca_list = name_list;
781280297Sjkim}
78255714Skris
78355714SkrisSTACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
784280297Sjkim{
785280297Sjkim    int i;
786280297Sjkim    STACK_OF(X509_NAME) *ret;
787280297Sjkim    X509_NAME *name;
78855714Skris
789280297Sjkim    ret = sk_X509_NAME_new_null();
790280297Sjkim    for (i = 0; i < sk_X509_NAME_num(sk); i++) {
791280297Sjkim        name = X509_NAME_dup(sk_X509_NAME_value(sk, i));
792280297Sjkim        if ((name == NULL) || !sk_X509_NAME_push(ret, name)) {
793280297Sjkim            sk_X509_NAME_pop_free(ret, X509_NAME_free);
794280297Sjkim            return (NULL);
795280297Sjkim        }
796280297Sjkim    }
797280297Sjkim    return (ret);
798280297Sjkim}
79955714Skris
800280297Sjkimvoid SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
801280297Sjkim{
802280297Sjkim    set_client_CA_list(&(s->client_CA), name_list);
803280297Sjkim}
80455714Skris
805280297Sjkimvoid SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
806280297Sjkim{
807280297Sjkim    set_client_CA_list(&(ctx->client_CA), name_list);
808280297Sjkim}
80955714Skris
810160814SsimonSTACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
811280297Sjkim{
812280297Sjkim    return (ctx->client_CA);
813280297Sjkim}
81455714Skris
815160814SsimonSTACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
816280297Sjkim{
817280297Sjkim    if (s->type == SSL_ST_CONNECT) { /* we are in the client */
818280297Sjkim        if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL))
819280297Sjkim            return (s->s3->tmp.ca_names);
820280297Sjkim        else
821280297Sjkim            return (NULL);
822280297Sjkim    } else {
823280297Sjkim        if (s->client_CA != NULL)
824280297Sjkim            return (s->client_CA);
825280297Sjkim        else
826280297Sjkim            return (s->ctx->client_CA);
827280297Sjkim    }
828280297Sjkim}
82955714Skris
830280297Sjkimstatic int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x)
831280297Sjkim{
832280297Sjkim    X509_NAME *name;
83355714Skris
834280297Sjkim    if (x == NULL)
835280297Sjkim        return (0);
836280297Sjkim    if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL))
837280297Sjkim        return (0);
83855714Skris
839280297Sjkim    if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL)
840280297Sjkim        return (0);
84155714Skris
842280297Sjkim    if (!sk_X509_NAME_push(*sk, name)) {
843280297Sjkim        X509_NAME_free(name);
844280297Sjkim        return (0);
845280297Sjkim    }
846280297Sjkim    return (1);
847280297Sjkim}
84855714Skris
849280297Sjkimint SSL_add_client_CA(SSL *ssl, X509 *x)
850280297Sjkim{
851280297Sjkim    return (add_client_CA(&(ssl->client_CA), x));
852280297Sjkim}
85355714Skris
854280297Sjkimint SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
855280297Sjkim{
856280297Sjkim    return (add_client_CA(&(ctx->client_CA), x));
857280297Sjkim}
85855714Skris
859280297Sjkimstatic int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
860280297Sjkim{
861280297Sjkim    return (X509_NAME_cmp(*a, *b));
862280297Sjkim}
863280297Sjkim
864109998Smarkm#ifndef OPENSSL_NO_STDIO
865280297Sjkim/**
86655714Skris * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
86755714Skris * it doesn't really have anything to do with clients (except that a common use
86855714Skris * for a stack of CAs is to send it to the client). Actually, it doesn't have
86955714Skris * much to do with CAs, either, since it will load any old cert.
87055714Skris * \param file the file containing one or more certs.
87155714Skris * \return a ::STACK containing the certs.
87255714Skris */
87355714SkrisSTACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
874280297Sjkim{
875280297Sjkim    BIO *in;
876280297Sjkim    X509 *x = NULL;
877280297Sjkim    X509_NAME *xn = NULL;
878280297Sjkim    STACK_OF(X509_NAME) *ret = NULL, *sk;
87955714Skris
880280297Sjkim    sk = sk_X509_NAME_new(xname_cmp);
88155714Skris
882280297Sjkim    in = BIO_new(BIO_s_file_internal());
88355714Skris
884280297Sjkim    if ((sk == NULL) || (in == NULL)) {
885280297Sjkim        SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
886280297Sjkim        goto err;
887280297Sjkim    }
88855714Skris
889280297Sjkim    if (!BIO_read_filename(in, file))
890280297Sjkim        goto err;
89155714Skris
892280297Sjkim    for (;;) {
893280297Sjkim        if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
894280297Sjkim            break;
895280297Sjkim        if (ret == NULL) {
896280297Sjkim            ret = sk_X509_NAME_new_null();
897280297Sjkim            if (ret == NULL) {
898280297Sjkim                SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
899280297Sjkim                goto err;
900280297Sjkim            }
901280297Sjkim        }
902280297Sjkim        if ((xn = X509_get_subject_name(x)) == NULL)
903280297Sjkim            goto err;
904280297Sjkim        /* check for duplicates */
905280297Sjkim        xn = X509_NAME_dup(xn);
906280297Sjkim        if (xn == NULL)
907280297Sjkim            goto err;
908280297Sjkim        if (sk_X509_NAME_find(sk, xn) >= 0)
909280297Sjkim            X509_NAME_free(xn);
910280297Sjkim        else {
911280297Sjkim            sk_X509_NAME_push(sk, xn);
912280297Sjkim            sk_X509_NAME_push(ret, xn);
913280297Sjkim        }
914280297Sjkim    }
915280297Sjkim
916280297Sjkim    if (0) {
917280297Sjkim err:
918280297Sjkim        if (ret != NULL)
919280297Sjkim            sk_X509_NAME_pop_free(ret, X509_NAME_free);
920280297Sjkim        ret = NULL;
921280297Sjkim    }
922280297Sjkim    if (sk != NULL)
923280297Sjkim        sk_X509_NAME_free(sk);
924280297Sjkim    if (in != NULL)
925280297Sjkim        BIO_free(in);
926280297Sjkim    if (x != NULL)
927280297Sjkim        X509_free(x);
928280297Sjkim    if (ret != NULL)
929280297Sjkim        ERR_clear_error();
930280297Sjkim    return (ret);
931280297Sjkim}
93255714Skris#endif
93355714Skris
934280297Sjkim/**
93555714Skris * Add a file of certs to a stack.
93655714Skris * \param stack the stack to add to.
93755714Skris * \param file the file to add from. All certs in this file that are not
93855714Skris * already in the stack will be added.
93955714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some
94055714Skris * certs may have been added to \c stack.
94155714Skris */
94255714Skris
94355714Skrisint SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
944280297Sjkim                                        const char *file)
945280297Sjkim{
946280297Sjkim    BIO *in;
947280297Sjkim    X509 *x = NULL;
948280297Sjkim    X509_NAME *xn = NULL;
949280297Sjkim    int ret = 1;
950280297Sjkim    int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b);
95155714Skris
952280297Sjkim    oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
953215697Ssimon
954280297Sjkim    in = BIO_new(BIO_s_file_internal());
95555714Skris
956280297Sjkim    if (in == NULL) {
957280297Sjkim        SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,
958280297Sjkim               ERR_R_MALLOC_FAILURE);
959280297Sjkim        goto err;
960280297Sjkim    }
96155714Skris
962280297Sjkim    if (!BIO_read_filename(in, file))
963280297Sjkim        goto err;
964280297Sjkim
965280297Sjkim    for (;;) {
966280297Sjkim        if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
967280297Sjkim            break;
968280297Sjkim        if ((xn = X509_get_subject_name(x)) == NULL)
969280297Sjkim            goto err;
970280297Sjkim        xn = X509_NAME_dup(xn);
971280297Sjkim        if (xn == NULL)
972280297Sjkim            goto err;
973280297Sjkim        if (sk_X509_NAME_find(stack, xn) >= 0)
974280297Sjkim            X509_NAME_free(xn);
975280297Sjkim        else
976280297Sjkim            sk_X509_NAME_push(stack, xn);
977280297Sjkim    }
978280297Sjkim
979280297Sjkim    ERR_clear_error();
980280297Sjkim
981280297Sjkim    if (0) {
982280297Sjkim err:
983280297Sjkim        ret = 0;
984280297Sjkim    }
985280297Sjkim    if (in != NULL)
986280297Sjkim        BIO_free(in);
987280297Sjkim    if (x != NULL)
988280297Sjkim        X509_free(x);
989280297Sjkim
990280297Sjkim    (void)sk_X509_NAME_set_cmp_func(stack, oldcmp);
991280297Sjkim
992280297Sjkim    return ret;
993280297Sjkim}
994280297Sjkim
995280297Sjkim/**
99655714Skris * Add a directory of certs to a stack.
99755714Skris * \param stack the stack to append to.
99855714Skris * \param dir the directory to append from. All files in this directory will be
99955714Skris * examined as potential certs. Any that are acceptable to
100055714Skris * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
100155714Skris * included.
100255714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some
100355714Skris * certs may have been added to \c stack.
100455714Skris */
100555714Skris
100655714Skrisint SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
1007280297Sjkim                                       const char *dir)
1008280297Sjkim{
1009280297Sjkim    OPENSSL_DIR_CTX *d = NULL;
1010280297Sjkim    const char *filename;
1011280297Sjkim    int ret = 0;
101255714Skris
1013280297Sjkim    CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
101455714Skris
1015280297Sjkim    /* Note that a side effect is that the CAs will be sorted by name */
1016160814Ssimon
1017280297Sjkim    while ((filename = OPENSSL_DIR_read(&d, dir))) {
1018280297Sjkim        char buf[1024];
1019280297Sjkim        int r;
1020160814Ssimon
1021331638Sjkim        if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) {
1022280297Sjkim            SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,
1023280297Sjkim                   SSL_R_PATH_TOO_LONG);
1024280297Sjkim            goto err;
1025280297Sjkim        }
1026160814Ssimon#ifdef OPENSSL_SYS_VMS
1027331638Sjkim        r = BIO_snprintf(buf, sizeof(buf), "%s%s", dir, filename);
1028160814Ssimon#else
1029331638Sjkim        r = BIO_snprintf(buf, sizeof(buf), "%s/%s", dir, filename);
1030160814Ssimon#endif
1031280297Sjkim        if (r <= 0 || r >= (int)sizeof(buf))
1032280297Sjkim            goto err;
1033280297Sjkim        if (!SSL_add_file_cert_subjects_to_stack(stack, buf))
1034280297Sjkim            goto err;
1035280297Sjkim    }
103655714Skris
1037280297Sjkim    if (errno) {
1038280297Sjkim        SYSerr(SYS_F_OPENDIR, get_last_sys_error());
1039280297Sjkim        ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
1040280297Sjkim        SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
1041280297Sjkim        goto err;
1042280297Sjkim    }
1043142425Snectar
1044280297Sjkim    ret = 1;
1045109998Smarkm
1046280297Sjkim err:
1047280297Sjkim    if (d)
1048280297Sjkim        OPENSSL_DIR_end(&d);
1049280297Sjkim    CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
1050280297Sjkim    return ret;
1051280297Sjkim}
1052290207Sjkim
1053290207Sjkim/* Add a certificate to a BUF_MEM structure */
1054290207Sjkim
1055290207Sjkimstatic int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
1056290207Sjkim{
1057290207Sjkim    int n;
1058290207Sjkim    unsigned char *p;
1059290207Sjkim
1060290207Sjkim    n = i2d_X509(x, NULL);
1061298998Sjkim    if (n < 0 || !BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
1062290207Sjkim        SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB);
1063290207Sjkim        return 0;
1064290207Sjkim    }
1065290207Sjkim    p = (unsigned char *)&(buf->data[*l]);
1066290207Sjkim    l2n3(n, p);
1067298998Sjkim    n = i2d_X509(x, &p);
1068298998Sjkim    if (n < 0) {
1069298998Sjkim        /* Shouldn't happen */
1070298998Sjkim        SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB);
1071298998Sjkim        return 0;
1072298998Sjkim    }
1073290207Sjkim    *l += n + 3;
1074290207Sjkim
1075290207Sjkim    return 1;
1076290207Sjkim}
1077290207Sjkim
1078290207Sjkim/* Add certificate chain to internal SSL BUF_MEM strcuture */
1079290207Sjkimint ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
1080290207Sjkim{
1081290207Sjkim    BUF_MEM *buf = s->init_buf;
1082290207Sjkim    int no_chain;
1083290207Sjkim    int i;
1084290207Sjkim
1085290207Sjkim    X509 *x;
1086290207Sjkim    STACK_OF(X509) *extra_certs;
1087290207Sjkim    X509_STORE *chain_store;
1088290207Sjkim
1089290207Sjkim    if (cpk)
1090290207Sjkim        x = cpk->x509;
1091290207Sjkim    else
1092290207Sjkim        x = NULL;
1093290207Sjkim
1094290207Sjkim    if (s->cert->chain_store)
1095290207Sjkim        chain_store = s->cert->chain_store;
1096290207Sjkim    else
1097290207Sjkim        chain_store = s->ctx->cert_store;
1098290207Sjkim
1099290207Sjkim    /*
1100290207Sjkim     * If we have a certificate specific chain use it, else use parent ctx.
1101290207Sjkim     */
1102290207Sjkim    if (cpk && cpk->chain)
1103290207Sjkim        extra_certs = cpk->chain;
1104290207Sjkim    else
1105290207Sjkim        extra_certs = s->ctx->extra_certs;
1106290207Sjkim
1107290207Sjkim    if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs)
1108290207Sjkim        no_chain = 1;
1109290207Sjkim    else
1110290207Sjkim        no_chain = 0;
1111290207Sjkim
1112290207Sjkim    /* TLSv1 sends a chain with nothing in it, instead of an alert */
1113290207Sjkim    if (!BUF_MEM_grow_clean(buf, 10)) {
1114290207Sjkim        SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_BUF_LIB);
1115290207Sjkim        return 0;
1116290207Sjkim    }
1117290207Sjkim    if (x != NULL) {
1118290207Sjkim        if (no_chain) {
1119290207Sjkim            if (!ssl_add_cert_to_buf(buf, l, x))
1120290207Sjkim                return 0;
1121290207Sjkim        } else {
1122290207Sjkim            X509_STORE_CTX xs_ctx;
1123290207Sjkim
1124290207Sjkim            if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) {
1125290207Sjkim                SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_X509_LIB);
1126290207Sjkim                return (0);
1127290207Sjkim            }
1128290207Sjkim            X509_verify_cert(&xs_ctx);
1129290207Sjkim            /* Don't leave errors in the queue */
1130290207Sjkim            ERR_clear_error();
1131290207Sjkim            for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) {
1132290207Sjkim                x = sk_X509_value(xs_ctx.chain, i);
1133290207Sjkim
1134290207Sjkim                if (!ssl_add_cert_to_buf(buf, l, x)) {
1135290207Sjkim                    X509_STORE_CTX_cleanup(&xs_ctx);
1136290207Sjkim                    return 0;
1137290207Sjkim                }
1138290207Sjkim            }
1139290207Sjkim            X509_STORE_CTX_cleanup(&xs_ctx);
1140290207Sjkim        }
1141290207Sjkim    }
1142290207Sjkim    for (i = 0; i < sk_X509_num(extra_certs); i++) {
1143290207Sjkim        x = sk_X509_value(extra_certs, i);
1144290207Sjkim        if (!ssl_add_cert_to_buf(buf, l, x))
1145290207Sjkim            return 0;
1146290207Sjkim    }
1147290207Sjkim
1148290207Sjkim    return 1;
1149290207Sjkim}
1150290207Sjkim
1151290207Sjkim/* Build a certificate chain for current certificate */
1152290207Sjkimint ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags)
1153290207Sjkim{
1154290207Sjkim    CERT_PKEY *cpk = c->key;
1155290207Sjkim    X509_STORE_CTX xs_ctx;
1156290207Sjkim    STACK_OF(X509) *chain = NULL, *untrusted = NULL;
1157290207Sjkim    X509 *x;
1158290207Sjkim    int i, rv = 0;
1159290207Sjkim    unsigned long error;
1160290207Sjkim
1161290207Sjkim    if (!cpk->x509) {
1162290207Sjkim        SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET);
1163290207Sjkim        goto err;
1164290207Sjkim    }
1165290207Sjkim    /* Rearranging and check the chain: add everything to a store */
1166290207Sjkim    if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) {
1167290207Sjkim        chain_store = X509_STORE_new();
1168290207Sjkim        if (!chain_store)
1169290207Sjkim            goto err;
1170290207Sjkim        for (i = 0; i < sk_X509_num(cpk->chain); i++) {
1171290207Sjkim            x = sk_X509_value(cpk->chain, i);
1172290207Sjkim            if (!X509_STORE_add_cert(chain_store, x)) {
1173290207Sjkim                error = ERR_peek_last_error();
1174290207Sjkim                if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
1175290207Sjkim                    ERR_GET_REASON(error) !=
1176290207Sjkim                    X509_R_CERT_ALREADY_IN_HASH_TABLE)
1177290207Sjkim                    goto err;
1178290207Sjkim                ERR_clear_error();
1179290207Sjkim            }
1180290207Sjkim        }
1181290207Sjkim        /* Add EE cert too: it might be self signed */
1182290207Sjkim        if (!X509_STORE_add_cert(chain_store, cpk->x509)) {
1183290207Sjkim            error = ERR_peek_last_error();
1184290207Sjkim            if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
1185290207Sjkim                ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE)
1186290207Sjkim                goto err;
1187290207Sjkim            ERR_clear_error();
1188290207Sjkim        }
1189290207Sjkim    } else {
1190290207Sjkim        if (c->chain_store)
1191290207Sjkim            chain_store = c->chain_store;
1192290207Sjkim
1193290207Sjkim        if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED)
1194290207Sjkim            untrusted = cpk->chain;
1195290207Sjkim    }
1196290207Sjkim
1197290207Sjkim    if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) {
1198290207Sjkim        SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB);
1199290207Sjkim        goto err;
1200290207Sjkim    }
1201290207Sjkim    /* Set suite B flags if needed */
1202290207Sjkim    X509_STORE_CTX_set_flags(&xs_ctx,
1203290207Sjkim                             c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS);
1204290207Sjkim
1205290207Sjkim    i = X509_verify_cert(&xs_ctx);
1206290207Sjkim    if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) {
1207290207Sjkim        if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR)
1208290207Sjkim            ERR_clear_error();
1209290207Sjkim        i = 1;
1210290207Sjkim        rv = 2;
1211290207Sjkim    }
1212290207Sjkim    if (i > 0)
1213290207Sjkim        chain = X509_STORE_CTX_get1_chain(&xs_ctx);
1214290207Sjkim    if (i <= 0) {
1215290207Sjkim        SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED);
1216290207Sjkim        i = X509_STORE_CTX_get_error(&xs_ctx);
1217290207Sjkim        ERR_add_error_data(2, "Verify error:",
1218290207Sjkim                           X509_verify_cert_error_string(i));
1219290207Sjkim
1220290207Sjkim        X509_STORE_CTX_cleanup(&xs_ctx);
1221290207Sjkim        goto err;
1222290207Sjkim    }
1223290207Sjkim    X509_STORE_CTX_cleanup(&xs_ctx);
1224290207Sjkim    if (cpk->chain)
1225290207Sjkim        sk_X509_pop_free(cpk->chain, X509_free);
1226290207Sjkim    /* Remove EE certificate from chain */
1227290207Sjkim    x = sk_X509_shift(chain);
1228290207Sjkim    X509_free(x);
1229290207Sjkim    if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) {
1230290207Sjkim        if (sk_X509_num(chain) > 0) {
1231290207Sjkim            /* See if last cert is self signed */
1232290207Sjkim            x = sk_X509_value(chain, sk_X509_num(chain) - 1);
1233290207Sjkim            X509_check_purpose(x, -1, 0);
1234290207Sjkim            if (x->ex_flags & EXFLAG_SS) {
1235290207Sjkim                x = sk_X509_pop(chain);
1236290207Sjkim                X509_free(x);
1237290207Sjkim            }
1238290207Sjkim        }
1239290207Sjkim    }
1240290207Sjkim    cpk->chain = chain;
1241290207Sjkim    if (rv == 0)
1242290207Sjkim        rv = 1;
1243290207Sjkim err:
1244290207Sjkim    if (flags & SSL_BUILD_CHAIN_FLAG_CHECK)
1245290207Sjkim        X509_STORE_free(chain_store);
1246290207Sjkim
1247290207Sjkim    return rv;
1248290207Sjkim}
1249290207Sjkim
1250290207Sjkimint ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
1251290207Sjkim{
1252290207Sjkim    X509_STORE **pstore;
1253290207Sjkim    if (chain)
1254290207Sjkim        pstore = &c->chain_store;
1255290207Sjkim    else
1256290207Sjkim        pstore = &c->verify_store;
1257290207Sjkim    if (*pstore)
1258290207Sjkim        X509_STORE_free(*pstore);
1259290207Sjkim    *pstore = store;
1260290207Sjkim    if (ref && store)
1261290207Sjkim        CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
1262290207Sjkim    return 1;
1263290207Sjkim}
1264