summaryrefslogtreecommitdiff
path: root/src/lib/libssl/ssl_rsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/ssl_rsa.c')
-rw-r--r--src/lib/libssl/ssl_rsa.c769
1 files changed, 0 insertions, 769 deletions
diff --git a/src/lib/libssl/ssl_rsa.c b/src/lib/libssl/ssl_rsa.c
deleted file mode 100644
index 68137bc5fb..0000000000
--- a/src/lib/libssl/ssl_rsa.c
+++ /dev/null
@@ -1,769 +0,0 @@
1/* $OpenBSD: ssl_rsa.c,v 1.50 2023/07/08 16:40:13 beck 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#include <stdio.h>
60
61#include <openssl/bio.h>
62#include <openssl/evp.h>
63#include <openssl/objects.h>
64#include <openssl/pem.h>
65#include <openssl/x509.h>
66
67#include "ssl_local.h"
68
69static int ssl_get_password_cb_and_arg(SSL_CTX *ctx, SSL *ssl,
70 pem_password_cb **passwd_cb, void **passwd_arg);
71static int ssl_set_cert(SSL_CTX *ctx, SSL *ssl, X509 *x509);
72static int ssl_set_pkey(SSL_CTX *ctx, SSL *ssl, EVP_PKEY *pkey);
73static int ssl_use_certificate_chain_bio(SSL_CTX *ctx, SSL *ssl, BIO *in);
74static int ssl_use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl,
75 const char *file);
76
77int
78SSL_use_certificate(SSL *ssl, X509 *x)
79{
80 if (x == NULL) {
81 SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
82 return (0);
83 }
84 return ssl_set_cert(NULL, ssl, x);
85}
86LSSL_ALIAS(SSL_use_certificate);
87
88int
89SSL_use_certificate_file(SSL *ssl, const char *file, int type)
90{
91 int j;
92 BIO *in;
93 int ret = 0;
94 X509 *x = NULL;
95
96 in = BIO_new(BIO_s_file());
97 if (in == NULL) {
98 SSLerror(ssl, ERR_R_BUF_LIB);
99 goto end;
100 }
101
102 if (BIO_read_filename(in, file) <= 0) {
103 SSLerror(ssl, ERR_R_SYS_LIB);
104 goto end;
105 }
106 if (type == SSL_FILETYPE_ASN1) {
107 j = ERR_R_ASN1_LIB;
108 x = d2i_X509_bio(in, NULL);
109 } else if (type == SSL_FILETYPE_PEM) {
110 j = ERR_R_PEM_LIB;
111 x = PEM_read_bio_X509(in, NULL,
112 ssl->ctx->default_passwd_callback,
113 ssl->ctx->default_passwd_callback_userdata);
114 } else {
115 SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
116 goto end;
117 }
118
119 if (x == NULL) {
120 SSLerror(ssl, j);
121 goto end;
122 }
123
124 ret = SSL_use_certificate(ssl, x);
125 end:
126 X509_free(x);
127 BIO_free(in);
128 return (ret);
129}
130LSSL_ALIAS(SSL_use_certificate_file);
131
132int
133SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
134{
135 X509 *x;
136 int ret;
137
138 x = d2i_X509(NULL, &d, (long)len);
139 if (x == NULL) {
140 SSLerror(ssl, ERR_R_ASN1_LIB);
141 return (0);
142 }
143
144 ret = SSL_use_certificate(ssl, x);
145 X509_free(x);
146 return (ret);
147}
148LSSL_ALIAS(SSL_use_certificate_ASN1);
149
150int
151SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
152{
153 EVP_PKEY *pkey;
154 int ret;
155
156 if (rsa == NULL) {
157 SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
158 return (0);
159 }
160 if ((pkey = EVP_PKEY_new()) == NULL) {
161 SSLerror(ssl, ERR_R_EVP_LIB);
162 return (0);
163 }
164
165 RSA_up_ref(rsa);
166 EVP_PKEY_assign_RSA(pkey, rsa);
167
168 ret = ssl_set_pkey(NULL, ssl, pkey);
169 EVP_PKEY_free(pkey);
170 return (ret);
171}
172LSSL_ALIAS(SSL_use_RSAPrivateKey);
173
174static int
175ssl_set_pkey(SSL_CTX *ctx, SSL *ssl, EVP_PKEY *pkey)
176{
177 SSL_CERT *c;
178 int i;
179
180 i = ssl_cert_type(pkey);
181 if (i < 0) {
182 SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
183 return (0);
184 }
185
186 if ((c = ssl_get0_cert(ctx, ssl)) == NULL)
187 return (0);
188
189 if (c->pkeys[i].x509 != NULL) {
190 EVP_PKEY *pktmp;
191
192 if ((pktmp = X509_get0_pubkey(c->pkeys[i].x509)) == NULL)
193 return 0;
194
195 /*
196 * Callers of EVP_PKEY_copy_parameters() can't distinguish
197 * errors from the absence of a param_copy() method. So
198 * pretend it can never fail.
199 */
200 EVP_PKEY_copy_parameters(pktmp, pkey);
201
202 ERR_clear_error();
203
204 /*
205 * Don't check the public/private key, this is mostly
206 * for smart cards.
207 */
208 if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA ||
209 !(RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK)) {
210 if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
211 X509_free(c->pkeys[i].x509);
212 c->pkeys[i].x509 = NULL;
213 return 0;
214 }
215 }
216 }
217
218 EVP_PKEY_free(c->pkeys[i].privatekey);
219 EVP_PKEY_up_ref(pkey);
220 c->pkeys[i].privatekey = pkey;
221 c->key = &(c->pkeys[i]);
222
223 c->valid = 0;
224 return 1;
225}
226
227int
228SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
229{
230 int j, ret = 0;
231 BIO *in;
232 RSA *rsa = NULL;
233
234 in = BIO_new(BIO_s_file());
235 if (in == NULL) {
236 SSLerror(ssl, ERR_R_BUF_LIB);
237 goto end;
238 }
239
240 if (BIO_read_filename(in, file) <= 0) {
241 SSLerror(ssl, ERR_R_SYS_LIB);
242 goto end;
243 }
244 if (type == SSL_FILETYPE_ASN1) {
245 j = ERR_R_ASN1_LIB;
246 rsa = d2i_RSAPrivateKey_bio(in, NULL);
247 } else if (type == SSL_FILETYPE_PEM) {
248 j = ERR_R_PEM_LIB;
249 rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
250 ssl->ctx->default_passwd_callback,
251 ssl->ctx->default_passwd_callback_userdata);
252 } else {
253 SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
254 goto end;
255 }
256 if (rsa == NULL) {
257 SSLerror(ssl, j);
258 goto end;
259 }
260 ret = SSL_use_RSAPrivateKey(ssl, rsa);
261 RSA_free(rsa);
262 end:
263 BIO_free(in);
264 return (ret);
265}
266LSSL_ALIAS(SSL_use_RSAPrivateKey_file);
267
268int
269SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
270{
271 int ret;
272 RSA *rsa;
273
274 if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
275 SSLerror(ssl, ERR_R_ASN1_LIB);
276 return (0);
277 }
278
279 ret = SSL_use_RSAPrivateKey(ssl, rsa);
280 RSA_free(rsa);
281 return (ret);
282}
283LSSL_ALIAS(SSL_use_RSAPrivateKey_ASN1);
284
285int
286SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
287{
288 int ret;
289
290 if (pkey == NULL) {
291 SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
292 return (0);
293 }
294 ret = ssl_set_pkey(NULL, ssl, pkey);
295 return (ret);
296}
297LSSL_ALIAS(SSL_use_PrivateKey);
298
299int
300SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
301{
302 int j, ret = 0;
303 BIO *in;
304 EVP_PKEY *pkey = NULL;
305
306 in = BIO_new(BIO_s_file());
307 if (in == NULL) {
308 SSLerror(ssl, ERR_R_BUF_LIB);
309 goto end;
310 }
311
312 if (BIO_read_filename(in, file) <= 0) {
313 SSLerror(ssl, ERR_R_SYS_LIB);
314 goto end;
315 }
316 if (type == SSL_FILETYPE_PEM) {
317 j = ERR_R_PEM_LIB;
318 pkey = PEM_read_bio_PrivateKey(in, NULL,
319 ssl->ctx->default_passwd_callback,
320 ssl->ctx->default_passwd_callback_userdata);
321 } else if (type == SSL_FILETYPE_ASN1) {
322 j = ERR_R_ASN1_LIB;
323 pkey = d2i_PrivateKey_bio(in, NULL);
324 } else {
325 SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
326 goto end;
327 }
328 if (pkey == NULL) {
329 SSLerror(ssl, j);
330 goto end;
331 }
332 ret = SSL_use_PrivateKey(ssl, pkey);
333 EVP_PKEY_free(pkey);
334 end:
335 BIO_free(in);
336 return (ret);
337}
338LSSL_ALIAS(SSL_use_PrivateKey_file);
339
340int
341SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
342{
343 int ret;
344 EVP_PKEY *pkey;
345
346 if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
347 SSLerror(ssl, ERR_R_ASN1_LIB);
348 return (0);
349 }
350
351 ret = SSL_use_PrivateKey(ssl, pkey);
352 EVP_PKEY_free(pkey);
353 return (ret);
354}
355LSSL_ALIAS(SSL_use_PrivateKey_ASN1);
356
357int
358SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
359{
360 if (x == NULL) {
361 SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
362 return (0);
363 }
364 return ssl_set_cert(ctx, NULL, x);
365}
366LSSL_ALIAS(SSL_CTX_use_certificate);
367
368static int
369ssl_get_password_cb_and_arg(SSL_CTX *ctx, SSL *ssl,
370 pem_password_cb **passwd_cb, void **passwd_arg)
371{
372 if (ssl != NULL)
373 ctx = ssl->ctx;
374
375 *passwd_cb = ctx->default_passwd_callback;
376 *passwd_arg = ctx->default_passwd_callback_userdata;
377
378 return 1;
379}
380
381static int
382ssl_set_cert(SSL_CTX *ctx, SSL *ssl, X509 *x)
383{
384 SSL_CERT *c;
385 EVP_PKEY *pkey;
386 int ssl_err;
387 int i;
388
389 if (!ssl_security_cert(ctx, ssl, x, 1, &ssl_err)) {
390 SSLerrorx(ssl_err);
391 return (0);
392 }
393
394 if ((c = ssl_get0_cert(ctx, ssl)) == NULL)
395 return (0);
396
397 pkey = X509_get_pubkey(x);
398 if (pkey == NULL) {
399 SSLerrorx(SSL_R_X509_LIB);
400 return (0);
401 }
402
403 i = ssl_cert_type(pkey);
404 if (i < 0) {
405 SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
406 EVP_PKEY_free(pkey);
407 return (0);
408 }
409
410 if (c->pkeys[i].privatekey != NULL) {
411 EVP_PKEY *priv_key = c->pkeys[i].privatekey;
412
413 EVP_PKEY_copy_parameters(pkey, priv_key);
414 ERR_clear_error();
415
416 /*
417 * Don't check the public/private key, this is mostly
418 * for smart cards.
419 */
420 if (EVP_PKEY_id(priv_key) != EVP_PKEY_RSA ||
421 !(RSA_flags(EVP_PKEY_get0_RSA(priv_key)) & RSA_METHOD_FLAG_NO_CHECK)) {
422 if (!X509_check_private_key(x, priv_key)) {
423 /*
424 * don't fail for a cert/key mismatch, just free
425 * current private key (when switching to a
426 * different cert & key, first this function
427 * should be used, then ssl_set_pkey.
428 */
429 EVP_PKEY_free(c->pkeys[i].privatekey);
430 c->pkeys[i].privatekey = NULL;
431 ERR_clear_error();
432 }
433 }
434 }
435
436 EVP_PKEY_free(pkey);
437
438 X509_free(c->pkeys[i].x509);
439 X509_up_ref(x);
440 c->pkeys[i].x509 = x;
441 c->key = &(c->pkeys[i]);
442
443 c->valid = 0;
444 return (1);
445}
446
447int
448SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
449{
450 int j;
451 BIO *in;
452 int ret = 0;
453 X509 *x = NULL;
454
455 in = BIO_new(BIO_s_file());
456 if (in == NULL) {
457 SSLerrorx(ERR_R_BUF_LIB);
458 goto end;
459 }
460
461 if (BIO_read_filename(in, file) <= 0) {
462 SSLerrorx(ERR_R_SYS_LIB);
463 goto end;
464 }
465 if (type == SSL_FILETYPE_ASN1) {
466 j = ERR_R_ASN1_LIB;
467 x = d2i_X509_bio(in, NULL);
468 } else if (type == SSL_FILETYPE_PEM) {
469 j = ERR_R_PEM_LIB;
470 x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
471 ctx->default_passwd_callback_userdata);
472 } else {
473 SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
474 goto end;
475 }
476
477 if (x == NULL) {
478 SSLerrorx(j);
479 goto end;
480 }
481
482 ret = SSL_CTX_use_certificate(ctx, x);
483 end:
484 X509_free(x);
485 BIO_free(in);
486 return (ret);
487}
488LSSL_ALIAS(SSL_CTX_use_certificate_file);
489
490int
491SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
492{
493 X509 *x;
494 int ret;
495
496 x = d2i_X509(NULL, &d, (long)len);
497 if (x == NULL) {
498 SSLerrorx(ERR_R_ASN1_LIB);
499 return (0);
500 }
501
502 ret = SSL_CTX_use_certificate(ctx, x);
503 X509_free(x);
504 return (ret);
505}
506LSSL_ALIAS(SSL_CTX_use_certificate_ASN1);
507
508int
509SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
510{
511 int ret;
512 EVP_PKEY *pkey;
513
514 if (rsa == NULL) {
515 SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
516 return (0);
517 }
518 if ((pkey = EVP_PKEY_new()) == NULL) {
519 SSLerrorx(ERR_R_EVP_LIB);
520 return (0);
521 }
522
523 RSA_up_ref(rsa);
524 EVP_PKEY_assign_RSA(pkey, rsa);
525
526 ret = ssl_set_pkey(ctx, NULL, pkey);
527 EVP_PKEY_free(pkey);
528 return (ret);
529}
530LSSL_ALIAS(SSL_CTX_use_RSAPrivateKey);
531
532int
533SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
534{
535 int j, ret = 0;
536 BIO *in;
537 RSA *rsa = NULL;
538
539 in = BIO_new(BIO_s_file());
540 if (in == NULL) {
541 SSLerrorx(ERR_R_BUF_LIB);
542 goto end;
543 }
544
545 if (BIO_read_filename(in, file) <= 0) {
546 SSLerrorx(ERR_R_SYS_LIB);
547 goto end;
548 }
549 if (type == SSL_FILETYPE_ASN1) {
550 j = ERR_R_ASN1_LIB;
551 rsa = d2i_RSAPrivateKey_bio(in, NULL);
552 } else if (type == SSL_FILETYPE_PEM) {
553 j = ERR_R_PEM_LIB;
554 rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
555 ctx->default_passwd_callback,
556 ctx->default_passwd_callback_userdata);
557 } else {
558 SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
559 goto end;
560 }
561 if (rsa == NULL) {
562 SSLerrorx(j);
563 goto end;
564 }
565 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
566 RSA_free(rsa);
567 end:
568 BIO_free(in);
569 return (ret);
570}
571LSSL_ALIAS(SSL_CTX_use_RSAPrivateKey_file);
572
573int
574SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
575{
576 int ret;
577 RSA *rsa;
578
579 if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
580 SSLerrorx(ERR_R_ASN1_LIB);
581 return (0);
582 }
583
584 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
585 RSA_free(rsa);
586 return (ret);
587}
588LSSL_ALIAS(SSL_CTX_use_RSAPrivateKey_ASN1);
589
590int
591SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
592{
593 if (pkey == NULL) {
594 SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
595 return (0);
596 }
597 return ssl_set_pkey(ctx, NULL, pkey);
598}
599LSSL_ALIAS(SSL_CTX_use_PrivateKey);
600
601int
602SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
603{
604 int j, ret = 0;
605 BIO *in;
606 EVP_PKEY *pkey = NULL;
607
608 in = BIO_new(BIO_s_file());
609 if (in == NULL) {
610 SSLerrorx(ERR_R_BUF_LIB);
611 goto end;
612 }
613
614 if (BIO_read_filename(in, file) <= 0) {
615 SSLerrorx(ERR_R_SYS_LIB);
616 goto end;
617 }
618 if (type == SSL_FILETYPE_PEM) {
619 j = ERR_R_PEM_LIB;
620 pkey = PEM_read_bio_PrivateKey(in, NULL,
621 ctx->default_passwd_callback,
622 ctx->default_passwd_callback_userdata);
623 } else if (type == SSL_FILETYPE_ASN1) {
624 j = ERR_R_ASN1_LIB;
625 pkey = d2i_PrivateKey_bio(in, NULL);
626 } else {
627 SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
628 goto end;
629 }
630 if (pkey == NULL) {
631 SSLerrorx(j);
632 goto end;
633 }
634 ret = SSL_CTX_use_PrivateKey(ctx, pkey);
635 EVP_PKEY_free(pkey);
636 end:
637 BIO_free(in);
638 return (ret);
639}
640LSSL_ALIAS(SSL_CTX_use_PrivateKey_file);
641
642int
643SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
644 long len)
645{
646 int ret;
647 EVP_PKEY *pkey;
648
649 if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
650 SSLerrorx(ERR_R_ASN1_LIB);
651 return (0);
652 }
653
654 ret = SSL_CTX_use_PrivateKey(ctx, pkey);
655 EVP_PKEY_free(pkey);
656 return (ret);
657}
658LSSL_ALIAS(SSL_CTX_use_PrivateKey_ASN1);
659
660
661/*
662 * Read a bio that contains our certificate in "PEM" format,
663 * possibly followed by a sequence of CA certificates that should be
664 * sent to the peer in the Certificate message.
665 */
666static int
667ssl_use_certificate_chain_bio(SSL_CTX *ctx, SSL *ssl, BIO *in)
668{
669 pem_password_cb *passwd_cb;
670 void *passwd_arg;
671 X509 *ca, *x = NULL;
672 unsigned long err;
673 int ret = 0;
674
675 if (!ssl_get_password_cb_and_arg(ctx, ssl, &passwd_cb, &passwd_arg))
676 goto err;
677
678 if ((x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_arg)) ==
679 NULL) {
680 SSLerrorx(ERR_R_PEM_LIB);
681 goto err;
682 }
683
684 if (!ssl_set_cert(ctx, ssl, x))
685 goto err;
686
687 if (!ssl_cert_set0_chain(ctx, ssl, NULL))
688 goto err;
689
690 /* Process any additional CA certificates. */
691 while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_arg)) !=
692 NULL) {
693 if (!ssl_cert_add0_chain_cert(ctx, ssl, ca)) {
694 X509_free(ca);
695 goto err;
696 }
697 }
698
699 /* When the while loop ends, it's usually just EOF. */
700 err = ERR_peek_last_error();
701 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
702 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
703 ERR_clear_error();
704 ret = 1;
705 }
706
707 err:
708 X509_free(x);
709
710 return (ret);
711}
712
713int
714ssl_use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
715{
716 BIO *in;
717 int ret = 0;
718
719 in = BIO_new(BIO_s_file());
720 if (in == NULL) {
721 SSLerrorx(ERR_R_BUF_LIB);
722 goto end;
723 }
724
725 if (BIO_read_filename(in, file) <= 0) {
726 SSLerrorx(ERR_R_SYS_LIB);
727 goto end;
728 }
729
730 ret = ssl_use_certificate_chain_bio(ctx, ssl, in);
731
732 end:
733 BIO_free(in);
734 return (ret);
735}
736
737int
738SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
739{
740 return ssl_use_certificate_chain_file(ctx, NULL, file);
741}
742LSSL_ALIAS(SSL_CTX_use_certificate_chain_file);
743
744int
745SSL_use_certificate_chain_file(SSL *ssl, const char *file)
746{
747 return ssl_use_certificate_chain_file(NULL, ssl, file);
748}
749LSSL_ALIAS(SSL_use_certificate_chain_file);
750
751int
752SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
753{
754 BIO *in;
755 int ret = 0;
756
757 in = BIO_new_mem_buf(buf, len);
758 if (in == NULL) {
759 SSLerrorx(ERR_R_BUF_LIB);
760 goto end;
761 }
762
763 ret = ssl_use_certificate_chain_bio(ctx, NULL, in);
764
765 end:
766 BIO_free(in);
767 return (ret);
768}
769LSSL_ALIAS(SSL_CTX_use_certificate_chain_mem);