1280304Sjkim/*
2280304Sjkim * ! \file ssl/ssl_cert.c
3280304Sjkim */
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.
10280304Sjkim *
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).
17280304Sjkim *
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.
24280304Sjkim *
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 :-).
39280304Sjkim * 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)"
42280304Sjkim *
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.
54280304Sjkim *
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
68280304Sjkim *    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.
115280304Sjkim * 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
132280304Sjkim# 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)
138280304Sjkim{
139280304Sjkim    static volatile int ssl_x509_store_ctx_idx = -1;
140280304Sjkim    int got_write_lock = 0;
14155714Skris
142280304Sjkim    CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
143162911Ssimon
144280304Sjkim    if (ssl_x509_store_ctx_idx < 0) {
145280304Sjkim        CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
146280304Sjkim        CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
147280304Sjkim        got_write_lock = 1;
148162911Ssimon
149280304Sjkim        if (ssl_x509_store_ctx_idx < 0) {
150280304Sjkim            ssl_x509_store_ctx_idx =
151280304Sjkim                X509_STORE_CTX_get_ex_new_index(0, "SSL for verify callback",
152280304Sjkim                                                NULL, NULL, NULL);
153280304Sjkim        }
154280304Sjkim    }
15555714Skris
156280304Sjkim    if (got_write_lock)
157280304Sjkim        CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
158280304Sjkim    else
159280304Sjkim        CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
160280304Sjkim
161280304Sjkim    return ssl_x509_store_ctx_idx;
162280304Sjkim}
163280304Sjkim
164238405Sjkimstatic void ssl_cert_set_default_md(CERT *cert)
165280304Sjkim{
166280304Sjkim    /* Set digest values to defaults */
167238405Sjkim#ifndef OPENSSL_NO_DSA
168280304Sjkim    cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
169238405Sjkim#endif
170238405Sjkim#ifndef OPENSSL_NO_RSA
171280304Sjkim    cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
172280304Sjkim    cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
173238405Sjkim#endif
174238405Sjkim#ifndef OPENSSL_NO_ECDSA
175280304Sjkim    cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
176238405Sjkim#endif
177280304Sjkim}
178238405Sjkim
17955714SkrisCERT *ssl_cert_new(void)
180280304Sjkim{
181280304Sjkim    CERT *ret;
18255714Skris
183280304Sjkim    ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
184280304Sjkim    if (ret == NULL) {
185280304Sjkim        SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE);
186280304Sjkim        return (NULL);
187280304Sjkim    }
188280304Sjkim    memset(ret, 0, sizeof(CERT));
18955714Skris
190280304Sjkim    ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]);
191280304Sjkim    ret->references = 1;
192280304Sjkim    ssl_cert_set_default_md(ret);
193280304Sjkim    return (ret);
194280304Sjkim}
19555714Skris
19655714SkrisCERT *ssl_cert_dup(CERT *cert)
197280304Sjkim{
198280304Sjkim    CERT *ret;
199280304Sjkim    int i;
20055714Skris
201280304Sjkim    ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
202280304Sjkim    if (ret == NULL) {
203280304Sjkim        SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
204280304Sjkim        return (NULL);
205280304Sjkim    }
20655714Skris
207280304Sjkim    memset(ret, 0, sizeof(CERT));
20855714Skris
209291721Sjkim    ret->references = 1;
210280304Sjkim    ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
211280304Sjkim    /*
212280304Sjkim     * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that
213280304Sjkim     * more readable
214280304Sjkim     */
21555714Skris
216280304Sjkim    ret->valid = cert->valid;
217280304Sjkim    ret->mask_k = cert->mask_k;
218280304Sjkim    ret->mask_a = cert->mask_a;
219280304Sjkim    ret->export_mask_k = cert->export_mask_k;
220280304Sjkim    ret->export_mask_a = cert->export_mask_a;
22155714Skris
222109998Smarkm#ifndef OPENSSL_NO_RSA
223280304Sjkim    if (cert->rsa_tmp != NULL) {
224280304Sjkim        RSA_up_ref(cert->rsa_tmp);
225280304Sjkim        ret->rsa_tmp = cert->rsa_tmp;
226280304Sjkim    }
227280304Sjkim    ret->rsa_tmp_cb = cert->rsa_tmp_cb;
22855714Skris#endif
22955714Skris
230109998Smarkm#ifndef OPENSSL_NO_DH
231280304Sjkim    if (cert->dh_tmp != NULL) {
232280304Sjkim        ret->dh_tmp = DHparams_dup(cert->dh_tmp);
233280304Sjkim        if (ret->dh_tmp == NULL) {
234280304Sjkim            SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
235280304Sjkim            goto err;
236280304Sjkim        }
237280304Sjkim        if (cert->dh_tmp->priv_key) {
238280304Sjkim            BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
239280304Sjkim            if (!b) {
240280304Sjkim                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
241280304Sjkim                goto err;
242280304Sjkim            }
243280304Sjkim            ret->dh_tmp->priv_key = b;
244280304Sjkim        }
245280304Sjkim        if (cert->dh_tmp->pub_key) {
246280304Sjkim            BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
247280304Sjkim            if (!b) {
248280304Sjkim                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
249280304Sjkim                goto err;
250280304Sjkim            }
251280304Sjkim            ret->dh_tmp->pub_key = b;
252280304Sjkim        }
253280304Sjkim    }
254280304Sjkim    ret->dh_tmp_cb = cert->dh_tmp_cb;
25555714Skris#endif
25655714Skris
257160814Ssimon#ifndef OPENSSL_NO_ECDH
258280304Sjkim    if (cert->ecdh_tmp) {
259280304Sjkim        ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
260280304Sjkim        if (ret->ecdh_tmp == NULL) {
261280304Sjkim            SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
262280304Sjkim            goto err;
263280304Sjkim        }
264280304Sjkim    }
265280304Sjkim    ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
266160814Ssimon#endif
267160814Ssimon
268280304Sjkim    for (i = 0; i < SSL_PKEY_NUM; i++) {
269280304Sjkim        if (cert->pkeys[i].x509 != NULL) {
270280304Sjkim            ret->pkeys[i].x509 = cert->pkeys[i].x509;
271280304Sjkim            CRYPTO_add(&ret->pkeys[i].x509->references, 1, CRYPTO_LOCK_X509);
272280304Sjkim        }
27355714Skris
274280304Sjkim        if (cert->pkeys[i].privatekey != NULL) {
275280304Sjkim            ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
276280304Sjkim            CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
277280304Sjkim                       CRYPTO_LOCK_EVP_PKEY);
278280304Sjkim        }
279280304Sjkim    }
28055714Skris
281280304Sjkim    /*
282280304Sjkim     * ret->extra_certs *should* exist, but currently the own certificate
283280304Sjkim     * chain is held inside SSL_CTX
284280304Sjkim     */
285280304Sjkim
286280304Sjkim    /*
287280304Sjkim     * Set digests to defaults. NB: we don't copy existing values as they
288280304Sjkim     * will be set during handshake.
289280304Sjkim     */
290280304Sjkim    ssl_cert_set_default_md(ret);
291280304Sjkim
292280304Sjkim    return (ret);
293280304Sjkim
294160814Ssimon#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
295280304Sjkim err:
29676866Skris#endif
297109998Smarkm#ifndef OPENSSL_NO_RSA
298280304Sjkim    if (ret->rsa_tmp != NULL)
299280304Sjkim        RSA_free(ret->rsa_tmp);
30055714Skris#endif
301109998Smarkm#ifndef OPENSSL_NO_DH
302280304Sjkim    if (ret->dh_tmp != NULL)
303280304Sjkim        DH_free(ret->dh_tmp);
30455714Skris#endif
305160814Ssimon#ifndef OPENSSL_NO_ECDH
306280304Sjkim    if (ret->ecdh_tmp != NULL)
307280304Sjkim        EC_KEY_free(ret->ecdh_tmp);
308160814Ssimon#endif
30955714Skris
310280304Sjkim    for (i = 0; i < SSL_PKEY_NUM; i++) {
311280304Sjkim        if (ret->pkeys[i].x509 != NULL)
312280304Sjkim            X509_free(ret->pkeys[i].x509);
313280304Sjkim        if (ret->pkeys[i].privatekey != NULL)
314280304Sjkim            EVP_PKEY_free(ret->pkeys[i].privatekey);
315280304Sjkim    }
31655714Skris
317280304Sjkim    return NULL;
318280304Sjkim}
31955714Skris
32055714Skrisvoid ssl_cert_free(CERT *c)
321280304Sjkim{
322280304Sjkim    int i;
32355714Skris
324280304Sjkim    if (c == NULL)
325280304Sjkim        return;
32655714Skris
327280304Sjkim    i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT);
32855714Skris#ifdef REF_PRINT
329280304Sjkim    REF_PRINT("CERT", c);
33055714Skris#endif
331280304Sjkim    if (i > 0)
332280304Sjkim        return;
33355714Skris#ifdef REF_CHECK
334280304Sjkim    if (i < 0) {
335280304Sjkim        fprintf(stderr, "ssl_cert_free, bad reference count\n");
336280304Sjkim        abort();                /* ok */
337280304Sjkim    }
33855714Skris#endif
33955714Skris
340109998Smarkm#ifndef OPENSSL_NO_RSA
341280304Sjkim    if (c->rsa_tmp)
342280304Sjkim        RSA_free(c->rsa_tmp);
34355714Skris#endif
344109998Smarkm#ifndef OPENSSL_NO_DH
345280304Sjkim    if (c->dh_tmp)
346280304Sjkim        DH_free(c->dh_tmp);
34755714Skris#endif
348160814Ssimon#ifndef OPENSSL_NO_ECDH
349280304Sjkim    if (c->ecdh_tmp)
350280304Sjkim        EC_KEY_free(c->ecdh_tmp);
351160814Ssimon#endif
35255714Skris
353280304Sjkim    for (i = 0; i < SSL_PKEY_NUM; i++) {
354280304Sjkim        if (c->pkeys[i].x509 != NULL)
355280304Sjkim            X509_free(c->pkeys[i].x509);
356280304Sjkim        if (c->pkeys[i].privatekey != NULL)
357280304Sjkim            EVP_PKEY_free(c->pkeys[i].privatekey);
35855714Skris#if 0
359280304Sjkim        if (c->pkeys[i].publickey != NULL)
360280304Sjkim            EVP_PKEY_free(c->pkeys[i].publickey);
36155714Skris#endif
362280304Sjkim    }
363280304Sjkim    OPENSSL_free(c);
364280304Sjkim}
36555714Skris
36655714Skrisint ssl_cert_inst(CERT **o)
367280304Sjkim{
368280304Sjkim    /*
369280304Sjkim     * Create a CERT if there isn't already one (which cannot really happen,
370280304Sjkim     * as it is initially created in SSL_CTX_new; but the earlier code
371280304Sjkim     * usually allows for that one being non-existant, so we follow that
372280304Sjkim     * behaviour, as it might turn out that there actually is a reason for it
373280304Sjkim     * -- but I'm not sure that *all* of the existing code could cope with
374280304Sjkim     * s->cert being NULL, otherwise we could do without the initialization
375280304Sjkim     * in SSL_CTX_new).
376280304Sjkim     */
37755714Skris
378280304Sjkim    if (o == NULL) {
379280304Sjkim        SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
380280304Sjkim        return (0);
381280304Sjkim    }
382280304Sjkim    if (*o == NULL) {
383280304Sjkim        if ((*o = ssl_cert_new()) == NULL) {
384280304Sjkim            SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
385280304Sjkim            return (0);
386280304Sjkim        }
387280304Sjkim    }
388280304Sjkim    return (1);
389280304Sjkim}
39055714Skris
39155714SkrisSESS_CERT *ssl_sess_cert_new(void)
392280304Sjkim{
393280304Sjkim    SESS_CERT *ret;
39455714Skris
395280304Sjkim    ret = OPENSSL_malloc(sizeof *ret);
396280304Sjkim    if (ret == NULL) {
397280304Sjkim        SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
398280304Sjkim        return NULL;
399280304Sjkim    }
40055714Skris
401280304Sjkim    memset(ret, 0, sizeof *ret);
402280304Sjkim    ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
403280304Sjkim    ret->references = 1;
40455714Skris
405280304Sjkim    return ret;
406280304Sjkim}
40755714Skris
40855714Skrisvoid ssl_sess_cert_free(SESS_CERT *sc)
409280304Sjkim{
410280304Sjkim    int i;
41155714Skris
412280304Sjkim    if (sc == NULL)
413280304Sjkim        return;
41455714Skris
415280304Sjkim    i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
41655714Skris#ifdef REF_PRINT
417280304Sjkim    REF_PRINT("SESS_CERT", sc);
41855714Skris#endif
419280304Sjkim    if (i > 0)
420280304Sjkim        return;
42155714Skris#ifdef REF_CHECK
422280304Sjkim    if (i < 0) {
423280304Sjkim        fprintf(stderr, "ssl_sess_cert_free, bad reference count\n");
424280304Sjkim        abort();                /* ok */
425280304Sjkim    }
42655714Skris#endif
42755714Skris
428280304Sjkim    /* i == 0 */
429280304Sjkim    if (sc->cert_chain != NULL)
430280304Sjkim        sk_X509_pop_free(sc->cert_chain, X509_free);
431280304Sjkim    for (i = 0; i < SSL_PKEY_NUM; i++) {
432280304Sjkim        if (sc->peer_pkeys[i].x509 != NULL)
433280304Sjkim            X509_free(sc->peer_pkeys[i].x509);
434280304Sjkim#if 0                           /* We don't have the peer's private key.
435280304Sjkim                                 * These lines are just * here as a reminder
436280304Sjkim                                 * that we're still using a
437280304Sjkim                                 * not-quite-appropriate * data structure. */
438280304Sjkim        if (sc->peer_pkeys[i].privatekey != NULL)
439280304Sjkim            EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
44055714Skris#endif
441280304Sjkim    }
44255714Skris
443109998Smarkm#ifndef OPENSSL_NO_RSA
444280304Sjkim    if (sc->peer_rsa_tmp != NULL)
445280304Sjkim        RSA_free(sc->peer_rsa_tmp);
44655714Skris#endif
447109998Smarkm#ifndef OPENSSL_NO_DH
448280304Sjkim    if (sc->peer_dh_tmp != NULL)
449280304Sjkim        DH_free(sc->peer_dh_tmp);
45055714Skris#endif
451160814Ssimon#ifndef OPENSSL_NO_ECDH
452280304Sjkim    if (sc->peer_ecdh_tmp != NULL)
453280304Sjkim        EC_KEY_free(sc->peer_ecdh_tmp);
454160814Ssimon#endif
45555714Skris
456280304Sjkim    OPENSSL_free(sc);
457280304Sjkim}
45855714Skris
459280304Sjkimint ssl_set_peer_cert_type(SESS_CERT *sc, int type)
460280304Sjkim{
461280304Sjkim    sc->peer_cert_type = type;
462280304Sjkim    return (1);
463280304Sjkim}
46455714Skris
465280304Sjkimint ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
466280304Sjkim{
467280304Sjkim    X509 *x;
468280304Sjkim    int i;
469280304Sjkim    X509_STORE_CTX ctx;
47055714Skris
471280304Sjkim    if ((sk == NULL) || (sk_X509_num(sk) == 0))
472280304Sjkim        return (0);
47355714Skris
474280304Sjkim    x = sk_X509_value(sk, 0);
475280304Sjkim    if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) {
476280304Sjkim        SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB);
477280304Sjkim        return (0);
478280304Sjkim    }
479160814Ssimon#if 0
480280304Sjkim    if (SSL_get_verify_depth(s) >= 0)
481280304Sjkim        X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
482160814Ssimon#endif
483280304Sjkim    X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
484109998Smarkm
485280304Sjkim    /*
486280304Sjkim     * We need to inherit the verify parameters. These can be determined by
487280304Sjkim     * the context: if its a server it will verify SSL client certificates or
488280304Sjkim     * vice versa.
489280304Sjkim     */
49055714Skris
491280304Sjkim    X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server");
492280304Sjkim    /*
493280304Sjkim     * Anything non-default in "param" should overwrite anything in the ctx.
494280304Sjkim     */
495280304Sjkim    X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
49659191Skris
497280304Sjkim    if (s->verify_callback)
498280304Sjkim        X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
49989837Skris
500280304Sjkim    if (s->ctx->app_verify_callback != NULL)
501280304Sjkim#if 1                           /* new with OpenSSL 0.9.7 */
502280304Sjkim        i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
503109998Smarkm#else
504280304Sjkim        i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
505109998Smarkm#endif
506280304Sjkim    else {
507109998Smarkm#ifndef OPENSSL_NO_X509_VERIFY
508280304Sjkim        i = X509_verify_cert(&ctx);
50955714Skris#else
510280304Sjkim        i = 0;
511280304Sjkim        ctx.error = X509_V_ERR_APPLICATION_VERIFICATION;
512280304Sjkim        SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK);
51355714Skris#endif
514280304Sjkim    }
51555714Skris
516280304Sjkim    s->verify_result = ctx.error;
517280304Sjkim    X509_STORE_CTX_cleanup(&ctx);
51855714Skris
519280304Sjkim    return (i);
520280304Sjkim}
52155714Skris
522280304Sjkimstatic void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
523280304Sjkim                               STACK_OF(X509_NAME) *name_list)
524280304Sjkim{
525280304Sjkim    if (*ca_list != NULL)
526280304Sjkim        sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
52755714Skris
528280304Sjkim    *ca_list = name_list;
529280304Sjkim}
53055714Skris
53155714SkrisSTACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
532280304Sjkim{
533280304Sjkim    int i;
534280304Sjkim    STACK_OF(X509_NAME) *ret;
535280304Sjkim    X509_NAME *name;
53655714Skris
537280304Sjkim    ret = sk_X509_NAME_new_null();
538280304Sjkim    for (i = 0; i < sk_X509_NAME_num(sk); i++) {
539280304Sjkim        name = X509_NAME_dup(sk_X509_NAME_value(sk, i));
540280304Sjkim        if ((name == NULL) || !sk_X509_NAME_push(ret, name)) {
541280304Sjkim            sk_X509_NAME_pop_free(ret, X509_NAME_free);
542280304Sjkim            return (NULL);
543280304Sjkim        }
544280304Sjkim    }
545280304Sjkim    return (ret);
546280304Sjkim}
54755714Skris
548280304Sjkimvoid SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
549280304Sjkim{
550280304Sjkim    set_client_CA_list(&(s->client_CA), name_list);
551280304Sjkim}
55255714Skris
553280304Sjkimvoid SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
554280304Sjkim{
555280304Sjkim    set_client_CA_list(&(ctx->client_CA), name_list);
556280304Sjkim}
55755714Skris
558160814SsimonSTACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
559280304Sjkim{
560280304Sjkim    return (ctx->client_CA);
561280304Sjkim}
56255714Skris
563160814SsimonSTACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
564280304Sjkim{
565280304Sjkim    if (s->type == SSL_ST_CONNECT) { /* we are in the client */
566280304Sjkim        if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL))
567280304Sjkim            return (s->s3->tmp.ca_names);
568280304Sjkim        else
569280304Sjkim            return (NULL);
570280304Sjkim    } else {
571280304Sjkim        if (s->client_CA != NULL)
572280304Sjkim            return (s->client_CA);
573280304Sjkim        else
574280304Sjkim            return (s->ctx->client_CA);
575280304Sjkim    }
576280304Sjkim}
57755714Skris
578280304Sjkimstatic int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x)
579280304Sjkim{
580280304Sjkim    X509_NAME *name;
58155714Skris
582280304Sjkim    if (x == NULL)
583280304Sjkim        return (0);
584280304Sjkim    if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL))
585280304Sjkim        return (0);
58655714Skris
587280304Sjkim    if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL)
588280304Sjkim        return (0);
58955714Skris
590280304Sjkim    if (!sk_X509_NAME_push(*sk, name)) {
591280304Sjkim        X509_NAME_free(name);
592280304Sjkim        return (0);
593280304Sjkim    }
594280304Sjkim    return (1);
595280304Sjkim}
59655714Skris
597280304Sjkimint SSL_add_client_CA(SSL *ssl, X509 *x)
598280304Sjkim{
599280304Sjkim    return (add_client_CA(&(ssl->client_CA), x));
600280304Sjkim}
60155714Skris
602280304Sjkimint SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
603280304Sjkim{
604280304Sjkim    return (add_client_CA(&(ctx->client_CA), x));
605280304Sjkim}
60655714Skris
607280304Sjkimstatic int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
608280304Sjkim{
609280304Sjkim    return (X509_NAME_cmp(*a, *b));
610280304Sjkim}
611280304Sjkim
612109998Smarkm#ifndef OPENSSL_NO_STDIO
613280304Sjkim/**
61455714Skris * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
61555714Skris * it doesn't really have anything to do with clients (except that a common use
61655714Skris * for a stack of CAs is to send it to the client). Actually, it doesn't have
61755714Skris * much to do with CAs, either, since it will load any old cert.
61855714Skris * \param file the file containing one or more certs.
61955714Skris * \return a ::STACK containing the certs.
62055714Skris */
62155714SkrisSTACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
622280304Sjkim{
623280304Sjkim    BIO *in;
624280304Sjkim    X509 *x = NULL;
625280304Sjkim    X509_NAME *xn = NULL;
626280304Sjkim    STACK_OF(X509_NAME) *ret = NULL, *sk;
62755714Skris
628280304Sjkim    sk = sk_X509_NAME_new(xname_cmp);
62955714Skris
630280304Sjkim    in = BIO_new(BIO_s_file_internal());
63155714Skris
632280304Sjkim    if ((sk == NULL) || (in == NULL)) {
633280304Sjkim        SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
634280304Sjkim        goto err;
635280304Sjkim    }
63655714Skris
637280304Sjkim    if (!BIO_read_filename(in, file))
638280304Sjkim        goto err;
63955714Skris
640280304Sjkim    for (;;) {
641280304Sjkim        if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
642280304Sjkim            break;
643280304Sjkim        if (ret == NULL) {
644280304Sjkim            ret = sk_X509_NAME_new_null();
645280304Sjkim            if (ret == NULL) {
646280304Sjkim                SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
647280304Sjkim                goto err;
648280304Sjkim            }
649280304Sjkim        }
650280304Sjkim        if ((xn = X509_get_subject_name(x)) == NULL)
651280304Sjkim            goto err;
652280304Sjkim        /* check for duplicates */
653280304Sjkim        xn = X509_NAME_dup(xn);
654280304Sjkim        if (xn == NULL)
655280304Sjkim            goto err;
656280304Sjkim        if (sk_X509_NAME_find(sk, xn) >= 0)
657280304Sjkim            X509_NAME_free(xn);
658280304Sjkim        else {
659280304Sjkim            sk_X509_NAME_push(sk, xn);
660280304Sjkim            sk_X509_NAME_push(ret, xn);
661280304Sjkim        }
662280304Sjkim    }
663280304Sjkim
664280304Sjkim    if (0) {
665280304Sjkim err:
666280304Sjkim        if (ret != NULL)
667280304Sjkim            sk_X509_NAME_pop_free(ret, X509_NAME_free);
668280304Sjkim        ret = NULL;
669280304Sjkim    }
670280304Sjkim    if (sk != NULL)
671280304Sjkim        sk_X509_NAME_free(sk);
672280304Sjkim    if (in != NULL)
673280304Sjkim        BIO_free(in);
674280304Sjkim    if (x != NULL)
675280304Sjkim        X509_free(x);
676280304Sjkim    if (ret != NULL)
677280304Sjkim        ERR_clear_error();
678280304Sjkim    return (ret);
679280304Sjkim}
68055714Skris#endif
68155714Skris
682280304Sjkim/**
68355714Skris * Add a file of certs to a stack.
68455714Skris * \param stack the stack to add to.
68555714Skris * \param file the file to add from. All certs in this file that are not
68655714Skris * already in the stack will be added.
68755714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some
68855714Skris * certs may have been added to \c stack.
68955714Skris */
69055714Skris
69155714Skrisint SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
692280304Sjkim                                        const char *file)
693280304Sjkim{
694280304Sjkim    BIO *in;
695280304Sjkim    X509 *x = NULL;
696280304Sjkim    X509_NAME *xn = NULL;
697280304Sjkim    int ret = 1;
698280304Sjkim    int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b);
69955714Skris
700280304Sjkim    oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
701215697Ssimon
702280304Sjkim    in = BIO_new(BIO_s_file_internal());
70355714Skris
704280304Sjkim    if (in == NULL) {
705280304Sjkim        SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,
706280304Sjkim               ERR_R_MALLOC_FAILURE);
707280304Sjkim        goto err;
708280304Sjkim    }
70955714Skris
710280304Sjkim    if (!BIO_read_filename(in, file))
711280304Sjkim        goto err;
712280304Sjkim
713280304Sjkim    for (;;) {
714280304Sjkim        if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
715280304Sjkim            break;
716280304Sjkim        if ((xn = X509_get_subject_name(x)) == NULL)
717280304Sjkim            goto err;
718280304Sjkim        xn = X509_NAME_dup(xn);
719280304Sjkim        if (xn == NULL)
720280304Sjkim            goto err;
721280304Sjkim        if (sk_X509_NAME_find(stack, xn) >= 0)
722280304Sjkim            X509_NAME_free(xn);
723280304Sjkim        else
724280304Sjkim            sk_X509_NAME_push(stack, xn);
725280304Sjkim    }
726280304Sjkim
727280304Sjkim    ERR_clear_error();
728280304Sjkim
729280304Sjkim    if (0) {
730280304Sjkim err:
731280304Sjkim        ret = 0;
732280304Sjkim    }
733280304Sjkim    if (in != NULL)
734280304Sjkim        BIO_free(in);
735280304Sjkim    if (x != NULL)
736280304Sjkim        X509_free(x);
737280304Sjkim
738280304Sjkim    (void)sk_X509_NAME_set_cmp_func(stack, oldcmp);
739280304Sjkim
740280304Sjkim    return ret;
741280304Sjkim}
742280304Sjkim
743280304Sjkim/**
74455714Skris * Add a directory of certs to a stack.
74555714Skris * \param stack the stack to append to.
74655714Skris * \param dir the directory to append from. All files in this directory will be
74755714Skris * examined as potential certs. Any that are acceptable to
74855714Skris * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
74955714Skris * included.
75055714Skris * \return 1 for success, 0 for failure. Note that in the case of failure some
75155714Skris * certs may have been added to \c stack.
75255714Skris */
75355714Skris
75455714Skrisint SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
755280304Sjkim                                       const char *dir)
756280304Sjkim{
757280304Sjkim    OPENSSL_DIR_CTX *d = NULL;
758280304Sjkim    const char *filename;
759280304Sjkim    int ret = 0;
76055714Skris
761280304Sjkim    CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
76255714Skris
763280304Sjkim    /* Note that a side effect is that the CAs will be sorted by name */
764160814Ssimon
765280304Sjkim    while ((filename = OPENSSL_DIR_read(&d, dir))) {
766280304Sjkim        char buf[1024];
767280304Sjkim        int r;
768160814Ssimon
769280304Sjkim        if (strlen(dir) + strlen(filename) + 2 > sizeof buf) {
770280304Sjkim            SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,
771280304Sjkim                   SSL_R_PATH_TOO_LONG);
772280304Sjkim            goto err;
773280304Sjkim        }
774160814Ssimon#ifdef OPENSSL_SYS_VMS
775280304Sjkim        r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename);
776160814Ssimon#else
777280304Sjkim        r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
778160814Ssimon#endif
779280304Sjkim        if (r <= 0 || r >= (int)sizeof(buf))
780280304Sjkim            goto err;
781280304Sjkim        if (!SSL_add_file_cert_subjects_to_stack(stack, buf))
782280304Sjkim            goto err;
783280304Sjkim    }
78455714Skris
785280304Sjkim    if (errno) {
786280304Sjkim        SYSerr(SYS_F_OPENDIR, get_last_sys_error());
787280304Sjkim        ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
788280304Sjkim        SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
789280304Sjkim        goto err;
790280304Sjkim    }
791142425Snectar
792280304Sjkim    ret = 1;
793109998Smarkm
794280304Sjkim err:
795280304Sjkim    if (d)
796280304Sjkim        OPENSSL_DIR_end(&d);
797280304Sjkim    CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
798280304Sjkim    return ret;
799280304Sjkim}
800