xref: /freebsd/crypto/openssl/ssl/ssl_cert.c (revision 6f9291cea8b06d251243fd47a7234018541832a3)
1*6f9291ceSJung-uk Kim /*
2*6f9291ceSJung-uk Kim  * ! \file ssl/ssl_cert.c
3*6f9291ceSJung-uk Kim  */
474664626SKris Kennaway /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
574664626SKris Kennaway  * All rights reserved.
674664626SKris Kennaway  *
774664626SKris Kennaway  * This package is an SSL implementation written
874664626SKris Kennaway  * by Eric Young (eay@cryptsoft.com).
974664626SKris Kennaway  * The implementation was written so as to conform with Netscapes SSL.
1074664626SKris Kennaway  *
1174664626SKris Kennaway  * This library is free for commercial and non-commercial use as long as
1274664626SKris Kennaway  * the following conditions are aheared to.  The following conditions
1374664626SKris Kennaway  * apply to all code found in this distribution, be it the RC4, RSA,
1474664626SKris Kennaway  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1574664626SKris Kennaway  * included with this distribution is covered by the same copyright terms
1674664626SKris Kennaway  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1774664626SKris Kennaway  *
1874664626SKris Kennaway  * Copyright remains Eric Young's, and as such any Copyright notices in
1974664626SKris Kennaway  * the code are not to be removed.
2074664626SKris Kennaway  * If this package is used in a product, Eric Young should be given attribution
2174664626SKris Kennaway  * as the author of the parts of the library used.
2274664626SKris Kennaway  * This can be in the form of a textual message at program startup or
2374664626SKris Kennaway  * in documentation (online or textual) provided with the package.
2474664626SKris Kennaway  *
2574664626SKris Kennaway  * Redistribution and use in source and binary forms, with or without
2674664626SKris Kennaway  * modification, are permitted provided that the following conditions
2774664626SKris Kennaway  * are met:
2874664626SKris Kennaway  * 1. Redistributions of source code must retain the copyright
2974664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
3074664626SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
3174664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer in the
3274664626SKris Kennaway  *    documentation and/or other materials provided with the distribution.
3374664626SKris Kennaway  * 3. All advertising materials mentioning features or use of this software
3474664626SKris Kennaway  *    must display the following acknowledgement:
3574664626SKris Kennaway  *    "This product includes cryptographic software written by
3674664626SKris Kennaway  *     Eric Young (eay@cryptsoft.com)"
3774664626SKris Kennaway  *    The word 'cryptographic' can be left out if the rouines from the library
3874664626SKris Kennaway  *    being used are not cryptographic related :-).
3974664626SKris Kennaway  * 4. If you include any Windows specific code (or a derivative thereof) from
4074664626SKris Kennaway  *    the apps directory (application code) you must include an acknowledgement:
4174664626SKris Kennaway  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4274664626SKris Kennaway  *
4374664626SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4474664626SKris Kennaway  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4574664626SKris Kennaway  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4674664626SKris Kennaway  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4774664626SKris Kennaway  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4874664626SKris Kennaway  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4974664626SKris Kennaway  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5074664626SKris Kennaway  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5174664626SKris Kennaway  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5274664626SKris Kennaway  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5374664626SKris Kennaway  * SUCH DAMAGE.
5474664626SKris Kennaway  *
5574664626SKris Kennaway  * The licence and distribution terms for any publically available version or
5674664626SKris Kennaway  * derivative of this code cannot be changed.  i.e. this code cannot simply be
5774664626SKris Kennaway  * copied and put under another distribution licence
5874664626SKris Kennaway  * [including the GNU Public Licence.]
5974664626SKris Kennaway  */
6074664626SKris Kennaway /* ====================================================================
611f13597dSJung-uk Kim  * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
6274664626SKris Kennaway  *
6374664626SKris Kennaway  * Redistribution and use in source and binary forms, with or without
6474664626SKris Kennaway  * modification, are permitted provided that the following conditions
6574664626SKris Kennaway  * are met:
6674664626SKris Kennaway  *
6774664626SKris Kennaway  * 1. Redistributions of source code must retain the above copyright
6874664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer.
6974664626SKris Kennaway  *
7074664626SKris Kennaway  * 2. Redistributions in binary form must reproduce the above copyright
7174664626SKris Kennaway  *    notice, this list of conditions and the following disclaimer in
7274664626SKris Kennaway  *    the documentation and/or other materials provided with the
7374664626SKris Kennaway  *    distribution.
7474664626SKris Kennaway  *
7574664626SKris Kennaway  * 3. All advertising materials mentioning features or use of this
7674664626SKris Kennaway  *    software must display the following acknowledgment:
7774664626SKris Kennaway  *    "This product includes software developed by the OpenSSL Project
78ed5d4f9aSSimon L. B. Nielsen  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
7974664626SKris Kennaway  *
8074664626SKris Kennaway  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
8174664626SKris Kennaway  *    endorse or promote products derived from this software without
8274664626SKris Kennaway  *    prior written permission. For written permission, please contact
83ed5d4f9aSSimon L. B. Nielsen  *    openssl-core@openssl.org.
8474664626SKris Kennaway  *
8574664626SKris Kennaway  * 5. Products derived from this software may not be called "OpenSSL"
8674664626SKris Kennaway  *    nor may "OpenSSL" appear in their names without prior written
8774664626SKris Kennaway  *    permission of the OpenSSL Project.
8874664626SKris Kennaway  *
8974664626SKris Kennaway  * 6. Redistributions of any form whatsoever must retain the following
9074664626SKris Kennaway  *    acknowledgment:
9174664626SKris Kennaway  *    "This product includes software developed by the OpenSSL Project
92ed5d4f9aSSimon L. B. Nielsen  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
9374664626SKris Kennaway  *
9474664626SKris Kennaway  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9574664626SKris Kennaway  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9674664626SKris Kennaway  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9774664626SKris Kennaway  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9874664626SKris Kennaway  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9974664626SKris Kennaway  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
10074664626SKris Kennaway  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10174664626SKris Kennaway  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10274664626SKris Kennaway  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10374664626SKris Kennaway  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10474664626SKris Kennaway  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10574664626SKris Kennaway  * OF THE POSSIBILITY OF SUCH DAMAGE.
10674664626SKris Kennaway  * ====================================================================
107ed5d4f9aSSimon L. B. Nielsen  *
108ed5d4f9aSSimon L. B. Nielsen  * This product includes cryptographic software written by Eric Young
109ed5d4f9aSSimon L. B. Nielsen  * (eay@cryptsoft.com).  This product includes software written by Tim
110ed5d4f9aSSimon L. B. Nielsen  * Hudson (tjh@cryptsoft.com).
111ed5d4f9aSSimon L. B. Nielsen  *
11274664626SKris Kennaway  */
1133b4e3dcbSSimon L. B. Nielsen /* ====================================================================
1143b4e3dcbSSimon L. B. Nielsen  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
1153b4e3dcbSSimon L. B. Nielsen  * ECC cipher suite support in OpenSSL originally developed by
1163b4e3dcbSSimon L. B. Nielsen  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
1173b4e3dcbSSimon L. B. Nielsen  */
11874664626SKris Kennaway 
11974664626SKris Kennaway #include <stdio.h>
120f579bf8eSKris Kennaway 
1215c87c606SMark Murray #include "e_os.h"
122f579bf8eSKris Kennaway #ifndef NO_SYS_TYPES_H
12374664626SKris Kennaway # include <sys/types.h>
124f579bf8eSKris Kennaway #endif
125f579bf8eSKris Kennaway 
1263b4e3dcbSSimon L. B. Nielsen #include "o_dir.h"
12774664626SKris Kennaway #include <openssl/objects.h>
12874664626SKris Kennaway #include <openssl/bio.h>
12974664626SKris Kennaway #include <openssl/pem.h>
130f579bf8eSKris Kennaway #include <openssl/x509v3.h>
1313b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_DH
1323b4e3dcbSSimon L. B. Nielsen # include <openssl/dh.h>
1333b4e3dcbSSimon L. B. Nielsen #endif
1343b4e3dcbSSimon L. B. Nielsen #include <openssl/bn.h>
13574664626SKris Kennaway #include "ssl_locl.h"
13674664626SKris Kennaway 
13774664626SKris Kennaway int SSL_get_ex_data_X509_STORE_CTX_idx(void)
13874664626SKris Kennaway {
1395c87c606SMark Murray     static volatile int ssl_x509_store_ctx_idx = -1;
140ed5d4f9aSSimon L. B. Nielsen     int got_write_lock = 0;
141ed5d4f9aSSimon L. B. Nielsen 
142ed5d4f9aSSimon L. B. Nielsen     CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
1435c87c606SMark Murray 
144*6f9291ceSJung-uk Kim     if (ssl_x509_store_ctx_idx < 0) {
145ed5d4f9aSSimon L. B. Nielsen         CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
1465c87c606SMark Murray         CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
147ed5d4f9aSSimon L. B. Nielsen         got_write_lock = 1;
14874664626SKris Kennaway 
149*6f9291ceSJung-uk Kim         if (ssl_x509_store_ctx_idx < 0) {
150*6f9291ceSJung-uk Kim             ssl_x509_store_ctx_idx =
151*6f9291ceSJung-uk Kim                 X509_STORE_CTX_get_ex_new_index(0, "SSL for verify callback",
152*6f9291ceSJung-uk Kim                                                 NULL, NULL, NULL);
15374664626SKris Kennaway         }
1545c87c606SMark Murray     }
155ed5d4f9aSSimon L. B. Nielsen 
156ed5d4f9aSSimon L. B. Nielsen     if (got_write_lock)
157ed5d4f9aSSimon L. B. Nielsen         CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
158ed5d4f9aSSimon L. B. Nielsen     else
159ed5d4f9aSSimon L. B. Nielsen         CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
160ed5d4f9aSSimon L. B. Nielsen 
1615c87c606SMark Murray     return ssl_x509_store_ctx_idx;
16274664626SKris Kennaway }
16374664626SKris Kennaway 
1641f13597dSJung-uk Kim static void ssl_cert_set_default_md(CERT *cert)
1651f13597dSJung-uk Kim {
1661f13597dSJung-uk Kim     /* Set digest values to defaults */
1671f13597dSJung-uk Kim #ifndef OPENSSL_NO_DSA
16809286989SJung-uk Kim     cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
1691f13597dSJung-uk Kim #endif
1701f13597dSJung-uk Kim #ifndef OPENSSL_NO_RSA
1711f13597dSJung-uk Kim     cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
1721f13597dSJung-uk Kim     cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
1731f13597dSJung-uk Kim #endif
1741f13597dSJung-uk Kim #ifndef OPENSSL_NO_ECDSA
17509286989SJung-uk Kim     cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
1761f13597dSJung-uk Kim #endif
1771f13597dSJung-uk Kim }
1781f13597dSJung-uk Kim 
17974664626SKris Kennaway CERT *ssl_cert_new(void)
18074664626SKris Kennaway {
18174664626SKris Kennaway     CERT *ret;
18274664626SKris Kennaway 
183ddd58736SKris Kennaway     ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
184*6f9291ceSJung-uk Kim     if (ret == NULL) {
18574664626SKris Kennaway         SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE);
18674664626SKris Kennaway         return (NULL);
18774664626SKris Kennaway     }
18874664626SKris Kennaway     memset(ret, 0, sizeof(CERT));
18974664626SKris Kennaway 
19074664626SKris Kennaway     ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]);
19174664626SKris Kennaway     ret->references = 1;
1921f13597dSJung-uk Kim     ssl_cert_set_default_md(ret);
19374664626SKris Kennaway     return (ret);
19474664626SKris Kennaway }
19574664626SKris Kennaway 
19674664626SKris Kennaway CERT *ssl_cert_dup(CERT *cert)
19774664626SKris Kennaway {
19874664626SKris Kennaway     CERT *ret;
19974664626SKris Kennaway     int i;
20074664626SKris Kennaway 
201ddd58736SKris Kennaway     ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
202*6f9291ceSJung-uk Kim     if (ret == NULL) {
20374664626SKris Kennaway         SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
20474664626SKris Kennaway         return (NULL);
20574664626SKris Kennaway     }
20674664626SKris Kennaway 
20774664626SKris Kennaway     memset(ret, 0, sizeof(CERT));
20874664626SKris Kennaway 
20974664626SKris Kennaway     ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
210*6f9291ceSJung-uk Kim     /*
211*6f9291ceSJung-uk Kim      * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that
212*6f9291ceSJung-uk Kim      * more readable
213*6f9291ceSJung-uk Kim      */
21474664626SKris Kennaway 
21574664626SKris Kennaway     ret->valid = cert->valid;
2161f13597dSJung-uk Kim     ret->mask_k = cert->mask_k;
2171f13597dSJung-uk Kim     ret->mask_a = cert->mask_a;
2181f13597dSJung-uk Kim     ret->export_mask_k = cert->export_mask_k;
2191f13597dSJung-uk Kim     ret->export_mask_a = cert->export_mask_a;
22074664626SKris Kennaway 
2215c87c606SMark Murray #ifndef OPENSSL_NO_RSA
222*6f9291ceSJung-uk Kim     if (cert->rsa_tmp != NULL) {
2235c87c606SMark Murray         RSA_up_ref(cert->rsa_tmp);
22474664626SKris Kennaway         ret->rsa_tmp = cert->rsa_tmp;
22574664626SKris Kennaway     }
22674664626SKris Kennaway     ret->rsa_tmp_cb = cert->rsa_tmp_cb;
22774664626SKris Kennaway #endif
22874664626SKris Kennaway 
2295c87c606SMark Murray #ifndef OPENSSL_NO_DH
230*6f9291ceSJung-uk Kim     if (cert->dh_tmp != NULL) {
23174664626SKris Kennaway         ret->dh_tmp = DHparams_dup(cert->dh_tmp);
232*6f9291ceSJung-uk Kim         if (ret->dh_tmp == NULL) {
233f579bf8eSKris Kennaway             SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
23474664626SKris Kennaway             goto err;
23574664626SKris Kennaway         }
236*6f9291ceSJung-uk Kim         if (cert->dh_tmp->priv_key) {
237f579bf8eSKris Kennaway             BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
238*6f9291ceSJung-uk Kim             if (!b) {
239f579bf8eSKris Kennaway                 SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
240f579bf8eSKris Kennaway                 goto err;
241f579bf8eSKris Kennaway             }
242f579bf8eSKris Kennaway             ret->dh_tmp->priv_key = b;
243f579bf8eSKris Kennaway         }
244*6f9291ceSJung-uk Kim         if (cert->dh_tmp->pub_key) {
245f579bf8eSKris Kennaway             BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
246*6f9291ceSJung-uk Kim             if (!b) {
247f579bf8eSKris Kennaway                 SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
248f579bf8eSKris Kennaway                 goto err;
249f579bf8eSKris Kennaway             }
250f579bf8eSKris Kennaway             ret->dh_tmp->pub_key = b;
251f579bf8eSKris Kennaway         }
25274664626SKris Kennaway     }
25374664626SKris Kennaway     ret->dh_tmp_cb = cert->dh_tmp_cb;
25474664626SKris Kennaway #endif
25574664626SKris Kennaway 
2563b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH
257*6f9291ceSJung-uk Kim     if (cert->ecdh_tmp) {
2583b4e3dcbSSimon L. B. Nielsen         ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
259*6f9291ceSJung-uk Kim         if (ret->ecdh_tmp == NULL) {
2603b4e3dcbSSimon L. B. Nielsen             SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
2613b4e3dcbSSimon L. B. Nielsen             goto err;
2623b4e3dcbSSimon L. B. Nielsen         }
2633b4e3dcbSSimon L. B. Nielsen     }
2643b4e3dcbSSimon L. B. Nielsen     ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
2653b4e3dcbSSimon L. B. Nielsen #endif
2663b4e3dcbSSimon L. B. Nielsen 
267*6f9291ceSJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++) {
268*6f9291ceSJung-uk Kim         if (cert->pkeys[i].x509 != NULL) {
26974664626SKris Kennaway             ret->pkeys[i].x509 = cert->pkeys[i].x509;
270*6f9291ceSJung-uk Kim             CRYPTO_add(&ret->pkeys[i].x509->references, 1, CRYPTO_LOCK_X509);
27174664626SKris Kennaway         }
27274664626SKris Kennaway 
273*6f9291ceSJung-uk Kim         if (cert->pkeys[i].privatekey != NULL) {
27474664626SKris Kennaway             ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
27574664626SKris Kennaway             CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
27674664626SKris Kennaway                        CRYPTO_LOCK_EVP_PKEY);
27774664626SKris Kennaway         }
27874664626SKris Kennaway     }
27974664626SKris Kennaway 
280*6f9291ceSJung-uk Kim     /*
281*6f9291ceSJung-uk Kim      * ret->extra_certs *should* exist, but currently the own certificate
282*6f9291ceSJung-uk Kim      * chain is held inside SSL_CTX
283*6f9291ceSJung-uk Kim      */
28474664626SKris Kennaway 
28574664626SKris Kennaway     ret->references = 1;
286*6f9291ceSJung-uk Kim     /*
287*6f9291ceSJung-uk Kim      * Set digests to defaults. NB: we don't copy existing values as they
2881f13597dSJung-uk Kim      * will be set during handshake.
2891f13597dSJung-uk Kim      */
2901f13597dSJung-uk Kim     ssl_cert_set_default_md(ret);
29174664626SKris Kennaway 
29274664626SKris Kennaway     return (ret);
29374664626SKris Kennaway 
2943b4e3dcbSSimon L. B. Nielsen #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
29574664626SKris Kennaway  err:
2965740a5e3SKris Kennaway #endif
2975c87c606SMark Murray #ifndef OPENSSL_NO_RSA
29874664626SKris Kennaway     if (ret->rsa_tmp != NULL)
29974664626SKris Kennaway         RSA_free(ret->rsa_tmp);
30074664626SKris Kennaway #endif
3015c87c606SMark Murray #ifndef OPENSSL_NO_DH
30274664626SKris Kennaway     if (ret->dh_tmp != NULL)
30374664626SKris Kennaway         DH_free(ret->dh_tmp);
30474664626SKris Kennaway #endif
3053b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH
3063b4e3dcbSSimon L. B. Nielsen     if (ret->ecdh_tmp != NULL)
3073b4e3dcbSSimon L. B. Nielsen         EC_KEY_free(ret->ecdh_tmp);
3083b4e3dcbSSimon L. B. Nielsen #endif
30974664626SKris Kennaway 
310*6f9291ceSJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++) {
31174664626SKris Kennaway         if (ret->pkeys[i].x509 != NULL)
31274664626SKris Kennaway             X509_free(ret->pkeys[i].x509);
31374664626SKris Kennaway         if (ret->pkeys[i].privatekey != NULL)
31474664626SKris Kennaway             EVP_PKEY_free(ret->pkeys[i].privatekey);
31574664626SKris Kennaway     }
31674664626SKris Kennaway 
31774664626SKris Kennaway     return NULL;
31874664626SKris Kennaway }
31974664626SKris Kennaway 
32074664626SKris Kennaway void ssl_cert_free(CERT *c)
32174664626SKris Kennaway {
32274664626SKris Kennaway     int i;
32374664626SKris Kennaway 
32474664626SKris Kennaway     if (c == NULL)
32574664626SKris Kennaway         return;
32674664626SKris Kennaway 
32774664626SKris Kennaway     i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT);
32874664626SKris Kennaway #ifdef REF_PRINT
32974664626SKris Kennaway     REF_PRINT("CERT", c);
33074664626SKris Kennaway #endif
331*6f9291ceSJung-uk Kim     if (i > 0)
332*6f9291ceSJung-uk Kim         return;
33374664626SKris Kennaway #ifdef REF_CHECK
334*6f9291ceSJung-uk Kim     if (i < 0) {
33574664626SKris Kennaway         fprintf(stderr, "ssl_cert_free, bad reference count\n");
33674664626SKris Kennaway         abort();                /* ok */
33774664626SKris Kennaway     }
33874664626SKris Kennaway #endif
33974664626SKris Kennaway 
3405c87c606SMark Murray #ifndef OPENSSL_NO_RSA
341*6f9291ceSJung-uk Kim     if (c->rsa_tmp)
342*6f9291ceSJung-uk Kim         RSA_free(c->rsa_tmp);
34374664626SKris Kennaway #endif
3445c87c606SMark Murray #ifndef OPENSSL_NO_DH
345*6f9291ceSJung-uk Kim     if (c->dh_tmp)
346*6f9291ceSJung-uk Kim         DH_free(c->dh_tmp);
34774664626SKris Kennaway #endif
3483b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH
349*6f9291ceSJung-uk Kim     if (c->ecdh_tmp)
350*6f9291ceSJung-uk Kim         EC_KEY_free(c->ecdh_tmp);
3513b4e3dcbSSimon L. B. Nielsen #endif
35274664626SKris Kennaway 
353*6f9291ceSJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++) {
35474664626SKris Kennaway         if (c->pkeys[i].x509 != NULL)
35574664626SKris Kennaway             X509_free(c->pkeys[i].x509);
35674664626SKris Kennaway         if (c->pkeys[i].privatekey != NULL)
35774664626SKris Kennaway             EVP_PKEY_free(c->pkeys[i].privatekey);
35874664626SKris Kennaway #if 0
35974664626SKris Kennaway         if (c->pkeys[i].publickey != NULL)
36074664626SKris Kennaway             EVP_PKEY_free(c->pkeys[i].publickey);
36174664626SKris Kennaway #endif
36274664626SKris Kennaway     }
363ddd58736SKris Kennaway     OPENSSL_free(c);
36474664626SKris Kennaway }
36574664626SKris Kennaway 
36674664626SKris Kennaway int ssl_cert_inst(CERT **o)
36774664626SKris Kennaway {
368*6f9291ceSJung-uk Kim     /*
369*6f9291ceSJung-uk Kim      * Create a CERT if there isn't already one (which cannot really happen,
370*6f9291ceSJung-uk Kim      * as it is initially created in SSL_CTX_new; but the earlier code
371*6f9291ceSJung-uk Kim      * usually allows for that one being non-existant, so we follow that
372*6f9291ceSJung-uk Kim      * behaviour, as it might turn out that there actually is a reason for it
373*6f9291ceSJung-uk Kim      * -- but I'm not sure that *all* of the existing code could cope with
374*6f9291ceSJung-uk Kim      * s->cert being NULL, otherwise we could do without the initialization
375*6f9291ceSJung-uk Kim      * in SSL_CTX_new).
37674664626SKris Kennaway      */
37774664626SKris Kennaway 
378*6f9291ceSJung-uk Kim     if (o == NULL) {
37974664626SKris Kennaway         SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
38074664626SKris Kennaway         return (0);
38174664626SKris Kennaway     }
382*6f9291ceSJung-uk Kim     if (*o == NULL) {
383*6f9291ceSJung-uk Kim         if ((*o = ssl_cert_new()) == NULL) {
38474664626SKris Kennaway             SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
38574664626SKris Kennaway             return (0);
38674664626SKris Kennaway         }
38774664626SKris Kennaway     }
38874664626SKris Kennaway     return (1);
38974664626SKris Kennaway }
39074664626SKris Kennaway 
39174664626SKris Kennaway SESS_CERT *ssl_sess_cert_new(void)
39274664626SKris Kennaway {
39374664626SKris Kennaway     SESS_CERT *ret;
39474664626SKris Kennaway 
395ddd58736SKris Kennaway     ret = OPENSSL_malloc(sizeof *ret);
396*6f9291ceSJung-uk Kim     if (ret == NULL) {
39774664626SKris Kennaway         SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
39874664626SKris Kennaway         return NULL;
39974664626SKris Kennaway     }
40074664626SKris Kennaway 
40174664626SKris Kennaway     memset(ret, 0, sizeof *ret);
40274664626SKris Kennaway     ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
40374664626SKris Kennaway     ret->references = 1;
40474664626SKris Kennaway 
40574664626SKris Kennaway     return ret;
40674664626SKris Kennaway }
40774664626SKris Kennaway 
40874664626SKris Kennaway void ssl_sess_cert_free(SESS_CERT *sc)
40974664626SKris Kennaway {
41074664626SKris Kennaway     int i;
41174664626SKris Kennaway 
41274664626SKris Kennaway     if (sc == NULL)
41374664626SKris Kennaway         return;
41474664626SKris Kennaway 
41574664626SKris Kennaway     i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
41674664626SKris Kennaway #ifdef REF_PRINT
41774664626SKris Kennaway     REF_PRINT("SESS_CERT", sc);
41874664626SKris Kennaway #endif
41974664626SKris Kennaway     if (i > 0)
42074664626SKris Kennaway         return;
42174664626SKris Kennaway #ifdef REF_CHECK
422*6f9291ceSJung-uk Kim     if (i < 0) {
42374664626SKris Kennaway         fprintf(stderr, "ssl_sess_cert_free, bad reference count\n");
42474664626SKris Kennaway         abort();                /* ok */
42574664626SKris Kennaway     }
42674664626SKris Kennaway #endif
42774664626SKris Kennaway 
42874664626SKris Kennaway     /* i == 0 */
42974664626SKris Kennaway     if (sc->cert_chain != NULL)
43074664626SKris Kennaway         sk_X509_pop_free(sc->cert_chain, X509_free);
431*6f9291ceSJung-uk Kim     for (i = 0; i < SSL_PKEY_NUM; i++) {
43274664626SKris Kennaway         if (sc->peer_pkeys[i].x509 != NULL)
43374664626SKris Kennaway             X509_free(sc->peer_pkeys[i].x509);
434*6f9291ceSJung-uk Kim #if 0                           /* We don't have the peer's private key.
435*6f9291ceSJung-uk Kim                                  * These lines are just * here as a reminder
436*6f9291ceSJung-uk Kim                                  * that we're still using a
437*6f9291ceSJung-uk Kim                                  * not-quite-appropriate * data structure. */
43874664626SKris Kennaway         if (sc->peer_pkeys[i].privatekey != NULL)
43974664626SKris Kennaway             EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
44074664626SKris Kennaway #endif
44174664626SKris Kennaway     }
44274664626SKris Kennaway 
4435c87c606SMark Murray #ifndef OPENSSL_NO_RSA
44474664626SKris Kennaway     if (sc->peer_rsa_tmp != NULL)
44574664626SKris Kennaway         RSA_free(sc->peer_rsa_tmp);
44674664626SKris Kennaway #endif
4475c87c606SMark Murray #ifndef OPENSSL_NO_DH
44874664626SKris Kennaway     if (sc->peer_dh_tmp != NULL)
44974664626SKris Kennaway         DH_free(sc->peer_dh_tmp);
45074664626SKris Kennaway #endif
4513b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_ECDH
4523b4e3dcbSSimon L. B. Nielsen     if (sc->peer_ecdh_tmp != NULL)
4533b4e3dcbSSimon L. B. Nielsen         EC_KEY_free(sc->peer_ecdh_tmp);
4543b4e3dcbSSimon L. B. Nielsen #endif
45574664626SKris Kennaway 
456ddd58736SKris Kennaway     OPENSSL_free(sc);
45774664626SKris Kennaway }
45874664626SKris Kennaway 
45974664626SKris Kennaway int ssl_set_peer_cert_type(SESS_CERT *sc, int type)
46074664626SKris Kennaway {
46174664626SKris Kennaway     sc->peer_cert_type = type;
46274664626SKris Kennaway     return (1);
46374664626SKris Kennaway }
46474664626SKris Kennaway 
46574664626SKris Kennaway int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
46674664626SKris Kennaway {
46774664626SKris Kennaway     X509 *x;
46874664626SKris Kennaway     int i;
46974664626SKris Kennaway     X509_STORE_CTX ctx;
47074664626SKris Kennaway 
47174664626SKris Kennaway     if ((sk == NULL) || (sk_X509_num(sk) == 0))
47274664626SKris Kennaway         return (0);
47374664626SKris Kennaway 
47474664626SKris Kennaway     x = sk_X509_value(sk, 0);
475*6f9291ceSJung-uk Kim     if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) {
4765c87c606SMark Murray         SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB);
4775c87c606SMark Murray         return (0);
4785c87c606SMark Murray     }
4793b4e3dcbSSimon L. B. Nielsen #if 0
48074664626SKris Kennaway     if (SSL_get_verify_depth(s) >= 0)
48174664626SKris Kennaway         X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
4823b4e3dcbSSimon L. B. Nielsen #endif
483f579bf8eSKris Kennaway     X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
4845c87c606SMark Murray 
485*6f9291ceSJung-uk Kim     /*
486*6f9291ceSJung-uk Kim      * We need to inherit the verify parameters. These can be determined by
487*6f9291ceSJung-uk Kim      * the context: if its a server it will verify SSL client certificates or
488*6f9291ceSJung-uk Kim      * vice versa.
489f579bf8eSKris Kennaway      */
490f579bf8eSKris Kennaway 
491*6f9291ceSJung-uk Kim     X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server");
492*6f9291ceSJung-uk Kim     /*
493*6f9291ceSJung-uk Kim      * Anything non-default in "param" should overwrite anything in the ctx.
4946a599222SSimon L. B. Nielsen      */
4956a599222SSimon L. B. Nielsen     X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
49674664626SKris Kennaway 
497a21b1b38SKris Kennaway     if (s->verify_callback)
498a21b1b38SKris Kennaway         X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
499a21b1b38SKris Kennaway 
50074664626SKris Kennaway     if (s->ctx->app_verify_callback != NULL)
5015c87c606SMark Murray #if 1                           /* new with OpenSSL 0.9.7 */
5025c87c606SMark Murray         i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
5035c87c606SMark Murray #else
50474664626SKris Kennaway         i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
5055c87c606SMark Murray #endif
506*6f9291ceSJung-uk Kim     else {
5075c87c606SMark Murray #ifndef OPENSSL_NO_X509_VERIFY
50874664626SKris Kennaway         i = X509_verify_cert(&ctx);
50974664626SKris Kennaway #else
51074664626SKris Kennaway         i = 0;
51174664626SKris Kennaway         ctx.error = X509_V_ERR_APPLICATION_VERIFICATION;
51274664626SKris Kennaway         SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK);
51374664626SKris Kennaway #endif
51474664626SKris Kennaway     }
51574664626SKris Kennaway 
51674664626SKris Kennaway     s->verify_result = ctx.error;
51774664626SKris Kennaway     X509_STORE_CTX_cleanup(&ctx);
51874664626SKris Kennaway 
51974664626SKris Kennaway     return (i);
52074664626SKris Kennaway }
52174664626SKris Kennaway 
522*6f9291ceSJung-uk Kim static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
523*6f9291ceSJung-uk Kim                                STACK_OF(X509_NAME) *name_list)
52474664626SKris Kennaway {
52574664626SKris Kennaway     if (*ca_list != NULL)
52674664626SKris Kennaway         sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
52774664626SKris Kennaway 
528ced566fdSJacques Vidrine     *ca_list = name_list;
52974664626SKris Kennaway }
53074664626SKris Kennaway 
53174664626SKris Kennaway STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
53274664626SKris Kennaway {
53374664626SKris Kennaway     int i;
53474664626SKris Kennaway     STACK_OF(X509_NAME) *ret;
53574664626SKris Kennaway     X509_NAME *name;
53674664626SKris Kennaway 
53774664626SKris Kennaway     ret = sk_X509_NAME_new_null();
538*6f9291ceSJung-uk Kim     for (i = 0; i < sk_X509_NAME_num(sk); i++) {
53974664626SKris Kennaway         name = X509_NAME_dup(sk_X509_NAME_value(sk, i));
540*6f9291ceSJung-uk Kim         if ((name == NULL) || !sk_X509_NAME_push(ret, name)) {
54174664626SKris Kennaway             sk_X509_NAME_pop_free(ret, X509_NAME_free);
54274664626SKris Kennaway             return (NULL);
54374664626SKris Kennaway         }
54474664626SKris Kennaway     }
54574664626SKris Kennaway     return (ret);
54674664626SKris Kennaway }
54774664626SKris Kennaway 
548ced566fdSJacques Vidrine void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
54974664626SKris Kennaway {
550ced566fdSJacques Vidrine     set_client_CA_list(&(s->client_CA), name_list);
55174664626SKris Kennaway }
55274664626SKris Kennaway 
553ced566fdSJacques Vidrine void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
55474664626SKris Kennaway {
555ced566fdSJacques Vidrine     set_client_CA_list(&(ctx->client_CA), name_list);
55674664626SKris Kennaway }
55774664626SKris Kennaway 
5583b4e3dcbSSimon L. B. Nielsen STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
55974664626SKris Kennaway {
56074664626SKris Kennaway     return (ctx->client_CA);
56174664626SKris Kennaway }
56274664626SKris Kennaway 
5633b4e3dcbSSimon L. B. Nielsen STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
56474664626SKris Kennaway {
565*6f9291ceSJung-uk Kim     if (s->type == SSL_ST_CONNECT) { /* we are in the client */
566*6f9291ceSJung-uk Kim         if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL))
56774664626SKris Kennaway             return (s->s3->tmp.ca_names);
56874664626SKris Kennaway         else
56974664626SKris Kennaway             return (NULL);
570*6f9291ceSJung-uk Kim     } else {
57174664626SKris Kennaway         if (s->client_CA != NULL)
57274664626SKris Kennaway             return (s->client_CA);
57374664626SKris Kennaway         else
57474664626SKris Kennaway             return (s->ctx->client_CA);
57574664626SKris Kennaway     }
57674664626SKris Kennaway }
57774664626SKris Kennaway 
57874664626SKris Kennaway static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x)
57974664626SKris Kennaway {
58074664626SKris Kennaway     X509_NAME *name;
58174664626SKris Kennaway 
582*6f9291ceSJung-uk Kim     if (x == NULL)
583*6f9291ceSJung-uk Kim         return (0);
58474664626SKris Kennaway     if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL))
58574664626SKris Kennaway         return (0);
58674664626SKris Kennaway 
58774664626SKris Kennaway     if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL)
58874664626SKris Kennaway         return (0);
58974664626SKris Kennaway 
590*6f9291ceSJung-uk Kim     if (!sk_X509_NAME_push(*sk, name)) {
59174664626SKris Kennaway         X509_NAME_free(name);
59274664626SKris Kennaway         return (0);
59374664626SKris Kennaway     }
59474664626SKris Kennaway     return (1);
59574664626SKris Kennaway }
59674664626SKris Kennaway 
59774664626SKris Kennaway int SSL_add_client_CA(SSL *ssl, X509 *x)
59874664626SKris Kennaway {
59974664626SKris Kennaway     return (add_client_CA(&(ssl->client_CA), x));
60074664626SKris Kennaway }
60174664626SKris Kennaway 
60274664626SKris Kennaway int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
60374664626SKris Kennaway {
60474664626SKris Kennaway     return (add_client_CA(&(ctx->client_CA), x));
60574664626SKris Kennaway }
60674664626SKris Kennaway 
607ddd58736SKris Kennaway static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
60874664626SKris Kennaway {
60974664626SKris Kennaway     return (X509_NAME_cmp(*a, *b));
61074664626SKris Kennaway }
61174664626SKris Kennaway 
6125c87c606SMark Murray #ifndef OPENSSL_NO_STDIO
613*6f9291ceSJung-uk Kim /**
61474664626SKris Kennaway  * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
61574664626SKris Kennaway  * it doesn't really have anything to do with clients (except that a common use
61674664626SKris Kennaway  * for a stack of CAs is to send it to the client). Actually, it doesn't have
61774664626SKris Kennaway  * much to do with CAs, either, since it will load any old cert.
61874664626SKris Kennaway  * \param file the file containing one or more certs.
61974664626SKris Kennaway  * \return a ::STACK containing the certs.
62074664626SKris Kennaway  */
62174664626SKris Kennaway STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
62274664626SKris Kennaway {
62374664626SKris Kennaway     BIO *in;
62474664626SKris Kennaway     X509 *x = NULL;
62574664626SKris Kennaway     X509_NAME *xn = NULL;
6263b4e3dcbSSimon L. B. Nielsen     STACK_OF(X509_NAME) *ret = NULL, *sk;
62774664626SKris Kennaway 
628f579bf8eSKris Kennaway     sk = sk_X509_NAME_new(xname_cmp);
62974664626SKris Kennaway 
63074664626SKris Kennaway     in = BIO_new(BIO_s_file_internal());
63174664626SKris Kennaway 
632*6f9291ceSJung-uk Kim     if ((sk == NULL) || (in == NULL)) {
63374664626SKris Kennaway         SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
63474664626SKris Kennaway         goto err;
63574664626SKris Kennaway     }
63674664626SKris Kennaway 
63774664626SKris Kennaway     if (!BIO_read_filename(in, file))
63874664626SKris Kennaway         goto err;
63974664626SKris Kennaway 
640*6f9291ceSJung-uk Kim     for (;;) {
64174664626SKris Kennaway         if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
64274664626SKris Kennaway             break;
643*6f9291ceSJung-uk Kim         if (ret == NULL) {
6443b4e3dcbSSimon L. B. Nielsen             ret = sk_X509_NAME_new_null();
645*6f9291ceSJung-uk Kim             if (ret == NULL) {
6463b4e3dcbSSimon L. B. Nielsen                 SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
6473b4e3dcbSSimon L. B. Nielsen                 goto err;
6483b4e3dcbSSimon L. B. Nielsen             }
6493b4e3dcbSSimon L. B. Nielsen         }
650*6f9291ceSJung-uk Kim         if ((xn = X509_get_subject_name(x)) == NULL)
651*6f9291ceSJung-uk Kim             goto err;
65274664626SKris Kennaway         /* check for duplicates */
65374664626SKris Kennaway         xn = X509_NAME_dup(xn);
654*6f9291ceSJung-uk Kim         if (xn == NULL)
655*6f9291ceSJung-uk Kim             goto err;
65674664626SKris Kennaway         if (sk_X509_NAME_find(sk, xn) >= 0)
65774664626SKris Kennaway             X509_NAME_free(xn);
658*6f9291ceSJung-uk Kim         else {
65974664626SKris Kennaway             sk_X509_NAME_push(sk, xn);
66074664626SKris Kennaway             sk_X509_NAME_push(ret, xn);
66174664626SKris Kennaway         }
66274664626SKris Kennaway     }
66374664626SKris Kennaway 
664*6f9291ceSJung-uk Kim     if (0) {
66574664626SKris Kennaway  err:
666*6f9291ceSJung-uk Kim         if (ret != NULL)
667*6f9291ceSJung-uk Kim             sk_X509_NAME_pop_free(ret, X509_NAME_free);
66874664626SKris Kennaway         ret = NULL;
66974664626SKris Kennaway     }
670*6f9291ceSJung-uk Kim     if (sk != NULL)
671*6f9291ceSJung-uk Kim         sk_X509_NAME_free(sk);
672*6f9291ceSJung-uk Kim     if (in != NULL)
673*6f9291ceSJung-uk Kim         BIO_free(in);
674*6f9291ceSJung-uk Kim     if (x != NULL)
675*6f9291ceSJung-uk Kim         X509_free(x);
6763b4e3dcbSSimon L. B. Nielsen     if (ret != NULL)
6773b4e3dcbSSimon L. B. Nielsen         ERR_clear_error();
67874664626SKris Kennaway     return (ret);
67974664626SKris Kennaway }
68074664626SKris Kennaway #endif
68174664626SKris Kennaway 
682*6f9291ceSJung-uk Kim /**
68374664626SKris Kennaway  * Add a file of certs to a stack.
68474664626SKris Kennaway  * \param stack the stack to add to.
68574664626SKris Kennaway  * \param file the file to add from. All certs in this file that are not
68674664626SKris Kennaway  * already in the stack will be added.
68774664626SKris Kennaway  * \return 1 for success, 0 for failure. Note that in the case of failure some
68874664626SKris Kennaway  * certs may have been added to \c stack.
68974664626SKris Kennaway  */
69074664626SKris Kennaway 
69174664626SKris Kennaway int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
69274664626SKris Kennaway                                         const char *file)
69374664626SKris Kennaway {
69474664626SKris Kennaway     BIO *in;
69574664626SKris Kennaway     X509 *x = NULL;
69674664626SKris Kennaway     X509_NAME *xn = NULL;
69774664626SKris Kennaway     int ret = 1;
698ddd58736SKris Kennaway     int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b);
69974664626SKris Kennaway 
700f579bf8eSKris Kennaway     oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
70174664626SKris Kennaway 
70274664626SKris Kennaway     in = BIO_new(BIO_s_file_internal());
70374664626SKris Kennaway 
704*6f9291ceSJung-uk Kim     if (in == NULL) {
705*6f9291ceSJung-uk Kim         SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,
706*6f9291ceSJung-uk Kim                ERR_R_MALLOC_FAILURE);
70774664626SKris Kennaway         goto err;
70874664626SKris Kennaway     }
70974664626SKris Kennaway 
71074664626SKris Kennaway     if (!BIO_read_filename(in, file))
71174664626SKris Kennaway         goto err;
71274664626SKris Kennaway 
713*6f9291ceSJung-uk Kim     for (;;) {
71474664626SKris Kennaway         if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
71574664626SKris Kennaway             break;
716*6f9291ceSJung-uk Kim         if ((xn = X509_get_subject_name(x)) == NULL)
717*6f9291ceSJung-uk Kim             goto err;
71874664626SKris Kennaway         xn = X509_NAME_dup(xn);
719*6f9291ceSJung-uk Kim         if (xn == NULL)
720*6f9291ceSJung-uk Kim             goto err;
72174664626SKris Kennaway         if (sk_X509_NAME_find(stack, xn) >= 0)
72274664626SKris Kennaway             X509_NAME_free(xn);
72374664626SKris Kennaway         else
72474664626SKris Kennaway             sk_X509_NAME_push(stack, xn);
72574664626SKris Kennaway     }
72674664626SKris Kennaway 
727a3ddd25aSSimon L. B. Nielsen     ERR_clear_error();
728a3ddd25aSSimon L. B. Nielsen 
729*6f9291ceSJung-uk Kim     if (0) {
73074664626SKris Kennaway  err:
73174664626SKris Kennaway         ret = 0;
73274664626SKris Kennaway     }
73374664626SKris Kennaway     if (in != NULL)
73474664626SKris Kennaway         BIO_free(in);
73574664626SKris Kennaway     if (x != NULL)
73674664626SKris Kennaway         X509_free(x);
73774664626SKris Kennaway 
738db522d3aSSimon L. B. Nielsen     (void)sk_X509_NAME_set_cmp_func(stack, oldcmp);
73974664626SKris Kennaway 
74074664626SKris Kennaway     return ret;
74174664626SKris Kennaway }
74274664626SKris Kennaway 
743*6f9291ceSJung-uk Kim /**
74474664626SKris Kennaway  * Add a directory of certs to a stack.
74574664626SKris Kennaway  * \param stack the stack to append to.
74674664626SKris Kennaway  * \param dir the directory to append from. All files in this directory will be
74774664626SKris Kennaway  * examined as potential certs. Any that are acceptable to
74874664626SKris Kennaway  * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
74974664626SKris Kennaway  * included.
75074664626SKris Kennaway  * \return 1 for success, 0 for failure. Note that in the case of failure some
75174664626SKris Kennaway  * certs may have been added to \c stack.
75274664626SKris Kennaway  */
75374664626SKris Kennaway 
75474664626SKris Kennaway int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
75574664626SKris Kennaway                                        const char *dir)
75674664626SKris Kennaway {
7573b4e3dcbSSimon L. B. Nielsen     OPENSSL_DIR_CTX *d = NULL;
7583b4e3dcbSSimon L. B. Nielsen     const char *filename;
75974664626SKris Kennaway     int ret = 0;
76074664626SKris Kennaway 
76174664626SKris Kennaway     CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
76274664626SKris Kennaway 
76374664626SKris Kennaway     /* Note that a side effect is that the CAs will be sorted by name */
76474664626SKris Kennaway 
765*6f9291ceSJung-uk Kim     while ((filename = OPENSSL_DIR_read(&d, dir))) {
76674664626SKris Kennaway         char buf[1024];
767ddd58736SKris Kennaway         int r;
76874664626SKris Kennaway 
769*6f9291ceSJung-uk Kim         if (strlen(dir) + strlen(filename) + 2 > sizeof buf) {
770*6f9291ceSJung-uk Kim             SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,
771*6f9291ceSJung-uk Kim                    SSL_R_PATH_TOO_LONG);
77274664626SKris Kennaway             goto err;
77374664626SKris Kennaway         }
7743b4e3dcbSSimon L. B. Nielsen #ifdef OPENSSL_SYS_VMS
7753b4e3dcbSSimon L. B. Nielsen         r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename);
7763b4e3dcbSSimon L. B. Nielsen #else
7773b4e3dcbSSimon L. B. Nielsen         r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
7783b4e3dcbSSimon L. B. Nielsen #endif
7793b4e3dcbSSimon L. B. Nielsen         if (r <= 0 || r >= (int)sizeof(buf))
780ddd58736SKris Kennaway             goto err;
78174664626SKris Kennaway         if (!SSL_add_file_cert_subjects_to_stack(stack, buf))
78274664626SKris Kennaway             goto err;
78374664626SKris Kennaway     }
78474664626SKris Kennaway 
785*6f9291ceSJung-uk Kim     if (errno) {
7865c87c606SMark Murray         SYSerr(SYS_F_OPENDIR, get_last_sys_error());
7873b4e3dcbSSimon L. B. Nielsen         ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
7885c87c606SMark Murray         SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
7895c87c606SMark Murray         goto err;
7905c87c606SMark Murray     }
7915c87c606SMark Murray 
7925c87c606SMark Murray     ret = 1;
7935c87c606SMark Murray 
7945c87c606SMark Murray  err:
795*6f9291ceSJung-uk Kim     if (d)
796*6f9291ceSJung-uk Kim         OPENSSL_DIR_end(&d);
7975c87c606SMark Murray     CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
7985c87c606SMark Murray     return ret;
7995c87c606SMark Murray }
800