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