1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57 #include <stdio.h>
58
59 #include <openssl/bio.h>
60 #include <openssl/err.h>
61 #include <openssl/evp.h>
62 #include <openssl/mem.h>
63 #include <openssl/obj.h>
64 #include <openssl/pem.h>
65 #include <openssl/x509.h>
66
67 #include "internal.h"
68
69 static int ssl_set_cert(CERT *c, X509 *x509);
70 static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
71
SSL_use_certificate(SSL * ssl,X509 * x)72 int SSL_use_certificate(SSL *ssl, X509 *x) {
73 if (x == NULL) {
74 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate, ERR_R_PASSED_NULL_PARAMETER);
75 return 0;
76 }
77 return ssl_set_cert(ssl->cert, x);
78 }
79
SSL_use_certificate_file(SSL * ssl,const char * file,int type)80 int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
81 int reason_code;
82 BIO *in;
83 int ret = 0;
84 X509 *x = NULL;
85
86 in = BIO_new(BIO_s_file());
87 if (in == NULL) {
88 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_BUF_LIB);
89 goto end;
90 }
91
92 if (BIO_read_filename(in, file) <= 0) {
93 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_SYS_LIB);
94 goto end;
95 }
96
97 if (type == SSL_FILETYPE_ASN1) {
98 reason_code = ERR_R_ASN1_LIB;
99 x = d2i_X509_bio(in, NULL);
100 } else if (type == SSL_FILETYPE_PEM) {
101 reason_code = ERR_R_PEM_LIB;
102 x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
103 ssl->ctx->default_passwd_callback_userdata);
104 } else {
105 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, SSL_R_BAD_SSL_FILETYPE);
106 goto end;
107 }
108
109 if (x == NULL) {
110 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, reason_code);
111 goto end;
112 }
113
114 ret = SSL_use_certificate(ssl, x);
115
116 end:
117 X509_free(x);
118 BIO_free(in);
119
120 return ret;
121 }
122
SSL_use_certificate_ASN1(SSL * ssl,const uint8_t * d,int len)123 int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d, int len) {
124 X509 *x;
125 int ret;
126
127 x = d2i_X509(NULL, &d, (long)len);
128 if (x == NULL) {
129 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_ASN1, ERR_R_ASN1_LIB);
130 return 0;
131 }
132
133 ret = SSL_use_certificate(ssl, x);
134 X509_free(x);
135 return ret;
136 }
137
SSL_use_RSAPrivateKey(SSL * ssl,RSA * rsa)138 int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
139 EVP_PKEY *pkey;
140 int ret;
141
142 if (rsa == NULL) {
143 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
144 return 0;
145 }
146
147 pkey = EVP_PKEY_new();
148 if (pkey == NULL) {
149 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_EVP_LIB);
150 return 0;
151 }
152
153 RSA_up_ref(rsa);
154 EVP_PKEY_assign_RSA(pkey, rsa);
155
156 ret = ssl_set_pkey(ssl->cert, pkey);
157 EVP_PKEY_free(pkey);
158
159 return ret;
160 }
161
ssl_set_pkey(CERT * c,EVP_PKEY * pkey)162 static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) {
163 int i;
164
165 i = ssl_cert_type(pkey);
166 if (i < 0) {
167 OPENSSL_PUT_ERROR(SSL, ssl_set_pkey, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
168 return 0;
169 }
170
171 if (c->pkeys[i].x509 != NULL) {
172 /* Sanity-check that the private key and the certificate match, unless the
173 * key is opaque (in case of, say, a smartcard). */
174 if (!EVP_PKEY_is_opaque(pkey) &&
175 !X509_check_private_key(c->pkeys[i].x509, pkey)) {
176 X509_free(c->pkeys[i].x509);
177 c->pkeys[i].x509 = NULL;
178 return 0;
179 }
180 }
181
182 EVP_PKEY_free(c->pkeys[i].privatekey);
183 c->pkeys[i].privatekey = EVP_PKEY_up_ref(pkey);
184 c->key = &(c->pkeys[i]);
185
186 return 1;
187 }
188
SSL_use_RSAPrivateKey_file(SSL * ssl,const char * file,int type)189 int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) {
190 int reason_code, ret = 0;
191 BIO *in;
192 RSA *rsa = NULL;
193
194 in = BIO_new(BIO_s_file());
195 if (in == NULL) {
196 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_BUF_LIB);
197 goto end;
198 }
199
200 if (BIO_read_filename(in, file) <= 0) {
201 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_SYS_LIB);
202 goto end;
203 }
204
205 if (type == SSL_FILETYPE_ASN1) {
206 reason_code = ERR_R_ASN1_LIB;
207 rsa = d2i_RSAPrivateKey_bio(in, NULL);
208 } else if (type == SSL_FILETYPE_PEM) {
209 reason_code = ERR_R_PEM_LIB;
210 rsa =
211 PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
212 ssl->ctx->default_passwd_callback_userdata);
213 } else {
214 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
215 goto end;
216 }
217
218 if (rsa == NULL) {
219 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, reason_code);
220 goto end;
221 }
222 ret = SSL_use_RSAPrivateKey(ssl, rsa);
223 RSA_free(rsa);
224
225 end:
226 BIO_free(in);
227 return ret;
228 }
229
SSL_use_RSAPrivateKey_ASN1(SSL * ssl,uint8_t * d,long len)230 int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, uint8_t *d, long len) {
231 int ret;
232 const uint8_t *p;
233 RSA *rsa;
234
235 p = d;
236 rsa = d2i_RSAPrivateKey(NULL, &p, (long)len);
237 if (rsa == NULL) {
238 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
239 return 0;
240 }
241
242 ret = SSL_use_RSAPrivateKey(ssl, rsa);
243 RSA_free(rsa);
244 return ret;
245 }
246
SSL_use_PrivateKey(SSL * ssl,EVP_PKEY * pkey)247 int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
248 int ret;
249
250 if (pkey == NULL) {
251 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER);
252 return 0;
253 }
254
255 ret = ssl_set_pkey(ssl->cert, pkey);
256 return ret;
257 }
258
SSL_use_PrivateKey_file(SSL * ssl,const char * file,int type)259 int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) {
260 int reason_code, ret = 0;
261 BIO *in;
262 EVP_PKEY *pkey = NULL;
263
264 in = BIO_new(BIO_s_file());
265 if (in == NULL) {
266 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_BUF_LIB);
267 goto end;
268 }
269
270 if (BIO_read_filename(in, file) <= 0) {
271 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_SYS_LIB);
272 goto end;
273 }
274
275 if (type == SSL_FILETYPE_PEM) {
276 reason_code = ERR_R_PEM_LIB;
277 pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
278 ssl->ctx->default_passwd_callback_userdata);
279 } else if (type == SSL_FILETYPE_ASN1) {
280 reason_code = ERR_R_ASN1_LIB;
281 pkey = d2i_PrivateKey_bio(in, NULL);
282 } else {
283 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
284 goto end;
285 }
286
287 if (pkey == NULL) {
288 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, reason_code);
289 goto end;
290 }
291 ret = SSL_use_PrivateKey(ssl, pkey);
292 EVP_PKEY_free(pkey);
293
294 end:
295 BIO_free(in);
296 return ret;
297 }
298
SSL_use_PrivateKey_ASN1(int type,SSL * ssl,const uint8_t * d,long len)299 int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) {
300 int ret;
301 const uint8_t *p;
302 EVP_PKEY *pkey;
303
304 p = d;
305 pkey = d2i_PrivateKey(type, NULL, &p, (long)len);
306 if (pkey == NULL) {
307 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_ASN1, ERR_R_ASN1_LIB);
308 return 0;
309 }
310
311 ret = SSL_use_PrivateKey(ssl, pkey);
312 EVP_PKEY_free(pkey);
313 return ret;
314 }
315
SSL_CTX_use_certificate(SSL_CTX * ctx,X509 * x)316 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
317 if (x == NULL) {
318 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate,
319 ERR_R_PASSED_NULL_PARAMETER);
320 return 0;
321 }
322
323 return ssl_set_cert(ctx->cert, x);
324 }
325
ssl_set_cert(CERT * c,X509 * x)326 static int ssl_set_cert(CERT *c, X509 *x) {
327 EVP_PKEY *pkey;
328 int i;
329
330 pkey = X509_get_pubkey(x);
331 if (pkey == NULL) {
332 OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_X509_LIB);
333 return 0;
334 }
335
336 i = ssl_cert_type(pkey);
337 if (i < 0) {
338 OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
339 EVP_PKEY_free(pkey);
340 return 0;
341 }
342
343 if (c->pkeys[i].privatekey != NULL) {
344 /* Sanity-check that the private key and the certificate match, unless the
345 * key is opaque (in case of, say, a smartcard). */
346 if (!EVP_PKEY_is_opaque(c->pkeys[i].privatekey) &&
347 !X509_check_private_key(x, c->pkeys[i].privatekey)) {
348 /* don't fail for a cert/key mismatch, just free current private key
349 * (when switching to a different cert & key, first this function should
350 * be used, then ssl_set_pkey */
351 EVP_PKEY_free(c->pkeys[i].privatekey);
352 c->pkeys[i].privatekey = NULL;
353 /* clear error queue */
354 ERR_clear_error();
355 }
356 }
357
358 EVP_PKEY_free(pkey);
359
360 X509_free(c->pkeys[i].x509);
361 c->pkeys[i].x509 = X509_up_ref(x);
362 c->key = &(c->pkeys[i]);
363
364 return 1;
365 }
366
SSL_CTX_use_certificate_file(SSL_CTX * ctx,const char * file,int type)367 int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) {
368 int reason_code;
369 BIO *in;
370 int ret = 0;
371 X509 *x = NULL;
372
373 in = BIO_new(BIO_s_file());
374 if (in == NULL) {
375 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_BUF_LIB);
376 goto end;
377 }
378
379 if (BIO_read_filename(in, file) <= 0) {
380 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_SYS_LIB);
381 goto end;
382 }
383
384 if (type == SSL_FILETYPE_ASN1) {
385 reason_code = ERR_R_ASN1_LIB;
386 x = d2i_X509_bio(in, NULL);
387 } else if (type == SSL_FILETYPE_PEM) {
388 reason_code = ERR_R_PEM_LIB;
389 x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
390 ctx->default_passwd_callback_userdata);
391 } else {
392 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file,
393 SSL_R_BAD_SSL_FILETYPE);
394 goto end;
395 }
396
397 if (x == NULL) {
398 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, reason_code);
399 goto end;
400 }
401
402 ret = SSL_CTX_use_certificate(ctx, x);
403
404 end:
405 X509_free(x);
406 BIO_free(in);
407 return ret;
408 }
409
SSL_CTX_use_certificate_ASN1(SSL_CTX * ctx,int len,const uint8_t * d)410 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const uint8_t *d) {
411 X509 *x;
412 int ret;
413
414 x = d2i_X509(NULL, &d, (long)len);
415 if (x == NULL) {
416 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_ASN1, ERR_R_ASN1_LIB);
417 return 0;
418 }
419
420 ret = SSL_CTX_use_certificate(ctx, x);
421 X509_free(x);
422 return ret;
423 }
424
SSL_CTX_use_RSAPrivateKey(SSL_CTX * ctx,RSA * rsa)425 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
426 int ret;
427 EVP_PKEY *pkey;
428
429 if (rsa == NULL) {
430 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey,
431 ERR_R_PASSED_NULL_PARAMETER);
432 return 0;
433 }
434
435 pkey = EVP_PKEY_new();
436 if (pkey == NULL) {
437 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, ERR_R_EVP_LIB);
438 return 0;
439 }
440
441 RSA_up_ref(rsa);
442 EVP_PKEY_assign_RSA(pkey, rsa);
443
444 ret = ssl_set_pkey(ctx->cert, pkey);
445 EVP_PKEY_free(pkey);
446 return ret;
447 }
448
SSL_CTX_use_RSAPrivateKey_file(SSL_CTX * ctx,const char * file,int type)449 int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
450 int reason_code, ret = 0;
451 BIO *in;
452 RSA *rsa = NULL;
453
454 in = BIO_new(BIO_s_file());
455 if (in == NULL) {
456 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_BUF_LIB);
457 goto end;
458 }
459
460 if (BIO_read_filename(in, file) <= 0) {
461 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_SYS_LIB);
462 goto end;
463 }
464
465 if (type == SSL_FILETYPE_ASN1) {
466 reason_code = ERR_R_ASN1_LIB;
467 rsa = d2i_RSAPrivateKey_bio(in, NULL);
468 } else if (type == SSL_FILETYPE_PEM) {
469 reason_code = ERR_R_PEM_LIB;
470 rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback,
471 ctx->default_passwd_callback_userdata);
472 } else {
473 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file,
474 SSL_R_BAD_SSL_FILETYPE);
475 goto end;
476 }
477
478 if (rsa == NULL) {
479 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, reason_code);
480 goto end;
481 }
482 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
483 RSA_free(rsa);
484
485 end:
486 BIO_free(in);
487 return ret;
488 }
489
SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX * ctx,const uint8_t * d,long len)490 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *d, long len) {
491 int ret;
492 const uint8_t *p;
493 RSA *rsa;
494
495 p = d;
496 rsa = d2i_RSAPrivateKey(NULL, &p, (long)len);
497 if (rsa == NULL) {
498 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
499 return 0;
500 }
501
502 ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
503 RSA_free(rsa);
504 return ret;
505 }
506
SSL_CTX_use_PrivateKey(SSL_CTX * ctx,EVP_PKEY * pkey)507 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
508 if (pkey == NULL) {
509 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER);
510 return 0;
511 }
512
513 return ssl_set_pkey(ctx->cert, pkey);
514 }
515
SSL_CTX_use_PrivateKey_file(SSL_CTX * ctx,const char * file,int type)516 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
517 int reason_code, ret = 0;
518 BIO *in;
519 EVP_PKEY *pkey = NULL;
520
521 in = BIO_new(BIO_s_file());
522 if (in == NULL) {
523 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_BUF_LIB);
524 goto end;
525 }
526
527 if (BIO_read_filename(in, file) <= 0) {
528 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_SYS_LIB);
529 goto end;
530 }
531
532 if (type == SSL_FILETYPE_PEM) {
533 reason_code = ERR_R_PEM_LIB;
534 pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback,
535 ctx->default_passwd_callback_userdata);
536 } else if (type == SSL_FILETYPE_ASN1) {
537 reason_code = ERR_R_ASN1_LIB;
538 pkey = d2i_PrivateKey_bio(in, NULL);
539 } else {
540 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
541 goto end;
542 }
543
544 if (pkey == NULL) {
545 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, reason_code);
546 goto end;
547 }
548 ret = SSL_CTX_use_PrivateKey(ctx, pkey);
549 EVP_PKEY_free(pkey);
550
551 end:
552 BIO_free(in);
553 return ret;
554 }
555
SSL_CTX_use_PrivateKey_ASN1(int type,SSL_CTX * ctx,const uint8_t * d,long len)556 int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d,
557 long len) {
558 int ret;
559 const uint8_t *p;
560 EVP_PKEY *pkey;
561
562 p = d;
563 pkey = d2i_PrivateKey(type, NULL, &p, (long)len);
564 if (pkey == NULL) {
565 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_ASN1, ERR_R_ASN1_LIB);
566 return 0;
567 }
568
569 ret = SSL_CTX_use_PrivateKey(ctx, pkey);
570 EVP_PKEY_free(pkey);
571 return ret;
572 }
573
574
575 /* Read a file that contains our certificate in "PEM" format, possibly followed
576 * by a sequence of CA certificates that should be sent to the peer in the
577 * Certificate message. */
SSL_CTX_use_certificate_chain_file(SSL_CTX * ctx,const char * file)578 int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) {
579 BIO *in;
580 int ret = 0;
581 X509 *x = NULL;
582
583 ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
584
585 in = BIO_new(BIO_s_file());
586 if (in == NULL) {
587 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_BUF_LIB);
588 goto end;
589 }
590
591 if (BIO_read_filename(in, file) <= 0) {
592 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_SYS_LIB);
593 goto end;
594 }
595
596 x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
597 ctx->default_passwd_callback_userdata);
598 if (x == NULL) {
599 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_PEM_LIB);
600 goto end;
601 }
602
603 ret = SSL_CTX_use_certificate(ctx, x);
604
605 if (ERR_peek_error() != 0) {
606 ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */
607 }
608
609 if (ret) {
610 /* If we could set up our certificate, now proceed to the CA
611 * certificates. */
612 X509 *ca;
613 int r;
614 uint32_t err;
615
616 SSL_CTX_clear_chain_certs(ctx);
617
618 while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
619 ctx->default_passwd_callback_userdata)) !=
620 NULL) {
621 r = SSL_CTX_add0_chain_cert(ctx, ca);
622 if (!r) {
623 X509_free(ca);
624 ret = 0;
625 goto end;
626 }
627 /* Note that we must not free r if it was successfully added to the chain
628 * (while we must free the main certificate, since its reference count is
629 * increased by SSL_CTX_use_certificate). */
630 }
631
632 /* When the while loop ends, it's usually just EOF. */
633 err = ERR_peek_last_error();
634 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
635 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
636 ERR_clear_error();
637 } else {
638 ret = 0; /* some real error */
639 }
640 }
641
642 end:
643 X509_free(x);
644 BIO_free(in);
645 return ret;
646 }
647