1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: ssl_rsa.c,v 1.48 2022/08/31 20:49:37 tb Exp $ */
2f5b1c8a1SJohn Marino /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3f5b1c8a1SJohn Marino * All rights reserved.
4f5b1c8a1SJohn Marino *
5f5b1c8a1SJohn Marino * This package is an SSL implementation written
6f5b1c8a1SJohn Marino * by Eric Young (eay@cryptsoft.com).
7f5b1c8a1SJohn Marino * The implementation was written so as to conform with Netscapes SSL.
8f5b1c8a1SJohn Marino *
9f5b1c8a1SJohn Marino * This library is free for commercial and non-commercial use as long as
10f5b1c8a1SJohn Marino * the following conditions are aheared to. The following conditions
11f5b1c8a1SJohn Marino * apply to all code found in this distribution, be it the RC4, RSA,
12f5b1c8a1SJohn Marino * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13f5b1c8a1SJohn Marino * included with this distribution is covered by the same copyright terms
14f5b1c8a1SJohn Marino * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15f5b1c8a1SJohn Marino *
16f5b1c8a1SJohn Marino * Copyright remains Eric Young's, and as such any Copyright notices in
17f5b1c8a1SJohn Marino * the code are not to be removed.
18f5b1c8a1SJohn Marino * If this package is used in a product, Eric Young should be given attribution
19f5b1c8a1SJohn Marino * as the author of the parts of the library used.
20f5b1c8a1SJohn Marino * This can be in the form of a textual message at program startup or
21f5b1c8a1SJohn Marino * in documentation (online or textual) provided with the package.
22f5b1c8a1SJohn Marino *
23f5b1c8a1SJohn Marino * Redistribution and use in source and binary forms, with or without
24f5b1c8a1SJohn Marino * modification, are permitted provided that the following conditions
25f5b1c8a1SJohn Marino * are met:
26f5b1c8a1SJohn Marino * 1. Redistributions of source code must retain the copyright
27f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer.
28f5b1c8a1SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
29f5b1c8a1SJohn Marino * notice, this list of conditions and the following disclaimer in the
30f5b1c8a1SJohn Marino * documentation and/or other materials provided with the distribution.
31f5b1c8a1SJohn Marino * 3. All advertising materials mentioning features or use of this software
32f5b1c8a1SJohn Marino * must display the following acknowledgement:
33f5b1c8a1SJohn Marino * "This product includes cryptographic software written by
34f5b1c8a1SJohn Marino * Eric Young (eay@cryptsoft.com)"
35f5b1c8a1SJohn Marino * The word 'cryptographic' can be left out if the rouines from the library
36f5b1c8a1SJohn Marino * being used are not cryptographic related :-).
37f5b1c8a1SJohn Marino * 4. If you include any Windows specific code (or a derivative thereof) from
38f5b1c8a1SJohn Marino * the apps directory (application code) you must include an acknowledgement:
39f5b1c8a1SJohn Marino * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40f5b1c8a1SJohn Marino *
41f5b1c8a1SJohn Marino * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42f5b1c8a1SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43f5b1c8a1SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44f5b1c8a1SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45f5b1c8a1SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46f5b1c8a1SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47f5b1c8a1SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48f5b1c8a1SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49f5b1c8a1SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50f5b1c8a1SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51f5b1c8a1SJohn Marino * SUCH DAMAGE.
52f5b1c8a1SJohn Marino *
53f5b1c8a1SJohn Marino * The licence and distribution terms for any publically available version or
54f5b1c8a1SJohn Marino * derivative of this code cannot be changed. i.e. this code cannot simply be
55f5b1c8a1SJohn Marino * copied and put under another distribution licence
56f5b1c8a1SJohn Marino * [including the GNU Public Licence.]
57f5b1c8a1SJohn Marino */
58f5b1c8a1SJohn Marino
59f5b1c8a1SJohn Marino #include <stdio.h>
60f5b1c8a1SJohn Marino
61f5b1c8a1SJohn Marino #include <openssl/bio.h>
62f5b1c8a1SJohn Marino #include <openssl/evp.h>
63f5b1c8a1SJohn Marino #include <openssl/objects.h>
64f5b1c8a1SJohn Marino #include <openssl/pem.h>
65f5b1c8a1SJohn Marino #include <openssl/x509.h>
66f5b1c8a1SJohn Marino
67*de0e0e4dSAntonio Huete Jimenez #include "ssl_locl.h"
68*de0e0e4dSAntonio Huete Jimenez
69*de0e0e4dSAntonio Huete Jimenez static int ssl_get_password_cb_and_arg(SSL_CTX *ctx, SSL *ssl,
70*de0e0e4dSAntonio Huete Jimenez pem_password_cb **passwd_cb, void **passwd_arg);
71*de0e0e4dSAntonio Huete Jimenez static int ssl_set_cert(SSL_CTX *ctx, SSL *ssl, X509 *x509);
72*de0e0e4dSAntonio Huete Jimenez static int ssl_set_pkey(SSL_CTX *ctx, SSL *ssl, EVP_PKEY *pkey);
73*de0e0e4dSAntonio Huete Jimenez static int ssl_use_certificate_chain_bio(SSL_CTX *ctx, SSL *ssl, BIO *in);
74*de0e0e4dSAntonio Huete Jimenez static int ssl_use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl,
75*de0e0e4dSAntonio Huete Jimenez const char *file);
76f5b1c8a1SJohn Marino
77f5b1c8a1SJohn Marino int
SSL_use_certificate(SSL * ssl,X509 * x)78f5b1c8a1SJohn Marino SSL_use_certificate(SSL *ssl, X509 *x)
79f5b1c8a1SJohn Marino {
80f5b1c8a1SJohn Marino if (x == NULL) {
8172c33676SMaxim Ag SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
82f5b1c8a1SJohn Marino return (0);
83f5b1c8a1SJohn Marino }
84*de0e0e4dSAntonio Huete Jimenez return ssl_set_cert(NULL, ssl, x);
85f5b1c8a1SJohn Marino }
86f5b1c8a1SJohn Marino
87f5b1c8a1SJohn Marino int
SSL_use_certificate_file(SSL * ssl,const char * file,int type)88f5b1c8a1SJohn Marino SSL_use_certificate_file(SSL *ssl, const char *file, int type)
89f5b1c8a1SJohn Marino {
90f5b1c8a1SJohn Marino int j;
91f5b1c8a1SJohn Marino BIO *in;
92f5b1c8a1SJohn Marino int ret = 0;
93f5b1c8a1SJohn Marino X509 *x = NULL;
94f5b1c8a1SJohn Marino
95*de0e0e4dSAntonio Huete Jimenez in = BIO_new(BIO_s_file());
96f5b1c8a1SJohn Marino if (in == NULL) {
9772c33676SMaxim Ag SSLerror(ssl, ERR_R_BUF_LIB);
98f5b1c8a1SJohn Marino goto end;
99f5b1c8a1SJohn Marino }
100f5b1c8a1SJohn Marino
101f5b1c8a1SJohn Marino if (BIO_read_filename(in, file) <= 0) {
10272c33676SMaxim Ag SSLerror(ssl, ERR_R_SYS_LIB);
103f5b1c8a1SJohn Marino goto end;
104f5b1c8a1SJohn Marino }
105f5b1c8a1SJohn Marino if (type == SSL_FILETYPE_ASN1) {
106f5b1c8a1SJohn Marino j = ERR_R_ASN1_LIB;
107f5b1c8a1SJohn Marino x = d2i_X509_bio(in, NULL);
108f5b1c8a1SJohn Marino } else if (type == SSL_FILETYPE_PEM) {
109f5b1c8a1SJohn Marino j = ERR_R_PEM_LIB;
110f5b1c8a1SJohn Marino x = PEM_read_bio_X509(in, NULL,
111f5b1c8a1SJohn Marino ssl->ctx->default_passwd_callback,
112f5b1c8a1SJohn Marino ssl->ctx->default_passwd_callback_userdata);
113f5b1c8a1SJohn Marino } else {
11472c33676SMaxim Ag SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
115f5b1c8a1SJohn Marino goto end;
116f5b1c8a1SJohn Marino }
117f5b1c8a1SJohn Marino
118f5b1c8a1SJohn Marino if (x == NULL) {
11972c33676SMaxim Ag SSLerror(ssl, j);
120f5b1c8a1SJohn Marino goto end;
121f5b1c8a1SJohn Marino }
122f5b1c8a1SJohn Marino
123f5b1c8a1SJohn Marino ret = SSL_use_certificate(ssl, x);
124f5b1c8a1SJohn Marino end:
125f5b1c8a1SJohn Marino X509_free(x);
126f5b1c8a1SJohn Marino BIO_free(in);
127f5b1c8a1SJohn Marino return (ret);
128f5b1c8a1SJohn Marino }
129f5b1c8a1SJohn Marino
130f5b1c8a1SJohn Marino int
SSL_use_certificate_ASN1(SSL * ssl,const unsigned char * d,int len)131f5b1c8a1SJohn Marino SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
132f5b1c8a1SJohn Marino {
133f5b1c8a1SJohn Marino X509 *x;
134f5b1c8a1SJohn Marino int ret;
135f5b1c8a1SJohn Marino
136f5b1c8a1SJohn Marino x = d2i_X509(NULL, &d, (long)len);
137f5b1c8a1SJohn Marino if (x == NULL) {
13872c33676SMaxim Ag SSLerror(ssl, ERR_R_ASN1_LIB);
139f5b1c8a1SJohn Marino return (0);
140f5b1c8a1SJohn Marino }
141f5b1c8a1SJohn Marino
142f5b1c8a1SJohn Marino ret = SSL_use_certificate(ssl, x);
143f5b1c8a1SJohn Marino X509_free(x);
144f5b1c8a1SJohn Marino return (ret);
145f5b1c8a1SJohn Marino }
146f5b1c8a1SJohn Marino
147f5b1c8a1SJohn Marino int
SSL_use_RSAPrivateKey(SSL * ssl,RSA * rsa)148f5b1c8a1SJohn Marino SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
149f5b1c8a1SJohn Marino {
150f5b1c8a1SJohn Marino EVP_PKEY *pkey;
151f5b1c8a1SJohn Marino int ret;
152f5b1c8a1SJohn Marino
153f5b1c8a1SJohn Marino if (rsa == NULL) {
15472c33676SMaxim Ag SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
155f5b1c8a1SJohn Marino return (0);
156f5b1c8a1SJohn Marino }
157f5b1c8a1SJohn Marino if ((pkey = EVP_PKEY_new()) == NULL) {
15872c33676SMaxim Ag SSLerror(ssl, ERR_R_EVP_LIB);
159f5b1c8a1SJohn Marino return (0);
160f5b1c8a1SJohn Marino }
161f5b1c8a1SJohn Marino
162f5b1c8a1SJohn Marino RSA_up_ref(rsa);
163f5b1c8a1SJohn Marino EVP_PKEY_assign_RSA(pkey, rsa);
164f5b1c8a1SJohn Marino
165*de0e0e4dSAntonio Huete Jimenez ret = ssl_set_pkey(NULL, ssl, pkey);
166f5b1c8a1SJohn Marino EVP_PKEY_free(pkey);
167f5b1c8a1SJohn Marino return (ret);
168f5b1c8a1SJohn Marino }
169f5b1c8a1SJohn Marino
170f5b1c8a1SJohn Marino static int
ssl_set_pkey(SSL_CTX * ctx,SSL * ssl,EVP_PKEY * pkey)171*de0e0e4dSAntonio Huete Jimenez ssl_set_pkey(SSL_CTX *ctx, SSL *ssl, EVP_PKEY *pkey)
172f5b1c8a1SJohn Marino {
173*de0e0e4dSAntonio Huete Jimenez SSL_CERT *c;
174f5b1c8a1SJohn Marino int i;
175f5b1c8a1SJohn Marino
176*de0e0e4dSAntonio Huete Jimenez i = ssl_cert_type(pkey);
177f5b1c8a1SJohn Marino if (i < 0) {
17872c33676SMaxim Ag SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
179f5b1c8a1SJohn Marino return (0);
180f5b1c8a1SJohn Marino }
181f5b1c8a1SJohn Marino
182*de0e0e4dSAntonio Huete Jimenez if ((c = ssl_get0_cert(ctx, ssl)) == NULL)
183*de0e0e4dSAntonio Huete Jimenez return (0);
184*de0e0e4dSAntonio Huete Jimenez
185f5b1c8a1SJohn Marino if (c->pkeys[i].x509 != NULL) {
186f5b1c8a1SJohn Marino EVP_PKEY *pktmp;
187*de0e0e4dSAntonio Huete Jimenez
188*de0e0e4dSAntonio Huete Jimenez if ((pktmp = X509_get0_pubkey(c->pkeys[i].x509)) == NULL)
189*de0e0e4dSAntonio Huete Jimenez return 0;
190*de0e0e4dSAntonio Huete Jimenez
191*de0e0e4dSAntonio Huete Jimenez /*
192*de0e0e4dSAntonio Huete Jimenez * Callers of EVP_PKEY_copy_parameters() can't distinguish
193*de0e0e4dSAntonio Huete Jimenez * errors from the absence of a param_copy() method. So
194*de0e0e4dSAntonio Huete Jimenez * pretend it can never fail.
195*de0e0e4dSAntonio Huete Jimenez */
196f5b1c8a1SJohn Marino EVP_PKEY_copy_parameters(pktmp, pkey);
197*de0e0e4dSAntonio Huete Jimenez
198f5b1c8a1SJohn Marino ERR_clear_error();
199f5b1c8a1SJohn Marino
200f5b1c8a1SJohn Marino /*
201f5b1c8a1SJohn Marino * Don't check the public/private key, this is mostly
202f5b1c8a1SJohn Marino * for smart cards.
203f5b1c8a1SJohn Marino */
204*de0e0e4dSAntonio Huete Jimenez if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA ||
205*de0e0e4dSAntonio Huete Jimenez !(RSA_flags(EVP_PKEY_get0_RSA(pkey)) & RSA_METHOD_FLAG_NO_CHECK)) {
206f5b1c8a1SJohn Marino if (!X509_check_private_key(c->pkeys[i].x509, pkey)) {
207f5b1c8a1SJohn Marino X509_free(c->pkeys[i].x509);
208f5b1c8a1SJohn Marino c->pkeys[i].x509 = NULL;
209f5b1c8a1SJohn Marino return 0;
210f5b1c8a1SJohn Marino }
211f5b1c8a1SJohn Marino }
212*de0e0e4dSAntonio Huete Jimenez }
213f5b1c8a1SJohn Marino
214f5b1c8a1SJohn Marino EVP_PKEY_free(c->pkeys[i].privatekey);
215*de0e0e4dSAntonio Huete Jimenez EVP_PKEY_up_ref(pkey);
216f5b1c8a1SJohn Marino c->pkeys[i].privatekey = pkey;
217f5b1c8a1SJohn Marino c->key = &(c->pkeys[i]);
218f5b1c8a1SJohn Marino
219f5b1c8a1SJohn Marino c->valid = 0;
220*de0e0e4dSAntonio Huete Jimenez return 1;
221f5b1c8a1SJohn Marino }
222f5b1c8a1SJohn Marino
223f5b1c8a1SJohn Marino int
SSL_use_RSAPrivateKey_file(SSL * ssl,const char * file,int type)224f5b1c8a1SJohn Marino SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
225f5b1c8a1SJohn Marino {
226f5b1c8a1SJohn Marino int j, ret = 0;
227f5b1c8a1SJohn Marino BIO *in;
228f5b1c8a1SJohn Marino RSA *rsa = NULL;
229f5b1c8a1SJohn Marino
230*de0e0e4dSAntonio Huete Jimenez in = BIO_new(BIO_s_file());
231f5b1c8a1SJohn Marino if (in == NULL) {
23272c33676SMaxim Ag SSLerror(ssl, ERR_R_BUF_LIB);
233f5b1c8a1SJohn Marino goto end;
234f5b1c8a1SJohn Marino }
235f5b1c8a1SJohn Marino
236f5b1c8a1SJohn Marino if (BIO_read_filename(in, file) <= 0) {
23772c33676SMaxim Ag SSLerror(ssl, ERR_R_SYS_LIB);
238f5b1c8a1SJohn Marino goto end;
239f5b1c8a1SJohn Marino }
240f5b1c8a1SJohn Marino if (type == SSL_FILETYPE_ASN1) {
241f5b1c8a1SJohn Marino j = ERR_R_ASN1_LIB;
242f5b1c8a1SJohn Marino rsa = d2i_RSAPrivateKey_bio(in, NULL);
243f5b1c8a1SJohn Marino } else if (type == SSL_FILETYPE_PEM) {
244f5b1c8a1SJohn Marino j = ERR_R_PEM_LIB;
245f5b1c8a1SJohn Marino rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
246f5b1c8a1SJohn Marino ssl->ctx->default_passwd_callback,
247f5b1c8a1SJohn Marino ssl->ctx->default_passwd_callback_userdata);
248f5b1c8a1SJohn Marino } else {
24972c33676SMaxim Ag SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
250f5b1c8a1SJohn Marino goto end;
251f5b1c8a1SJohn Marino }
252f5b1c8a1SJohn Marino if (rsa == NULL) {
25372c33676SMaxim Ag SSLerror(ssl, j);
254f5b1c8a1SJohn Marino goto end;
255f5b1c8a1SJohn Marino }
256f5b1c8a1SJohn Marino ret = SSL_use_RSAPrivateKey(ssl, rsa);
257f5b1c8a1SJohn Marino RSA_free(rsa);
258f5b1c8a1SJohn Marino end:
259f5b1c8a1SJohn Marino BIO_free(in);
260f5b1c8a1SJohn Marino return (ret);
261f5b1c8a1SJohn Marino }
262f5b1c8a1SJohn Marino
263f5b1c8a1SJohn Marino int
SSL_use_RSAPrivateKey_ASN1(SSL * ssl,const unsigned char * d,long len)26472c33676SMaxim Ag SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const unsigned char *d, long len)
265f5b1c8a1SJohn Marino {
266f5b1c8a1SJohn Marino int ret;
267f5b1c8a1SJohn Marino RSA *rsa;
268f5b1c8a1SJohn Marino
26972c33676SMaxim Ag if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
27072c33676SMaxim Ag SSLerror(ssl, ERR_R_ASN1_LIB);
271f5b1c8a1SJohn Marino return (0);
272f5b1c8a1SJohn Marino }
273f5b1c8a1SJohn Marino
274f5b1c8a1SJohn Marino ret = SSL_use_RSAPrivateKey(ssl, rsa);
275f5b1c8a1SJohn Marino RSA_free(rsa);
276f5b1c8a1SJohn Marino return (ret);
277f5b1c8a1SJohn Marino }
278f5b1c8a1SJohn Marino
279f5b1c8a1SJohn Marino int
SSL_use_PrivateKey(SSL * ssl,EVP_PKEY * pkey)280f5b1c8a1SJohn Marino SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
281f5b1c8a1SJohn Marino {
282f5b1c8a1SJohn Marino int ret;
283f5b1c8a1SJohn Marino
284f5b1c8a1SJohn Marino if (pkey == NULL) {
28572c33676SMaxim Ag SSLerror(ssl, ERR_R_PASSED_NULL_PARAMETER);
286f5b1c8a1SJohn Marino return (0);
287f5b1c8a1SJohn Marino }
288*de0e0e4dSAntonio Huete Jimenez ret = ssl_set_pkey(NULL, ssl, pkey);
289f5b1c8a1SJohn Marino return (ret);
290f5b1c8a1SJohn Marino }
291f5b1c8a1SJohn Marino
292f5b1c8a1SJohn Marino int
SSL_use_PrivateKey_file(SSL * ssl,const char * file,int type)293f5b1c8a1SJohn Marino SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
294f5b1c8a1SJohn Marino {
295f5b1c8a1SJohn Marino int j, ret = 0;
296f5b1c8a1SJohn Marino BIO *in;
297f5b1c8a1SJohn Marino EVP_PKEY *pkey = NULL;
298f5b1c8a1SJohn Marino
299*de0e0e4dSAntonio Huete Jimenez in = BIO_new(BIO_s_file());
300f5b1c8a1SJohn Marino if (in == NULL) {
30172c33676SMaxim Ag SSLerror(ssl, ERR_R_BUF_LIB);
302f5b1c8a1SJohn Marino goto end;
303f5b1c8a1SJohn Marino }
304f5b1c8a1SJohn Marino
305f5b1c8a1SJohn Marino if (BIO_read_filename(in, file) <= 0) {
30672c33676SMaxim Ag SSLerror(ssl, ERR_R_SYS_LIB);
307f5b1c8a1SJohn Marino goto end;
308f5b1c8a1SJohn Marino }
309f5b1c8a1SJohn Marino if (type == SSL_FILETYPE_PEM) {
310f5b1c8a1SJohn Marino j = ERR_R_PEM_LIB;
311f5b1c8a1SJohn Marino pkey = PEM_read_bio_PrivateKey(in, NULL,
312f5b1c8a1SJohn Marino ssl->ctx->default_passwd_callback,
313f5b1c8a1SJohn Marino ssl->ctx->default_passwd_callback_userdata);
314f5b1c8a1SJohn Marino } else if (type == SSL_FILETYPE_ASN1) {
315f5b1c8a1SJohn Marino j = ERR_R_ASN1_LIB;
316f5b1c8a1SJohn Marino pkey = d2i_PrivateKey_bio(in, NULL);
317f5b1c8a1SJohn Marino } else {
31872c33676SMaxim Ag SSLerror(ssl, SSL_R_BAD_SSL_FILETYPE);
319f5b1c8a1SJohn Marino goto end;
320f5b1c8a1SJohn Marino }
321f5b1c8a1SJohn Marino if (pkey == NULL) {
32272c33676SMaxim Ag SSLerror(ssl, j);
323f5b1c8a1SJohn Marino goto end;
324f5b1c8a1SJohn Marino }
325f5b1c8a1SJohn Marino ret = SSL_use_PrivateKey(ssl, pkey);
326f5b1c8a1SJohn Marino EVP_PKEY_free(pkey);
327f5b1c8a1SJohn Marino end:
328f5b1c8a1SJohn Marino BIO_free(in);
329f5b1c8a1SJohn Marino return (ret);
330f5b1c8a1SJohn Marino }
331f5b1c8a1SJohn Marino
332f5b1c8a1SJohn Marino int
SSL_use_PrivateKey_ASN1(int type,SSL * ssl,const unsigned char * d,long len)333f5b1c8a1SJohn Marino SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
334f5b1c8a1SJohn Marino {
335f5b1c8a1SJohn Marino int ret;
336f5b1c8a1SJohn Marino EVP_PKEY *pkey;
337f5b1c8a1SJohn Marino
33872c33676SMaxim Ag if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
33972c33676SMaxim Ag SSLerror(ssl, ERR_R_ASN1_LIB);
340f5b1c8a1SJohn Marino return (0);
341f5b1c8a1SJohn Marino }
342f5b1c8a1SJohn Marino
343f5b1c8a1SJohn Marino ret = SSL_use_PrivateKey(ssl, pkey);
344f5b1c8a1SJohn Marino EVP_PKEY_free(pkey);
345f5b1c8a1SJohn Marino return (ret);
346f5b1c8a1SJohn Marino }
347f5b1c8a1SJohn Marino
348f5b1c8a1SJohn Marino int
SSL_CTX_use_certificate(SSL_CTX * ctx,X509 * x)349f5b1c8a1SJohn Marino SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
350f5b1c8a1SJohn Marino {
351f5b1c8a1SJohn Marino if (x == NULL) {
35272c33676SMaxim Ag SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
353f5b1c8a1SJohn Marino return (0);
354f5b1c8a1SJohn Marino }
355*de0e0e4dSAntonio Huete Jimenez return ssl_set_cert(ctx, NULL, x);
356f5b1c8a1SJohn Marino }
357f5b1c8a1SJohn Marino
358f5b1c8a1SJohn Marino static int
ssl_get_password_cb_and_arg(SSL_CTX * ctx,SSL * ssl,pem_password_cb ** passwd_cb,void ** passwd_arg)359*de0e0e4dSAntonio Huete Jimenez ssl_get_password_cb_and_arg(SSL_CTX *ctx, SSL *ssl,
360*de0e0e4dSAntonio Huete Jimenez pem_password_cb **passwd_cb, void **passwd_arg)
361f5b1c8a1SJohn Marino {
362*de0e0e4dSAntonio Huete Jimenez if (ssl != NULL)
363*de0e0e4dSAntonio Huete Jimenez ctx = ssl->ctx;
364*de0e0e4dSAntonio Huete Jimenez
365*de0e0e4dSAntonio Huete Jimenez *passwd_cb = ctx->default_passwd_callback;
366*de0e0e4dSAntonio Huete Jimenez *passwd_arg = ctx->default_passwd_callback_userdata;
367*de0e0e4dSAntonio Huete Jimenez
368*de0e0e4dSAntonio Huete Jimenez return 1;
369*de0e0e4dSAntonio Huete Jimenez }
370*de0e0e4dSAntonio Huete Jimenez
371*de0e0e4dSAntonio Huete Jimenez static int
ssl_set_cert(SSL_CTX * ctx,SSL * ssl,X509 * x)372*de0e0e4dSAntonio Huete Jimenez ssl_set_cert(SSL_CTX *ctx, SSL *ssl, X509 *x)
373*de0e0e4dSAntonio Huete Jimenez {
374*de0e0e4dSAntonio Huete Jimenez SSL_CERT *c;
375f5b1c8a1SJohn Marino EVP_PKEY *pkey;
376*de0e0e4dSAntonio Huete Jimenez int ssl_err;
377f5b1c8a1SJohn Marino int i;
378f5b1c8a1SJohn Marino
379*de0e0e4dSAntonio Huete Jimenez if (!ssl_security_cert(ctx, ssl, x, 1, &ssl_err)) {
380*de0e0e4dSAntonio Huete Jimenez SSLerrorx(ssl_err);
381*de0e0e4dSAntonio Huete Jimenez return (0);
382*de0e0e4dSAntonio Huete Jimenez }
383*de0e0e4dSAntonio Huete Jimenez
384*de0e0e4dSAntonio Huete Jimenez if ((c = ssl_get0_cert(ctx, ssl)) == NULL)
385*de0e0e4dSAntonio Huete Jimenez return (0);
386*de0e0e4dSAntonio Huete Jimenez
387f5b1c8a1SJohn Marino pkey = X509_get_pubkey(x);
388f5b1c8a1SJohn Marino if (pkey == NULL) {
38972c33676SMaxim Ag SSLerrorx(SSL_R_X509_LIB);
390f5b1c8a1SJohn Marino return (0);
391f5b1c8a1SJohn Marino }
392f5b1c8a1SJohn Marino
393*de0e0e4dSAntonio Huete Jimenez i = ssl_cert_type(pkey);
394f5b1c8a1SJohn Marino if (i < 0) {
39572c33676SMaxim Ag SSLerrorx(SSL_R_UNKNOWN_CERTIFICATE_TYPE);
396f5b1c8a1SJohn Marino EVP_PKEY_free(pkey);
397f5b1c8a1SJohn Marino return (0);
398f5b1c8a1SJohn Marino }
399f5b1c8a1SJohn Marino
400f5b1c8a1SJohn Marino if (c->pkeys[i].privatekey != NULL) {
401*de0e0e4dSAntonio Huete Jimenez EVP_PKEY *priv_key = c->pkeys[i].privatekey;
402*de0e0e4dSAntonio Huete Jimenez
403*de0e0e4dSAntonio Huete Jimenez EVP_PKEY_copy_parameters(pkey, priv_key);
404f5b1c8a1SJohn Marino ERR_clear_error();
405f5b1c8a1SJohn Marino
406f5b1c8a1SJohn Marino /*
407f5b1c8a1SJohn Marino * Don't check the public/private key, this is mostly
408f5b1c8a1SJohn Marino * for smart cards.
409f5b1c8a1SJohn Marino */
410*de0e0e4dSAntonio Huete Jimenez if (EVP_PKEY_id(priv_key) != EVP_PKEY_RSA ||
411*de0e0e4dSAntonio Huete Jimenez !(RSA_flags(EVP_PKEY_get0_RSA(priv_key)) & RSA_METHOD_FLAG_NO_CHECK)) {
412*de0e0e4dSAntonio Huete Jimenez if (!X509_check_private_key(x, priv_key)) {
413f5b1c8a1SJohn Marino /*
414f5b1c8a1SJohn Marino * don't fail for a cert/key mismatch, just free
415*de0e0e4dSAntonio Huete Jimenez * current private key (when switching to a
416*de0e0e4dSAntonio Huete Jimenez * different cert & key, first this function
417*de0e0e4dSAntonio Huete Jimenez * should be used, then ssl_set_pkey.
418f5b1c8a1SJohn Marino */
419f5b1c8a1SJohn Marino EVP_PKEY_free(c->pkeys[i].privatekey);
420f5b1c8a1SJohn Marino c->pkeys[i].privatekey = NULL;
421f5b1c8a1SJohn Marino ERR_clear_error();
422f5b1c8a1SJohn Marino }
423f5b1c8a1SJohn Marino }
424*de0e0e4dSAntonio Huete Jimenez }
425f5b1c8a1SJohn Marino
426f5b1c8a1SJohn Marino EVP_PKEY_free(pkey);
427f5b1c8a1SJohn Marino
428f5b1c8a1SJohn Marino X509_free(c->pkeys[i].x509);
429*de0e0e4dSAntonio Huete Jimenez X509_up_ref(x);
430f5b1c8a1SJohn Marino c->pkeys[i].x509 = x;
431f5b1c8a1SJohn Marino c->key = &(c->pkeys[i]);
432f5b1c8a1SJohn Marino
433f5b1c8a1SJohn Marino c->valid = 0;
434f5b1c8a1SJohn Marino return (1);
435f5b1c8a1SJohn Marino }
436f5b1c8a1SJohn Marino
437f5b1c8a1SJohn Marino int
SSL_CTX_use_certificate_file(SSL_CTX * ctx,const char * file,int type)438f5b1c8a1SJohn Marino SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
439f5b1c8a1SJohn Marino {
440f5b1c8a1SJohn Marino int j;
441f5b1c8a1SJohn Marino BIO *in;
442f5b1c8a1SJohn Marino int ret = 0;
443f5b1c8a1SJohn Marino X509 *x = NULL;
444f5b1c8a1SJohn Marino
445*de0e0e4dSAntonio Huete Jimenez in = BIO_new(BIO_s_file());
446f5b1c8a1SJohn Marino if (in == NULL) {
44772c33676SMaxim Ag SSLerrorx(ERR_R_BUF_LIB);
448f5b1c8a1SJohn Marino goto end;
449f5b1c8a1SJohn Marino }
450f5b1c8a1SJohn Marino
451f5b1c8a1SJohn Marino if (BIO_read_filename(in, file) <= 0) {
45272c33676SMaxim Ag SSLerrorx(ERR_R_SYS_LIB);
453f5b1c8a1SJohn Marino goto end;
454f5b1c8a1SJohn Marino }
455f5b1c8a1SJohn Marino if (type == SSL_FILETYPE_ASN1) {
456f5b1c8a1SJohn Marino j = ERR_R_ASN1_LIB;
457f5b1c8a1SJohn Marino x = d2i_X509_bio(in, NULL);
458f5b1c8a1SJohn Marino } else if (type == SSL_FILETYPE_PEM) {
459f5b1c8a1SJohn Marino j = ERR_R_PEM_LIB;
460f5b1c8a1SJohn Marino x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
461f5b1c8a1SJohn Marino ctx->default_passwd_callback_userdata);
462f5b1c8a1SJohn Marino } else {
46372c33676SMaxim Ag SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
464f5b1c8a1SJohn Marino goto end;
465f5b1c8a1SJohn Marino }
466f5b1c8a1SJohn Marino
467f5b1c8a1SJohn Marino if (x == NULL) {
46872c33676SMaxim Ag SSLerrorx(j);
469f5b1c8a1SJohn Marino goto end;
470f5b1c8a1SJohn Marino }
471f5b1c8a1SJohn Marino
472f5b1c8a1SJohn Marino ret = SSL_CTX_use_certificate(ctx, x);
473f5b1c8a1SJohn Marino end:
474f5b1c8a1SJohn Marino X509_free(x);
475f5b1c8a1SJohn Marino BIO_free(in);
476f5b1c8a1SJohn Marino return (ret);
477f5b1c8a1SJohn Marino }
478f5b1c8a1SJohn Marino
479f5b1c8a1SJohn Marino int
SSL_CTX_use_certificate_ASN1(SSL_CTX * ctx,int len,const unsigned char * d)480f5b1c8a1SJohn Marino SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
481f5b1c8a1SJohn Marino {
482f5b1c8a1SJohn Marino X509 *x;
483f5b1c8a1SJohn Marino int ret;
484f5b1c8a1SJohn Marino
485f5b1c8a1SJohn Marino x = d2i_X509(NULL, &d, (long)len);
486f5b1c8a1SJohn Marino if (x == NULL) {
48772c33676SMaxim Ag SSLerrorx(ERR_R_ASN1_LIB);
488f5b1c8a1SJohn Marino return (0);
489f5b1c8a1SJohn Marino }
490f5b1c8a1SJohn Marino
491f5b1c8a1SJohn Marino ret = SSL_CTX_use_certificate(ctx, x);
492f5b1c8a1SJohn Marino X509_free(x);
493f5b1c8a1SJohn Marino return (ret);
494f5b1c8a1SJohn Marino }
495f5b1c8a1SJohn Marino
496f5b1c8a1SJohn Marino int
SSL_CTX_use_RSAPrivateKey(SSL_CTX * ctx,RSA * rsa)497f5b1c8a1SJohn Marino SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
498f5b1c8a1SJohn Marino {
499f5b1c8a1SJohn Marino int ret;
500f5b1c8a1SJohn Marino EVP_PKEY *pkey;
501f5b1c8a1SJohn Marino
502f5b1c8a1SJohn Marino if (rsa == NULL) {
50372c33676SMaxim Ag SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
504f5b1c8a1SJohn Marino return (0);
505f5b1c8a1SJohn Marino }
506f5b1c8a1SJohn Marino if ((pkey = EVP_PKEY_new()) == NULL) {
50772c33676SMaxim Ag SSLerrorx(ERR_R_EVP_LIB);
508f5b1c8a1SJohn Marino return (0);
509f5b1c8a1SJohn Marino }
510f5b1c8a1SJohn Marino
511f5b1c8a1SJohn Marino RSA_up_ref(rsa);
512f5b1c8a1SJohn Marino EVP_PKEY_assign_RSA(pkey, rsa);
513f5b1c8a1SJohn Marino
514*de0e0e4dSAntonio Huete Jimenez ret = ssl_set_pkey(ctx, NULL, pkey);
515f5b1c8a1SJohn Marino EVP_PKEY_free(pkey);
516f5b1c8a1SJohn Marino return (ret);
517f5b1c8a1SJohn Marino }
518f5b1c8a1SJohn Marino
519f5b1c8a1SJohn Marino int
SSL_CTX_use_RSAPrivateKey_file(SSL_CTX * ctx,const char * file,int type)520f5b1c8a1SJohn Marino SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
521f5b1c8a1SJohn Marino {
522f5b1c8a1SJohn Marino int j, ret = 0;
523f5b1c8a1SJohn Marino BIO *in;
524f5b1c8a1SJohn Marino RSA *rsa = NULL;
525f5b1c8a1SJohn Marino
526*de0e0e4dSAntonio Huete Jimenez in = BIO_new(BIO_s_file());
527f5b1c8a1SJohn Marino if (in == NULL) {
52872c33676SMaxim Ag SSLerrorx(ERR_R_BUF_LIB);
529f5b1c8a1SJohn Marino goto end;
530f5b1c8a1SJohn Marino }
531f5b1c8a1SJohn Marino
532f5b1c8a1SJohn Marino if (BIO_read_filename(in, file) <= 0) {
53372c33676SMaxim Ag SSLerrorx(ERR_R_SYS_LIB);
534f5b1c8a1SJohn Marino goto end;
535f5b1c8a1SJohn Marino }
536f5b1c8a1SJohn Marino if (type == SSL_FILETYPE_ASN1) {
537f5b1c8a1SJohn Marino j = ERR_R_ASN1_LIB;
538f5b1c8a1SJohn Marino rsa = d2i_RSAPrivateKey_bio(in, NULL);
539f5b1c8a1SJohn Marino } else if (type == SSL_FILETYPE_PEM) {
540f5b1c8a1SJohn Marino j = ERR_R_PEM_LIB;
541f5b1c8a1SJohn Marino rsa = PEM_read_bio_RSAPrivateKey(in, NULL,
542f5b1c8a1SJohn Marino ctx->default_passwd_callback,
543f5b1c8a1SJohn Marino ctx->default_passwd_callback_userdata);
544f5b1c8a1SJohn Marino } else {
54572c33676SMaxim Ag SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
546f5b1c8a1SJohn Marino goto end;
547f5b1c8a1SJohn Marino }
548f5b1c8a1SJohn Marino if (rsa == NULL) {
54972c33676SMaxim Ag SSLerrorx(j);
550f5b1c8a1SJohn Marino goto end;
551f5b1c8a1SJohn Marino }
552f5b1c8a1SJohn Marino ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
553f5b1c8a1SJohn Marino RSA_free(rsa);
554f5b1c8a1SJohn Marino end:
555f5b1c8a1SJohn Marino BIO_free(in);
556f5b1c8a1SJohn Marino return (ret);
557f5b1c8a1SJohn Marino }
558f5b1c8a1SJohn Marino
559f5b1c8a1SJohn Marino int
SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX * ctx,const unsigned char * d,long len)560f5b1c8a1SJohn Marino SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
561f5b1c8a1SJohn Marino {
562f5b1c8a1SJohn Marino int ret;
563f5b1c8a1SJohn Marino RSA *rsa;
564f5b1c8a1SJohn Marino
56572c33676SMaxim Ag if ((rsa = d2i_RSAPrivateKey(NULL, &d, (long)len)) == NULL) {
56672c33676SMaxim Ag SSLerrorx(ERR_R_ASN1_LIB);
567f5b1c8a1SJohn Marino return (0);
568f5b1c8a1SJohn Marino }
569f5b1c8a1SJohn Marino
570f5b1c8a1SJohn Marino ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
571f5b1c8a1SJohn Marino RSA_free(rsa);
572f5b1c8a1SJohn Marino return (ret);
573f5b1c8a1SJohn Marino }
574f5b1c8a1SJohn Marino
575f5b1c8a1SJohn Marino int
SSL_CTX_use_PrivateKey(SSL_CTX * ctx,EVP_PKEY * pkey)576f5b1c8a1SJohn Marino SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
577f5b1c8a1SJohn Marino {
578f5b1c8a1SJohn Marino if (pkey == NULL) {
57972c33676SMaxim Ag SSLerrorx(ERR_R_PASSED_NULL_PARAMETER);
580f5b1c8a1SJohn Marino return (0);
581f5b1c8a1SJohn Marino }
582*de0e0e4dSAntonio Huete Jimenez return ssl_set_pkey(ctx, NULL, pkey);
583f5b1c8a1SJohn Marino }
584f5b1c8a1SJohn Marino
585f5b1c8a1SJohn Marino int
SSL_CTX_use_PrivateKey_file(SSL_CTX * ctx,const char * file,int type)586f5b1c8a1SJohn Marino SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
587f5b1c8a1SJohn Marino {
588f5b1c8a1SJohn Marino int j, ret = 0;
589f5b1c8a1SJohn Marino BIO *in;
590f5b1c8a1SJohn Marino EVP_PKEY *pkey = NULL;
591f5b1c8a1SJohn Marino
592*de0e0e4dSAntonio Huete Jimenez in = BIO_new(BIO_s_file());
593f5b1c8a1SJohn Marino if (in == NULL) {
59472c33676SMaxim Ag SSLerrorx(ERR_R_BUF_LIB);
595f5b1c8a1SJohn Marino goto end;
596f5b1c8a1SJohn Marino }
597f5b1c8a1SJohn Marino
598f5b1c8a1SJohn Marino if (BIO_read_filename(in, file) <= 0) {
59972c33676SMaxim Ag SSLerrorx(ERR_R_SYS_LIB);
600f5b1c8a1SJohn Marino goto end;
601f5b1c8a1SJohn Marino }
602f5b1c8a1SJohn Marino if (type == SSL_FILETYPE_PEM) {
603f5b1c8a1SJohn Marino j = ERR_R_PEM_LIB;
604f5b1c8a1SJohn Marino pkey = PEM_read_bio_PrivateKey(in, NULL,
605f5b1c8a1SJohn Marino ctx->default_passwd_callback,
606f5b1c8a1SJohn Marino ctx->default_passwd_callback_userdata);
607f5b1c8a1SJohn Marino } else if (type == SSL_FILETYPE_ASN1) {
608f5b1c8a1SJohn Marino j = ERR_R_ASN1_LIB;
609f5b1c8a1SJohn Marino pkey = d2i_PrivateKey_bio(in, NULL);
610f5b1c8a1SJohn Marino } else {
61172c33676SMaxim Ag SSLerrorx(SSL_R_BAD_SSL_FILETYPE);
612f5b1c8a1SJohn Marino goto end;
613f5b1c8a1SJohn Marino }
614f5b1c8a1SJohn Marino if (pkey == NULL) {
61572c33676SMaxim Ag SSLerrorx(j);
616f5b1c8a1SJohn Marino goto end;
617f5b1c8a1SJohn Marino }
618f5b1c8a1SJohn Marino ret = SSL_CTX_use_PrivateKey(ctx, pkey);
619f5b1c8a1SJohn Marino EVP_PKEY_free(pkey);
620f5b1c8a1SJohn Marino end:
621f5b1c8a1SJohn Marino BIO_free(in);
622f5b1c8a1SJohn Marino return (ret);
623f5b1c8a1SJohn Marino }
624f5b1c8a1SJohn Marino
625f5b1c8a1SJohn Marino int
SSL_CTX_use_PrivateKey_ASN1(int type,SSL_CTX * ctx,const unsigned char * d,long len)626f5b1c8a1SJohn Marino SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
627f5b1c8a1SJohn Marino long len)
628f5b1c8a1SJohn Marino {
629f5b1c8a1SJohn Marino int ret;
630f5b1c8a1SJohn Marino EVP_PKEY *pkey;
631f5b1c8a1SJohn Marino
63272c33676SMaxim Ag if ((pkey = d2i_PrivateKey(type, NULL, &d, (long)len)) == NULL) {
63372c33676SMaxim Ag SSLerrorx(ERR_R_ASN1_LIB);
634f5b1c8a1SJohn Marino return (0);
635f5b1c8a1SJohn Marino }
636f5b1c8a1SJohn Marino
637f5b1c8a1SJohn Marino ret = SSL_CTX_use_PrivateKey(ctx, pkey);
638f5b1c8a1SJohn Marino EVP_PKEY_free(pkey);
639f5b1c8a1SJohn Marino return (ret);
640f5b1c8a1SJohn Marino }
641f5b1c8a1SJohn Marino
642f5b1c8a1SJohn Marino
643f5b1c8a1SJohn Marino /*
644f5b1c8a1SJohn Marino * Read a bio that contains our certificate in "PEM" format,
645f5b1c8a1SJohn Marino * possibly followed by a sequence of CA certificates that should be
646f5b1c8a1SJohn Marino * sent to the peer in the Certificate message.
647f5b1c8a1SJohn Marino */
648f5b1c8a1SJohn Marino static int
ssl_use_certificate_chain_bio(SSL_CTX * ctx,SSL * ssl,BIO * in)649*de0e0e4dSAntonio Huete Jimenez ssl_use_certificate_chain_bio(SSL_CTX *ctx, SSL *ssl, BIO *in)
650f5b1c8a1SJohn Marino {
651*de0e0e4dSAntonio Huete Jimenez pem_password_cb *passwd_cb;
652*de0e0e4dSAntonio Huete Jimenez void *passwd_arg;
65372c33676SMaxim Ag X509 *ca, *x = NULL;
654f5b1c8a1SJohn Marino unsigned long err;
65572c33676SMaxim Ag int ret = 0;
656f5b1c8a1SJohn Marino
657*de0e0e4dSAntonio Huete Jimenez if (!ssl_get_password_cb_and_arg(ctx, ssl, &passwd_cb, &passwd_arg))
658*de0e0e4dSAntonio Huete Jimenez goto err;
659*de0e0e4dSAntonio Huete Jimenez
660*de0e0e4dSAntonio Huete Jimenez if ((x = PEM_read_bio_X509_AUX(in, NULL, passwd_cb, passwd_arg)) ==
661*de0e0e4dSAntonio Huete Jimenez NULL) {
66272c33676SMaxim Ag SSLerrorx(ERR_R_PEM_LIB);
66372c33676SMaxim Ag goto err;
664f5b1c8a1SJohn Marino }
665f5b1c8a1SJohn Marino
666*de0e0e4dSAntonio Huete Jimenez if (!ssl_set_cert(ctx, ssl, x))
66772c33676SMaxim Ag goto err;
66872c33676SMaxim Ag
669*de0e0e4dSAntonio Huete Jimenez if (!ssl_cert_set0_chain(ctx, ssl, NULL))
67072c33676SMaxim Ag goto err;
67172c33676SMaxim Ag
67272c33676SMaxim Ag /* Process any additional CA certificates. */
673*de0e0e4dSAntonio Huete Jimenez while ((ca = PEM_read_bio_X509(in, NULL, passwd_cb, passwd_arg)) !=
674*de0e0e4dSAntonio Huete Jimenez NULL) {
675*de0e0e4dSAntonio Huete Jimenez if (!ssl_cert_add0_chain_cert(ctx, ssl, ca)) {
676f5b1c8a1SJohn Marino X509_free(ca);
67772c33676SMaxim Ag goto err;
678f5b1c8a1SJohn Marino }
679f5b1c8a1SJohn Marino }
680f5b1c8a1SJohn Marino
681f5b1c8a1SJohn Marino /* When the while loop ends, it's usually just EOF. */
682f5b1c8a1SJohn Marino err = ERR_peek_last_error();
683f5b1c8a1SJohn Marino if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
68472c33676SMaxim Ag ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
685f5b1c8a1SJohn Marino ERR_clear_error();
68672c33676SMaxim Ag ret = 1;
687f5b1c8a1SJohn Marino }
688f5b1c8a1SJohn Marino
68972c33676SMaxim Ag err:
690f5b1c8a1SJohn Marino X509_free(x);
69172c33676SMaxim Ag
692f5b1c8a1SJohn Marino return (ret);
693f5b1c8a1SJohn Marino }
694f5b1c8a1SJohn Marino
695f5b1c8a1SJohn Marino int
ssl_use_certificate_chain_file(SSL_CTX * ctx,SSL * ssl,const char * file)696*de0e0e4dSAntonio Huete Jimenez ssl_use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
697f5b1c8a1SJohn Marino {
698f5b1c8a1SJohn Marino BIO *in;
699f5b1c8a1SJohn Marino int ret = 0;
700f5b1c8a1SJohn Marino
701*de0e0e4dSAntonio Huete Jimenez in = BIO_new(BIO_s_file());
702f5b1c8a1SJohn Marino if (in == NULL) {
70372c33676SMaxim Ag SSLerrorx(ERR_R_BUF_LIB);
704f5b1c8a1SJohn Marino goto end;
705f5b1c8a1SJohn Marino }
706f5b1c8a1SJohn Marino
707f5b1c8a1SJohn Marino if (BIO_read_filename(in, file) <= 0) {
70872c33676SMaxim Ag SSLerrorx(ERR_R_SYS_LIB);
709f5b1c8a1SJohn Marino goto end;
710f5b1c8a1SJohn Marino }
711f5b1c8a1SJohn Marino
712*de0e0e4dSAntonio Huete Jimenez ret = ssl_use_certificate_chain_bio(ctx, ssl, in);
713f5b1c8a1SJohn Marino
714f5b1c8a1SJohn Marino end:
715f5b1c8a1SJohn Marino BIO_free(in);
716f5b1c8a1SJohn Marino return (ret);
717f5b1c8a1SJohn Marino }
718f5b1c8a1SJohn Marino
719f5b1c8a1SJohn Marino int
SSL_CTX_use_certificate_chain_file(SSL_CTX * ctx,const char * file)720*de0e0e4dSAntonio Huete Jimenez SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
721*de0e0e4dSAntonio Huete Jimenez {
722*de0e0e4dSAntonio Huete Jimenez return ssl_use_certificate_chain_file(ctx, NULL, file);
723*de0e0e4dSAntonio Huete Jimenez }
724*de0e0e4dSAntonio Huete Jimenez
725*de0e0e4dSAntonio Huete Jimenez int
SSL_use_certificate_chain_file(SSL * ssl,const char * file)726*de0e0e4dSAntonio Huete Jimenez SSL_use_certificate_chain_file(SSL *ssl, const char *file)
727*de0e0e4dSAntonio Huete Jimenez {
728*de0e0e4dSAntonio Huete Jimenez return ssl_use_certificate_chain_file(NULL, ssl, file);
729*de0e0e4dSAntonio Huete Jimenez }
730*de0e0e4dSAntonio Huete Jimenez
731*de0e0e4dSAntonio Huete Jimenez int
SSL_CTX_use_certificate_chain_mem(SSL_CTX * ctx,void * buf,int len)732f5b1c8a1SJohn Marino SSL_CTX_use_certificate_chain_mem(SSL_CTX *ctx, void *buf, int len)
733f5b1c8a1SJohn Marino {
734f5b1c8a1SJohn Marino BIO *in;
735f5b1c8a1SJohn Marino int ret = 0;
736f5b1c8a1SJohn Marino
737f5b1c8a1SJohn Marino in = BIO_new_mem_buf(buf, len);
738f5b1c8a1SJohn Marino if (in == NULL) {
73972c33676SMaxim Ag SSLerrorx(ERR_R_BUF_LIB);
740f5b1c8a1SJohn Marino goto end;
741f5b1c8a1SJohn Marino }
742f5b1c8a1SJohn Marino
743*de0e0e4dSAntonio Huete Jimenez ret = ssl_use_certificate_chain_bio(ctx, NULL, in);
744f5b1c8a1SJohn Marino
745f5b1c8a1SJohn Marino end:
746f5b1c8a1SJohn Marino BIO_free(in);
747f5b1c8a1SJohn Marino return (ret);
748f5b1c8a1SJohn Marino }
749