ssl_cert.c revision 296341
1/*
2 * ! \file ssl/ssl_cert.c
3 */
4/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5 * All rights reserved.
6 *
7 * This package is an SSL implementation written
8 * by Eric Young (eay@cryptsoft.com).
9 * The implementation was written so as to conform with Netscapes SSL.
10 *
11 * This library is free for commercial and non-commercial use as long as
12 * the following conditions are aheared to.  The following conditions
13 * apply to all code found in this distribution, be it the RC4, RSA,
14 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
15 * included with this distribution is covered by the same copyright terms
16 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
17 *
18 * Copyright remains Eric Young's, and as such any Copyright notices in
19 * the code are not to be removed.
20 * If this package is used in a product, Eric Young should be given attribution
21 * as the author of the parts of the library used.
22 * This can be in the form of a textual message at program startup or
23 * in documentation (online or textual) provided with the package.
24 *
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 * 1. Redistributions of source code must retain the copyright
29 *    notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 *    notice, this list of conditions and the following disclaimer in the
32 *    documentation and/or other materials provided with the distribution.
33 * 3. All advertising materials mentioning features or use of this software
34 *    must display the following acknowledgement:
35 *    "This product includes cryptographic software written by
36 *     Eric Young (eay@cryptsoft.com)"
37 *    The word 'cryptographic' can be left out if the rouines from the library
38 *    being used are not cryptographic related :-).
39 * 4. If you include any Windows specific code (or a derivative thereof) from
40 *    the apps directory (application code) you must include an acknowledgement:
41 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
42 *
43 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
47 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 *
55 * The licence and distribution terms for any publically available version or
56 * derivative of this code cannot be changed.  i.e. this code cannot simply be
57 * copied and put under another distribution licence
58 * [including the GNU Public Licence.]
59 */
60/* ====================================================================
61 * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
62 *
63 * Redistribution and use in source and binary forms, with or without
64 * modification, are permitted provided that the following conditions
65 * are met:
66 *
67 * 1. Redistributions of source code must retain the above copyright
68 *    notice, this list of conditions and the following disclaimer.
69 *
70 * 2. Redistributions in binary form must reproduce the above copyright
71 *    notice, this list of conditions and the following disclaimer in
72 *    the documentation and/or other materials provided with the
73 *    distribution.
74 *
75 * 3. All advertising materials mentioning features or use of this
76 *    software must display the following acknowledgment:
77 *    "This product includes software developed by the OpenSSL Project
78 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
79 *
80 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
81 *    endorse or promote products derived from this software without
82 *    prior written permission. For written permission, please contact
83 *    openssl-core@openssl.org.
84 *
85 * 5. Products derived from this software may not be called "OpenSSL"
86 *    nor may "OpenSSL" appear in their names without prior written
87 *    permission of the OpenSSL Project.
88 *
89 * 6. Redistributions of any form whatsoever must retain the following
90 *    acknowledgment:
91 *    "This product includes software developed by the OpenSSL Project
92 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
93 *
94 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
95 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
96 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
97 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
98 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
99 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
100 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
102 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
103 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
104 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
105 * OF THE POSSIBILITY OF SUCH DAMAGE.
106 * ====================================================================
107 *
108 * This product includes cryptographic software written by Eric Young
109 * (eay@cryptsoft.com).  This product includes software written by Tim
110 * Hudson (tjh@cryptsoft.com).
111 *
112 */
113/* ====================================================================
114 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
115 * ECC cipher suite support in OpenSSL originally developed by
116 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
117 */
118
119#include <stdio.h>
120
121#include "e_os.h"
122#ifndef NO_SYS_TYPES_H
123# include <sys/types.h>
124#endif
125
126#include "o_dir.h"
127#include <openssl/objects.h>
128#include <openssl/bio.h>
129#include <openssl/pem.h>
130#include <openssl/x509v3.h>
131#ifndef OPENSSL_NO_DH
132# include <openssl/dh.h>
133#endif
134#include <openssl/bn.h>
135#include "ssl_locl.h"
136
137int SSL_get_ex_data_X509_STORE_CTX_idx(void)
138{
139    static volatile int ssl_x509_store_ctx_idx = -1;
140    int got_write_lock = 0;
141
142    CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
143
144    if (ssl_x509_store_ctx_idx < 0) {
145        CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
146        CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
147        got_write_lock = 1;
148
149        if (ssl_x509_store_ctx_idx < 0) {
150            ssl_x509_store_ctx_idx =
151                X509_STORE_CTX_get_ex_new_index(0, "SSL for verify callback",
152                                                NULL, NULL, NULL);
153        }
154    }
155
156    if (got_write_lock)
157        CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
158    else
159        CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
160
161    return ssl_x509_store_ctx_idx;
162}
163
164static void ssl_cert_set_default_md(CERT *cert)
165{
166    /* Set digest values to defaults */
167#ifndef OPENSSL_NO_DSA
168    cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
169#endif
170#ifndef OPENSSL_NO_RSA
171    cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
172    cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
173#endif
174#ifndef OPENSSL_NO_ECDSA
175    cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
176#endif
177}
178
179CERT *ssl_cert_new(void)
180{
181    CERT *ret;
182
183    ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
184    if (ret == NULL) {
185        SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE);
186        return (NULL);
187    }
188    memset(ret, 0, sizeof(CERT));
189
190    ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]);
191    ret->references = 1;
192    ssl_cert_set_default_md(ret);
193    return (ret);
194}
195
196CERT *ssl_cert_dup(CERT *cert)
197{
198    CERT *ret;
199    int i;
200
201    ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
202    if (ret == NULL) {
203        SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
204        return (NULL);
205    }
206
207    memset(ret, 0, sizeof(CERT));
208
209    ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
210    /*
211     * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that
212     * more readable
213     */
214
215    ret->valid = cert->valid;
216    ret->mask_k = cert->mask_k;
217    ret->mask_a = cert->mask_a;
218    ret->export_mask_k = cert->export_mask_k;
219    ret->export_mask_a = cert->export_mask_a;
220
221#ifndef OPENSSL_NO_RSA
222    if (cert->rsa_tmp != NULL) {
223        RSA_up_ref(cert->rsa_tmp);
224        ret->rsa_tmp = cert->rsa_tmp;
225    }
226    ret->rsa_tmp_cb = cert->rsa_tmp_cb;
227#endif
228
229#ifndef OPENSSL_NO_DH
230    if (cert->dh_tmp != NULL) {
231        ret->dh_tmp = DHparams_dup(cert->dh_tmp);
232        if (ret->dh_tmp == NULL) {
233            SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB);
234            goto err;
235        }
236        if (cert->dh_tmp->priv_key) {
237            BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
238            if (!b) {
239                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
240                goto err;
241            }
242            ret->dh_tmp->priv_key = b;
243        }
244        if (cert->dh_tmp->pub_key) {
245            BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
246            if (!b) {
247                SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB);
248                goto err;
249            }
250            ret->dh_tmp->pub_key = b;
251        }
252    }
253    ret->dh_tmp_cb = cert->dh_tmp_cb;
254#endif
255
256#ifndef OPENSSL_NO_ECDH
257    if (cert->ecdh_tmp) {
258        ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp);
259        if (ret->ecdh_tmp == NULL) {
260            SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB);
261            goto err;
262        }
263    }
264    ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
265#endif
266
267    for (i = 0; i < SSL_PKEY_NUM; i++) {
268        if (cert->pkeys[i].x509 != NULL) {
269            ret->pkeys[i].x509 = cert->pkeys[i].x509;
270            CRYPTO_add(&ret->pkeys[i].x509->references, 1, CRYPTO_LOCK_X509);
271        }
272
273        if (cert->pkeys[i].privatekey != NULL) {
274            ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
275            CRYPTO_add(&ret->pkeys[i].privatekey->references, 1,
276                       CRYPTO_LOCK_EVP_PKEY);
277        }
278    }
279
280    /*
281     * ret->extra_certs *should* exist, but currently the own certificate
282     * chain is held inside SSL_CTX
283     */
284
285    ret->references = 1;
286    /*
287     * Set digests to defaults. NB: we don't copy existing values as they
288     * will be set during handshake.
289     */
290    ssl_cert_set_default_md(ret);
291
292    return (ret);
293
294#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
295 err:
296#endif
297#ifndef OPENSSL_NO_RSA
298    if (ret->rsa_tmp != NULL)
299        RSA_free(ret->rsa_tmp);
300#endif
301#ifndef OPENSSL_NO_DH
302    if (ret->dh_tmp != NULL)
303        DH_free(ret->dh_tmp);
304#endif
305#ifndef OPENSSL_NO_ECDH
306    if (ret->ecdh_tmp != NULL)
307        EC_KEY_free(ret->ecdh_tmp);
308#endif
309
310    for (i = 0; i < SSL_PKEY_NUM; i++) {
311        if (ret->pkeys[i].x509 != NULL)
312            X509_free(ret->pkeys[i].x509);
313        if (ret->pkeys[i].privatekey != NULL)
314            EVP_PKEY_free(ret->pkeys[i].privatekey);
315    }
316
317    return NULL;
318}
319
320void ssl_cert_free(CERT *c)
321{
322    int i;
323
324    if (c == NULL)
325        return;
326
327    i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT);
328#ifdef REF_PRINT
329    REF_PRINT("CERT", c);
330#endif
331    if (i > 0)
332        return;
333#ifdef REF_CHECK
334    if (i < 0) {
335        fprintf(stderr, "ssl_cert_free, bad reference count\n");
336        abort();                /* ok */
337    }
338#endif
339
340#ifndef OPENSSL_NO_RSA
341    if (c->rsa_tmp)
342        RSA_free(c->rsa_tmp);
343#endif
344#ifndef OPENSSL_NO_DH
345    if (c->dh_tmp)
346        DH_free(c->dh_tmp);
347#endif
348#ifndef OPENSSL_NO_ECDH
349    if (c->ecdh_tmp)
350        EC_KEY_free(c->ecdh_tmp);
351#endif
352
353    for (i = 0; i < SSL_PKEY_NUM; i++) {
354        if (c->pkeys[i].x509 != NULL)
355            X509_free(c->pkeys[i].x509);
356        if (c->pkeys[i].privatekey != NULL)
357            EVP_PKEY_free(c->pkeys[i].privatekey);
358#if 0
359        if (c->pkeys[i].publickey != NULL)
360            EVP_PKEY_free(c->pkeys[i].publickey);
361#endif
362    }
363    OPENSSL_free(c);
364}
365
366int ssl_cert_inst(CERT **o)
367{
368    /*
369     * Create a CERT if there isn't already one (which cannot really happen,
370     * as it is initially created in SSL_CTX_new; but the earlier code
371     * usually allows for that one being non-existant, so we follow that
372     * behaviour, as it might turn out that there actually is a reason for it
373     * -- but I'm not sure that *all* of the existing code could cope with
374     * s->cert being NULL, otherwise we could do without the initialization
375     * in SSL_CTX_new).
376     */
377
378    if (o == NULL) {
379        SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER);
380        return (0);
381    }
382    if (*o == NULL) {
383        if ((*o = ssl_cert_new()) == NULL) {
384            SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE);
385            return (0);
386        }
387    }
388    return (1);
389}
390
391SESS_CERT *ssl_sess_cert_new(void)
392{
393    SESS_CERT *ret;
394
395    ret = OPENSSL_malloc(sizeof *ret);
396    if (ret == NULL) {
397        SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE);
398        return NULL;
399    }
400
401    memset(ret, 0, sizeof *ret);
402    ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]);
403    ret->references = 1;
404
405    return ret;
406}
407
408void ssl_sess_cert_free(SESS_CERT *sc)
409{
410    int i;
411
412    if (sc == NULL)
413        return;
414
415    i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT);
416#ifdef REF_PRINT
417    REF_PRINT("SESS_CERT", sc);
418#endif
419    if (i > 0)
420        return;
421#ifdef REF_CHECK
422    if (i < 0) {
423        fprintf(stderr, "ssl_sess_cert_free, bad reference count\n");
424        abort();                /* ok */
425    }
426#endif
427
428    /* i == 0 */
429    if (sc->cert_chain != NULL)
430        sk_X509_pop_free(sc->cert_chain, X509_free);
431    for (i = 0; i < SSL_PKEY_NUM; i++) {
432        if (sc->peer_pkeys[i].x509 != NULL)
433            X509_free(sc->peer_pkeys[i].x509);
434#if 0                           /* We don't have the peer's private key.
435                                 * These lines are just * here as a reminder
436                                 * that we're still using a
437                                 * not-quite-appropriate * data structure. */
438        if (sc->peer_pkeys[i].privatekey != NULL)
439            EVP_PKEY_free(sc->peer_pkeys[i].privatekey);
440#endif
441    }
442
443#ifndef OPENSSL_NO_RSA
444    if (sc->peer_rsa_tmp != NULL)
445        RSA_free(sc->peer_rsa_tmp);
446#endif
447#ifndef OPENSSL_NO_DH
448    if (sc->peer_dh_tmp != NULL)
449        DH_free(sc->peer_dh_tmp);
450#endif
451#ifndef OPENSSL_NO_ECDH
452    if (sc->peer_ecdh_tmp != NULL)
453        EC_KEY_free(sc->peer_ecdh_tmp);
454#endif
455
456    OPENSSL_free(sc);
457}
458
459int ssl_set_peer_cert_type(SESS_CERT *sc, int type)
460{
461    sc->peer_cert_type = type;
462    return (1);
463}
464
465int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk)
466{
467    X509 *x;
468    int i;
469    X509_STORE_CTX ctx;
470
471    if ((sk == NULL) || (sk_X509_num(sk) == 0))
472        return (0);
473
474    x = sk_X509_value(sk, 0);
475    if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) {
476        SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB);
477        return (0);
478    }
479#if 0
480    if (SSL_get_verify_depth(s) >= 0)
481        X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s));
482#endif
483    X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
484
485    /*
486     * We need to inherit the verify parameters. These can be determined by
487     * the context: if its a server it will verify SSL client certificates or
488     * vice versa.
489     */
490
491    X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server");
492    /*
493     * Anything non-default in "param" should overwrite anything in the ctx.
494     */
495    X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
496
497    if (s->verify_callback)
498        X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
499
500    if (s->ctx->app_verify_callback != NULL)
501#if 1                           /* new with OpenSSL 0.9.7 */
502        i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
503#else
504        i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
505#endif
506    else {
507#ifndef OPENSSL_NO_X509_VERIFY
508        i = X509_verify_cert(&ctx);
509#else
510        i = 0;
511        ctx.error = X509_V_ERR_APPLICATION_VERIFICATION;
512        SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK);
513#endif
514    }
515
516    s->verify_result = ctx.error;
517    X509_STORE_CTX_cleanup(&ctx);
518
519    return (i);
520}
521
522static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
523                               STACK_OF(X509_NAME) *name_list)
524{
525    if (*ca_list != NULL)
526        sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
527
528    *ca_list = name_list;
529}
530
531STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk)
532{
533    int i;
534    STACK_OF(X509_NAME) *ret;
535    X509_NAME *name;
536
537    ret = sk_X509_NAME_new_null();
538    for (i = 0; i < sk_X509_NAME_num(sk); i++) {
539        name = X509_NAME_dup(sk_X509_NAME_value(sk, i));
540        if ((name == NULL) || !sk_X509_NAME_push(ret, name)) {
541            sk_X509_NAME_pop_free(ret, X509_NAME_free);
542            return (NULL);
543        }
544    }
545    return (ret);
546}
547
548void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
549{
550    set_client_CA_list(&(s->client_CA), name_list);
551}
552
553void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
554{
555    set_client_CA_list(&(ctx->client_CA), name_list);
556}
557
558STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
559{
560    return (ctx->client_CA);
561}
562
563STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s)
564{
565    if (s->type == SSL_ST_CONNECT) { /* we are in the client */
566        if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL))
567            return (s->s3->tmp.ca_names);
568        else
569            return (NULL);
570    } else {
571        if (s->client_CA != NULL)
572            return (s->client_CA);
573        else
574            return (s->ctx->client_CA);
575    }
576}
577
578static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x)
579{
580    X509_NAME *name;
581
582    if (x == NULL)
583        return (0);
584    if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL))
585        return (0);
586
587    if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL)
588        return (0);
589
590    if (!sk_X509_NAME_push(*sk, name)) {
591        X509_NAME_free(name);
592        return (0);
593    }
594    return (1);
595}
596
597int SSL_add_client_CA(SSL *ssl, X509 *x)
598{
599    return (add_client_CA(&(ssl->client_CA), x));
600}
601
602int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
603{
604    return (add_client_CA(&(ctx->client_CA), x));
605}
606
607static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
608{
609    return (X509_NAME_cmp(*a, *b));
610}
611
612#ifndef OPENSSL_NO_STDIO
613/**
614 * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
615 * it doesn't really have anything to do with clients (except that a common use
616 * for a stack of CAs is to send it to the client). Actually, it doesn't have
617 * much to do with CAs, either, since it will load any old cert.
618 * \param file the file containing one or more certs.
619 * \return a ::STACK containing the certs.
620 */
621STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file)
622{
623    BIO *in;
624    X509 *x = NULL;
625    X509_NAME *xn = NULL;
626    STACK_OF(X509_NAME) *ret = NULL, *sk;
627
628    sk = sk_X509_NAME_new(xname_cmp);
629
630    in = BIO_new(BIO_s_file_internal());
631
632    if ((sk == NULL) || (in == NULL)) {
633        SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
634        goto err;
635    }
636
637    if (!BIO_read_filename(in, file))
638        goto err;
639
640    for (;;) {
641        if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
642            break;
643        if (ret == NULL) {
644            ret = sk_X509_NAME_new_null();
645            if (ret == NULL) {
646                SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE);
647                goto err;
648            }
649        }
650        if ((xn = X509_get_subject_name(x)) == NULL)
651            goto err;
652        /* check for duplicates */
653        xn = X509_NAME_dup(xn);
654        if (xn == NULL)
655            goto err;
656        if (sk_X509_NAME_find(sk, xn) >= 0)
657            X509_NAME_free(xn);
658        else {
659            sk_X509_NAME_push(sk, xn);
660            sk_X509_NAME_push(ret, xn);
661        }
662    }
663
664    if (0) {
665 err:
666        if (ret != NULL)
667            sk_X509_NAME_pop_free(ret, X509_NAME_free);
668        ret = NULL;
669    }
670    if (sk != NULL)
671        sk_X509_NAME_free(sk);
672    if (in != NULL)
673        BIO_free(in);
674    if (x != NULL)
675        X509_free(x);
676    if (ret != NULL)
677        ERR_clear_error();
678    return (ret);
679}
680#endif
681
682/**
683 * Add a file of certs to a stack.
684 * \param stack the stack to add to.
685 * \param file the file to add from. All certs in this file that are not
686 * already in the stack will be added.
687 * \return 1 for success, 0 for failure. Note that in the case of failure some
688 * certs may have been added to \c stack.
689 */
690
691int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
692                                        const char *file)
693{
694    BIO *in;
695    X509 *x = NULL;
696    X509_NAME *xn = NULL;
697    int ret = 1;
698    int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b);
699
700    oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
701
702    in = BIO_new(BIO_s_file_internal());
703
704    if (in == NULL) {
705        SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK,
706               ERR_R_MALLOC_FAILURE);
707        goto err;
708    }
709
710    if (!BIO_read_filename(in, file))
711        goto err;
712
713    for (;;) {
714        if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
715            break;
716        if ((xn = X509_get_subject_name(x)) == NULL)
717            goto err;
718        xn = X509_NAME_dup(xn);
719        if (xn == NULL)
720            goto err;
721        if (sk_X509_NAME_find(stack, xn) >= 0)
722            X509_NAME_free(xn);
723        else
724            sk_X509_NAME_push(stack, xn);
725    }
726
727    ERR_clear_error();
728
729    if (0) {
730 err:
731        ret = 0;
732    }
733    if (in != NULL)
734        BIO_free(in);
735    if (x != NULL)
736        X509_free(x);
737
738    (void)sk_X509_NAME_set_cmp_func(stack, oldcmp);
739
740    return ret;
741}
742
743/**
744 * Add a directory of certs to a stack.
745 * \param stack the stack to append to.
746 * \param dir the directory to append from. All files in this directory will be
747 * examined as potential certs. Any that are acceptable to
748 * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be
749 * included.
750 * \return 1 for success, 0 for failure. Note that in the case of failure some
751 * certs may have been added to \c stack.
752 */
753
754int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
755                                       const char *dir)
756{
757    OPENSSL_DIR_CTX *d = NULL;
758    const char *filename;
759    int ret = 0;
760
761    CRYPTO_w_lock(CRYPTO_LOCK_READDIR);
762
763    /* Note that a side effect is that the CAs will be sorted by name */
764
765    while ((filename = OPENSSL_DIR_read(&d, dir))) {
766        char buf[1024];
767        int r;
768
769        if (strlen(dir) + strlen(filename) + 2 > sizeof buf) {
770            SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK,
771                   SSL_R_PATH_TOO_LONG);
772            goto err;
773        }
774#ifdef OPENSSL_SYS_VMS
775        r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename);
776#else
777        r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
778#endif
779        if (r <= 0 || r >= (int)sizeof(buf))
780            goto err;
781        if (!SSL_add_file_cert_subjects_to_stack(stack, buf))
782            goto err;
783    }
784
785    if (errno) {
786        SYSerr(SYS_F_OPENDIR, get_last_sys_error());
787        ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
788        SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB);
789        goto err;
790    }
791
792    ret = 1;
793
794 err:
795    if (d)
796        OPENSSL_DIR_end(&d);
797    CRYPTO_w_unlock(CRYPTO_LOCK_READDIR);
798    return ret;
799}
800