Coverage Report

Created: 2022-08-24 06:31

/src/libressl/ssl/ssl_cert.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: ssl_cert.c,v 1.103 2022/07/07 13:04:39 tb Exp $ */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
/* ====================================================================
59
 * Copyright (c) 1998-2007 The OpenSSL Project.  All rights reserved.
60
 *
61
 * Redistribution and use in source and binary forms, with or without
62
 * modification, are permitted provided that the following conditions
63
 * are met:
64
 *
65
 * 1. Redistributions of source code must retain the above copyright
66
 *    notice, this list of conditions and the following disclaimer.
67
 *
68
 * 2. Redistributions in binary form must reproduce the above copyright
69
 *    notice, this list of conditions and the following disclaimer in
70
 *    the documentation and/or other materials provided with the
71
 *    distribution.
72
 *
73
 * 3. All advertising materials mentioning features or use of this
74
 *    software must display the following acknowledgment:
75
 *    "This product includes software developed by the OpenSSL Project
76
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77
 *
78
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79
 *    endorse or promote products derived from this software without
80
 *    prior written permission. For written permission, please contact
81
 *    openssl-core@openssl.org.
82
 *
83
 * 5. Products derived from this software may not be called "OpenSSL"
84
 *    nor may "OpenSSL" appear in their names without prior written
85
 *    permission of the OpenSSL Project.
86
 *
87
 * 6. Redistributions of any form whatsoever must retain the following
88
 *    acknowledgment:
89
 *    "This product includes software developed by the OpenSSL Project
90
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91
 *
92
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
96
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103
 * OF THE POSSIBILITY OF SUCH DAMAGE.
104
 * ====================================================================
105
 *
106
 * This product includes cryptographic software written by Eric Young
107
 * (eay@cryptsoft.com).  This product includes software written by Tim
108
 * Hudson (tjh@cryptsoft.com).
109
 *
110
 */
111
/* ====================================================================
112
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
113
 * ECC cipher suite support in OpenSSL originally developed by
114
 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
115
 */
116
117
#include <sys/types.h>
118
119
#include <dirent.h>
120
#include <stdio.h>
121
#include <unistd.h>
122
123
#include <openssl/bio.h>
124
#include <openssl/bn.h>
125
#include <openssl/dh.h>
126
#include <openssl/objects.h>
127
#include <openssl/opensslconf.h>
128
#include <openssl/pem.h>
129
#include <openssl/x509v3.h>
130
131
#include "ssl_locl.h"
132
133
int
134
SSL_get_ex_data_X509_STORE_CTX_idx(void)
135
0
{
136
0
  static volatile int ssl_x509_store_ctx_idx = -1;
137
0
  int got_write_lock = 0;
138
139
0
  CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
140
141
0
  if (ssl_x509_store_ctx_idx < 0) {
142
0
    CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
143
0
    CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
144
0
    got_write_lock = 1;
145
146
0
    if (ssl_x509_store_ctx_idx < 0) {
147
0
      ssl_x509_store_ctx_idx =
148
0
          X509_STORE_CTX_get_ex_new_index(
149
0
        0, "SSL for verify callback", NULL, NULL, NULL);
150
0
    }
151
0
  }
152
153
0
  if (got_write_lock)
154
0
    CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
155
0
  else
156
0
    CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
157
158
0
  return ssl_x509_store_ctx_idx;
159
0
}
160
161
SSL_CERT *
162
ssl_cert_new(void)
163
0
{
164
0
  SSL_CERT *ret;
165
166
0
  ret = calloc(1, sizeof(SSL_CERT));
167
0
  if (ret == NULL) {
168
0
    SSLerrorx(ERR_R_MALLOC_FAILURE);
169
0
    return (NULL);
170
0
  }
171
0
  ret->key = &(ret->pkeys[SSL_PKEY_RSA]);
172
0
  ret->references = 1;
173
0
  ret->security_cb = ssl_security_default_cb;
174
0
  ret->security_level = OPENSSL_TLS_SECURITY_LEVEL;
175
0
  ret->security_ex_data = NULL;
176
0
  return (ret);
177
0
}
178
179
SSL_CERT *
180
ssl_cert_dup(SSL_CERT *cert)
181
0
{
182
0
  SSL_CERT *ret;
183
0
  int i;
184
185
0
  ret = calloc(1, sizeof(SSL_CERT));
186
0
  if (ret == NULL) {
187
0
    SSLerrorx(ERR_R_MALLOC_FAILURE);
188
0
    return (NULL);
189
0
  }
190
191
  /*
192
   * same as ret->key = ret->pkeys + (cert->key - cert->pkeys),
193
   * if you find that more readable
194
   */
195
0
  ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
196
197
0
  ret->valid = cert->valid;
198
0
  ret->mask_k = cert->mask_k;
199
0
  ret->mask_a = cert->mask_a;
200
201
0
  if (cert->dhe_params != NULL) {
202
0
    ret->dhe_params = DHparams_dup(cert->dhe_params);
203
0
    if (ret->dhe_params == NULL) {
204
0
      SSLerrorx(ERR_R_DH_LIB);
205
0
      goto err;
206
0
    }
207
0
  }
208
0
  ret->dhe_params_cb = cert->dhe_params_cb;
209
0
  ret->dhe_params_auto = cert->dhe_params_auto;
210
211
0
  for (i = 0; i < SSL_PKEY_NUM; i++) {
212
0
    if (cert->pkeys[i].x509 != NULL) {
213
0
      ret->pkeys[i].x509 = cert->pkeys[i].x509;
214
0
      X509_up_ref(ret->pkeys[i].x509);
215
0
    }
216
217
0
    if (cert->pkeys[i].privatekey != NULL) {
218
0
      ret->pkeys[i].privatekey = cert->pkeys[i].privatekey;
219
0
      EVP_PKEY_up_ref(ret->pkeys[i].privatekey);
220
0
      switch (i) {
221
        /*
222
         * If there was anything special to do for
223
         * certain types of keys, we'd do it here.
224
         * (Nothing at the moment, I think.)
225
         */
226
227
0
      case SSL_PKEY_RSA:
228
        /* We have an RSA key. */
229
0
        break;
230
231
0
      case SSL_PKEY_ECC:
232
        /* We have an ECC key */
233
0
        break;
234
235
0
      case SSL_PKEY_GOST01:
236
        /* We have a GOST key */
237
0
        break;
238
239
0
      default:
240
        /* Can't happen. */
241
0
        SSLerrorx(SSL_R_LIBRARY_BUG);
242
0
      }
243
0
    }
244
245
0
    if (cert->pkeys[i].chain != NULL) {
246
0
      if ((ret->pkeys[i].chain =
247
0
          X509_chain_up_ref(cert->pkeys[i].chain)) == NULL)
248
0
        goto err;
249
0
    }
250
0
  }
251
252
0
  ret->security_cb = cert->security_cb;
253
0
  ret->security_level = cert->security_level;
254
0
  ret->security_ex_data = cert->security_ex_data;
255
256
  /*
257
   * ret->extra_certs *should* exist, but currently the own certificate
258
   * chain is held inside SSL_CTX
259
   */
260
261
0
  ret->references = 1;
262
263
0
  return (ret);
264
265
0
 err:
266
0
  DH_free(ret->dhe_params);
267
268
0
  for (i = 0; i < SSL_PKEY_NUM; i++) {
269
0
    X509_free(ret->pkeys[i].x509);
270
0
    EVP_PKEY_free(ret->pkeys[i].privatekey);
271
0
    sk_X509_pop_free(ret->pkeys[i].chain, X509_free);
272
0
  }
273
0
  free (ret);
274
0
  return NULL;
275
0
}
276
277
278
void
279
ssl_cert_free(SSL_CERT *c)
280
0
{
281
0
  int i;
282
283
0
  if (c == NULL)
284
0
    return;
285
286
0
  i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT);
287
0
  if (i > 0)
288
0
    return;
289
290
0
  DH_free(c->dhe_params);
291
292
0
  for (i = 0; i < SSL_PKEY_NUM; i++) {
293
0
    X509_free(c->pkeys[i].x509);
294
0
    EVP_PKEY_free(c->pkeys[i].privatekey);
295
0
    sk_X509_pop_free(c->pkeys[i].chain, X509_free);
296
0
  }
297
298
0
  free(c);
299
0
}
300
301
SSL_CERT *
302
ssl_get0_cert(SSL_CTX *ctx, SSL *ssl)
303
0
{
304
0
  if (ssl != NULL)
305
0
    return ssl->cert;
306
307
0
  return ctx->internal->cert;
308
0
}
309
310
int
311
ssl_cert_set0_chain(SSL_CTX *ctx, SSL *ssl, STACK_OF(X509) *chain)
312
0
{
313
0
  SSL_CERT *ssl_cert;
314
0
  SSL_CERT_PKEY *cpk;
315
0
  X509 *x509;
316
0
  int ssl_err;
317
0
  int i;
318
319
0
  if ((ssl_cert = ssl_get0_cert(ctx, ssl)) == NULL)
320
0
    return 0;
321
322
0
  if ((cpk = ssl_cert->key) == NULL)
323
0
    return 0;
324
325
0
  for (i = 0; i < sk_X509_num(chain); i++) {
326
0
    x509 = sk_X509_value(chain, i);
327
0
    if (!ssl_security_cert(ctx, ssl, x509, 0, &ssl_err)) {
328
0
      SSLerrorx(ssl_err);
329
0
      return 0;
330
0
    }
331
0
  }
332
333
0
  sk_X509_pop_free(cpk->chain, X509_free);
334
0
  cpk->chain = chain;
335
336
0
  return 1;
337
0
}
338
339
int
340
ssl_cert_set1_chain(SSL_CTX *ctx, SSL *ssl, STACK_OF(X509) *chain)
341
0
{
342
0
  STACK_OF(X509) *new_chain = NULL;
343
344
0
  if (chain != NULL) {
345
0
    if ((new_chain = X509_chain_up_ref(chain)) == NULL)
346
0
      return 0;
347
0
  }
348
0
  if (!ssl_cert_set0_chain(ctx, ssl, new_chain)) {
349
0
    sk_X509_pop_free(new_chain, X509_free);
350
0
    return 0;
351
0
  }
352
353
0
  return 1;
354
0
}
355
356
int
357
ssl_cert_add0_chain_cert(SSL_CTX *ctx, SSL *ssl, X509 *cert)
358
0
{
359
0
  SSL_CERT *ssl_cert;
360
0
  SSL_CERT_PKEY *cpk;
361
0
  int ssl_err;
362
363
0
  if ((ssl_cert = ssl_get0_cert(ctx, ssl)) == NULL)
364
0
    return 0;
365
366
0
  if ((cpk = ssl_cert->key) == NULL)
367
0
    return 0;
368
369
0
  if (!ssl_security_cert(ctx, ssl, cert, 0, &ssl_err)) {
370
0
    SSLerrorx(ssl_err);
371
0
    return 0;
372
0
  }
373
374
0
  if (cpk->chain == NULL) {
375
0
    if ((cpk->chain = sk_X509_new_null()) == NULL)
376
0
      return 0;
377
0
  }
378
0
  if (!sk_X509_push(cpk->chain, cert))
379
0
    return 0;
380
381
0
  return 1;
382
0
}
383
384
int
385
ssl_cert_add1_chain_cert(SSL_CTX *ctx, SSL *ssl, X509 *cert)
386
0
{
387
0
  if (!ssl_cert_add0_chain_cert(ctx, ssl, cert))
388
0
    return 0;
389
390
0
  X509_up_ref(cert);
391
392
0
  return 1;
393
0
}
394
395
int
396
ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *certs)
397
0
{
398
0
  X509_STORE_CTX *ctx = NULL;
399
0
  X509_VERIFY_PARAM *param;
400
0
  X509 *cert;
401
0
  int ret = 0;
402
403
0
  if (sk_X509_num(certs) < 1)
404
0
    goto err;
405
406
0
  if ((ctx = X509_STORE_CTX_new()) == NULL)
407
0
    goto err;
408
409
0
  cert = sk_X509_value(certs, 0);
410
0
  if (!X509_STORE_CTX_init(ctx, s->ctx->cert_store, cert, certs)) {
411
0
    SSLerror(s, ERR_R_X509_LIB);
412
0
    goto err;
413
0
  }
414
0
  X509_STORE_CTX_set_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
415
416
  /*
417
   * We need to inherit the verify parameters. These can be
418
   * determined by the context: if its a server it will verify
419
   * SSL client certificates or vice versa.
420
   */
421
0
  X509_STORE_CTX_set_default(ctx, s->server ? "ssl_client" : "ssl_server");
422
423
0
  param = X509_STORE_CTX_get0_param(ctx);
424
425
0
  X509_VERIFY_PARAM_set_auth_level(param, SSL_get_security_level(s));
426
427
  /*
428
   * Anything non-default in "param" should overwrite anything
429
   * in the ctx.
430
   */
431
0
  X509_VERIFY_PARAM_set1(param, s->param);
432
433
0
  if (s->internal->verify_callback)
434
0
    X509_STORE_CTX_set_verify_cb(ctx, s->internal->verify_callback);
435
436
0
  if (s->ctx->internal->app_verify_callback != NULL)
437
0
    ret = s->ctx->internal->app_verify_callback(ctx,
438
0
        s->ctx->internal->app_verify_arg);
439
0
  else
440
0
    ret = X509_verify_cert(ctx);
441
442
0
  s->verify_result = X509_STORE_CTX_get_error(ctx);
443
0
  sk_X509_pop_free(s->internal->verified_chain, X509_free);
444
0
  s->internal->verified_chain = NULL;
445
0
  if (X509_STORE_CTX_get0_chain(ctx) != NULL) {
446
0
    s->internal->verified_chain = X509_STORE_CTX_get1_chain(ctx);
447
0
    if (s->internal->verified_chain == NULL) {
448
0
      SSLerrorx(ERR_R_MALLOC_FAILURE);
449
0
      ret = 0;
450
0
    }
451
0
  }
452
453
0
 err:
454
0
  X509_STORE_CTX_free(ctx);
455
456
0
  return (ret);
457
0
}
458
459
static void
460
set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
461
    STACK_OF(X509_NAME) *name_list)
462
0
{
463
0
  sk_X509_NAME_pop_free(*ca_list, X509_NAME_free);
464
0
  *ca_list = name_list;
465
0
}
466
467
STACK_OF(X509_NAME) *
468
SSL_dup_CA_list(const STACK_OF(X509_NAME) *sk)
469
0
{
470
0
  int i;
471
0
  STACK_OF(X509_NAME) *ret;
472
0
  X509_NAME *name = NULL;
473
474
0
  if ((ret = sk_X509_NAME_new_null()) == NULL)
475
0
    goto err;
476
477
0
  for (i = 0; i < sk_X509_NAME_num(sk); i++) {
478
0
    if ((name = X509_NAME_dup(sk_X509_NAME_value(sk, i))) == NULL)
479
0
      goto err;
480
0
    if (!sk_X509_NAME_push(ret, name))
481
0
      goto err;
482
0
  }
483
0
  return (ret);
484
485
0
 err:
486
0
  X509_NAME_free(name);
487
0
  sk_X509_NAME_pop_free(ret, X509_NAME_free);
488
0
  return NULL;
489
0
}
490
491
void
492
SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list)
493
0
{
494
0
  set_client_CA_list(&(s->internal->client_CA), name_list);
495
0
}
496
497
void
498
SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list)
499
0
{
500
0
  set_client_CA_list(&(ctx->internal->client_CA), name_list);
501
0
}
502
503
STACK_OF(X509_NAME) *
504
SSL_CTX_get_client_CA_list(const SSL_CTX *ctx)
505
0
{
506
0
  return (ctx->internal->client_CA);
507
0
}
508
509
STACK_OF(X509_NAME) *
510
SSL_get_client_CA_list(const SSL *s)
511
0
{
512
0
  if (!s->server) {
513
    /* We are in the client. */
514
0
    if ((s->version >> 8) == SSL3_VERSION_MAJOR)
515
0
      return (s->s3->hs.tls12.ca_names);
516
0
    else
517
0
      return (NULL);
518
0
  } else {
519
0
    if (s->internal->client_CA != NULL)
520
0
      return (s->internal->client_CA);
521
0
    else
522
0
      return (s->ctx->internal->client_CA);
523
0
  }
524
0
}
525
526
static int
527
add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x)
528
0
{
529
0
  X509_NAME *name;
530
531
0
  if (x == NULL)
532
0
    return (0);
533
0
  if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL))
534
0
    return (0);
535
536
0
  if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL)
537
0
    return (0);
538
539
0
  if (!sk_X509_NAME_push(*sk, name)) {
540
0
    X509_NAME_free(name);
541
0
    return (0);
542
0
  }
543
0
  return (1);
544
0
}
545
546
int
547
SSL_add_client_CA(SSL *ssl, X509 *x)
548
0
{
549
0
  return (add_client_CA(&(ssl->internal->client_CA), x));
550
0
}
551
552
int
553
SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x)
554
0
{
555
0
  return (add_client_CA(&(ctx->internal->client_CA), x));
556
0
}
557
558
static int
559
xname_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
560
0
{
561
0
  return (X509_NAME_cmp(*a, *b));
562
0
}
563
564
/*!
565
 * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
566
 * it doesn't really have anything to do with clients (except that a common use
567
 * for a stack of CAs is to send it to the client). Actually, it doesn't have
568
 * much to do with CAs, either, since it will load any old cert.
569
 * \param file the file containing one or more certs.
570
 * \return a ::STACK containing the certs.
571
 */
572
STACK_OF(X509_NAME) *
573
SSL_load_client_CA_file(const char *file)
574
0
{
575
0
  BIO *in;
576
0
  X509 *x = NULL;
577
0
  X509_NAME *xn = NULL;
578
0
  STACK_OF(X509_NAME) *ret = NULL, *sk;
579
580
0
  sk = sk_X509_NAME_new(xname_cmp);
581
582
0
  in = BIO_new(BIO_s_file());
583
584
0
  if ((sk == NULL) || (in == NULL)) {
585
0
    SSLerrorx(ERR_R_MALLOC_FAILURE);
586
0
    goto err;
587
0
  }
588
589
0
  if (!BIO_read_filename(in, file))
590
0
    goto err;
591
592
0
  for (;;) {
593
0
    if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
594
0
      break;
595
0
    if (ret == NULL) {
596
0
      ret = sk_X509_NAME_new_null();
597
0
      if (ret == NULL) {
598
0
        SSLerrorx(ERR_R_MALLOC_FAILURE);
599
0
        goto err;
600
0
      }
601
0
    }
602
0
    if ((xn = X509_get_subject_name(x)) == NULL)
603
0
      goto err;
604
    /* check for duplicates */
605
0
    xn = X509_NAME_dup(xn);
606
0
    if (xn == NULL)
607
0
      goto err;
608
0
    if (sk_X509_NAME_find(sk, xn) >= 0)
609
0
      X509_NAME_free(xn);
610
0
    else {
611
0
      if (!sk_X509_NAME_push(sk, xn))
612
0
        goto err;
613
0
      if (!sk_X509_NAME_push(ret, xn))
614
0
        goto err;
615
0
    }
616
0
  }
617
618
0
  if (0) {
619
0
 err:
620
0
    sk_X509_NAME_pop_free(ret, X509_NAME_free);
621
0
    ret = NULL;
622
0
  }
623
0
  sk_X509_NAME_free(sk);
624
0
  BIO_free(in);
625
0
  X509_free(x);
626
0
  if (ret != NULL)
627
0
    ERR_clear_error();
628
629
0
  return (ret);
630
0
}
631
632
/*!
633
 * Add a file of certs to a stack.
634
 * \param stack the stack to add to.
635
 * \param file the file to add from. All certs in this file that are not
636
 * already in the stack will be added.
637
 * \return 1 for success, 0 for failure. Note that in the case of failure some
638
 * certs may have been added to \c stack.
639
 */
640
641
int
642
SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
643
    const char *file)
644
0
{
645
0
  BIO *in;
646
0
  X509 *x = NULL;
647
0
  X509_NAME *xn = NULL;
648
0
  int ret = 1;
649
0
  int (*oldcmp)(const X509_NAME * const *a, const X509_NAME * const *b);
650
651
0
  oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
652
653
0
  in = BIO_new(BIO_s_file());
654
655
0
  if (in == NULL) {
656
0
    SSLerrorx(ERR_R_MALLOC_FAILURE);
657
0
    goto err;
658
0
  }
659
660
0
  if (!BIO_read_filename(in, file))
661
0
    goto err;
662
663
0
  for (;;) {
664
0
    if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
665
0
      break;
666
0
    if ((xn = X509_get_subject_name(x)) == NULL)
667
0
      goto err;
668
0
    xn = X509_NAME_dup(xn);
669
0
    if (xn == NULL)
670
0
      goto err;
671
0
    if (sk_X509_NAME_find(stack, xn) >= 0)
672
0
      X509_NAME_free(xn);
673
0
    else
674
0
      if (!sk_X509_NAME_push(stack, xn))
675
0
        goto err;
676
0
  }
677
678
0
  ERR_clear_error();
679
680
0
  if (0) {
681
0
 err:
682
0
    ret = 0;
683
0
  }
684
0
  BIO_free(in);
685
0
  X509_free(x);
686
687
0
  (void)sk_X509_NAME_set_cmp_func(stack, oldcmp);
688
689
0
  return ret;
690
0
}
691
692
/*!
693
 * Add a directory of certs to a stack.
694
 * \param stack the stack to append to.
695
 * \param dir the directory to append from. All files in this directory will be
696
 * examined as potential certs. Any that are acceptable to
697
 * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will
698
 * be included.
699
 * \return 1 for success, 0 for failure. Note that in the case of failure some
700
 * certs may have been added to \c stack.
701
 */
702
703
int
704
SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, const char *dir)
705
0
{
706
0
  DIR *dirp = NULL;
707
0
  char *path = NULL;
708
0
  int ret = 0;
709
710
0
  dirp = opendir(dir);
711
0
  if (dirp) {
712
0
    struct dirent *dp;
713
0
    while ((dp = readdir(dirp)) != NULL) {
714
0
      if (asprintf(&path, "%s/%s", dir, dp->d_name) != -1) {
715
0
        ret = SSL_add_file_cert_subjects_to_stack(
716
0
            stack, path);
717
0
        free(path);
718
0
      }
719
0
      if (!ret)
720
0
        break;
721
0
    }
722
0
    (void) closedir(dirp);
723
0
  }
724
0
  if (!ret) {
725
0
    SYSerror(errno);
726
0
    ERR_asprintf_error_data("opendir ('%s')", dir);
727
0
    SSLerrorx(ERR_R_SYS_LIB);
728
0
  }
729
0
  return ret;
730
0
}