1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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.
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).
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.
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
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)"
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
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.] */
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>
69 static int ssl_set_cert(CERT *c, X509 *x509);
70 static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
71 int SSL_use_certificate(SSL *ssl, X509 *x)
75 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate, ERR_R_PASSED_NULL_PARAMETER);
78 if (!ssl_cert_inst(&ssl->cert))
80 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate, ERR_R_MALLOC_FAILURE);
83 return(ssl_set_cert(ssl->cert,x));
86 #ifndef OPENSSL_NO_STDIO
87 int SSL_use_certificate_file(SSL *ssl, const char *file, int type)
94 in=BIO_new(BIO_s_file());
97 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_BUF_LIB);
101 if (BIO_read_filename(in,file) <= 0)
103 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_SYS_LIB);
106 if (type == SSL_FILETYPE_ASN1)
108 reason_code =ERR_R_ASN1_LIB;
109 x=d2i_X509_bio(in,NULL);
111 else if (type == SSL_FILETYPE_PEM)
113 reason_code=ERR_R_PEM_LIB;
114 x=PEM_read_bio_X509(in,NULL,ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
118 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, SSL_R_BAD_SSL_FILETYPE);
124 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file,reason_code);
128 ret=SSL_use_certificate(ssl,x);
130 if (x != NULL) X509_free(x);
131 if (in != NULL) BIO_free(in);
136 int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len)
141 x=d2i_X509(NULL,&d,(long)len);
144 OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_ASN1, ERR_R_ASN1_LIB);
148 ret=SSL_use_certificate(ssl,x);
153 int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
160 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
163 if (!ssl_cert_inst(&ssl->cert))
165 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_MALLOC_FAILURE);
168 if ((pkey=EVP_PKEY_new()) == NULL)
170 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_EVP_LIB);
175 EVP_PKEY_assign_RSA(pkey,rsa);
177 ret=ssl_set_pkey(ssl->cert,pkey);
182 static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey)
186 i=ssl_cert_type(NULL,pkey);
189 OPENSSL_PUT_ERROR(SSL, ssl_set_pkey, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
193 if (c->pkeys[i].x509 != NULL)
196 pktmp = X509_get_pubkey(c->pkeys[i].x509);
197 EVP_PKEY_copy_parameters(pktmp,pkey);
198 EVP_PKEY_free(pktmp);
201 /* Sanity-check that the private key and the certificate match,
202 * unless the key is opaque (in case of, say, a smartcard). */
203 if (!EVP_PKEY_is_opaque(pkey) &&
204 !X509_check_private_key(c->pkeys[i].x509,pkey))
206 X509_free(c->pkeys[i].x509);
207 c->pkeys[i].x509 = NULL;
212 if (c->pkeys[i].privatekey != NULL)
213 EVP_PKEY_free(c->pkeys[i].privatekey);
214 c->pkeys[i].privatekey = EVP_PKEY_dup(pkey);
215 c->key = &(c->pkeys[i]);
221 #ifndef OPENSSL_NO_STDIO
222 int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type)
224 int reason_code,ret=0;
228 in=BIO_new(BIO_s_file());
231 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_BUF_LIB);
235 if (BIO_read_filename(in,file) <= 0)
237 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_SYS_LIB);
240 if (type == SSL_FILETYPE_ASN1)
242 reason_code=ERR_R_ASN1_LIB;
243 rsa=d2i_RSAPrivateKey_bio(in,NULL);
245 else if (type == SSL_FILETYPE_PEM)
247 reason_code=ERR_R_PEM_LIB;
248 rsa=PEM_read_bio_RSAPrivateKey(in,NULL,
249 ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
253 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
258 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file,reason_code);
261 ret=SSL_use_RSAPrivateKey(ssl,rsa);
264 if (in != NULL) BIO_free(in);
269 int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len)
272 const unsigned char *p;
276 if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL)
278 OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
282 ret=SSL_use_RSAPrivateKey(ssl,rsa);
287 int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey)
293 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER);
296 if (!ssl_cert_inst(&ssl->cert))
298 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey, ERR_R_MALLOC_FAILURE);
301 ret=ssl_set_pkey(ssl->cert,pkey);
305 #ifndef OPENSSL_NO_STDIO
306 int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type)
308 int reason_code,ret=0;
312 in=BIO_new(BIO_s_file());
315 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_BUF_LIB);
319 if (BIO_read_filename(in,file) <= 0)
321 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_SYS_LIB);
324 if (type == SSL_FILETYPE_PEM)
326 reason_code=ERR_R_PEM_LIB;
327 pkey=PEM_read_bio_PrivateKey(in,NULL,
328 ssl->ctx->default_passwd_callback,ssl->ctx->default_passwd_callback_userdata);
330 else if (type == SSL_FILETYPE_ASN1)
332 reason_code = ERR_R_ASN1_LIB;
333 pkey = d2i_PrivateKey_bio(in,NULL);
337 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
342 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file,reason_code);
345 ret=SSL_use_PrivateKey(ssl,pkey);
348 if (in != NULL) BIO_free(in);
353 int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len)
356 const unsigned char *p;
360 if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL)
362 OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_ASN1, ERR_R_ASN1_LIB);
366 ret=SSL_use_PrivateKey(ssl,pkey);
371 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x)
375 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate, ERR_R_PASSED_NULL_PARAMETER);
378 if (!ssl_cert_inst(&ctx->cert))
380 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate, ERR_R_MALLOC_FAILURE);
383 return(ssl_set_cert(ctx->cert, x));
386 static int ssl_set_cert(CERT *c, X509 *x)
391 pkey=X509_get_pubkey(x);
394 OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_X509_LIB);
398 i=ssl_cert_type(x,pkey);
401 OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
406 if (c->pkeys[i].privatekey != NULL)
408 EVP_PKEY_copy_parameters(pkey,c->pkeys[i].privatekey);
411 /* Sanity-check that the private key and the certificate match,
412 * unless the key is opaque (in case of, say, a smartcard). */
413 if (!EVP_PKEY_is_opaque(c->pkeys[i].privatekey) &&
414 !X509_check_private_key(x,c->pkeys[i].privatekey))
416 /* don't fail for a cert/key mismatch, just free
417 * current private key (when switching to a different
418 * cert & key, first this function should be used,
419 * then ssl_set_pkey */
420 EVP_PKEY_free(c->pkeys[i].privatekey);
421 c->pkeys[i].privatekey=NULL;
422 /* clear error queue */
429 if (c->pkeys[i].x509 != NULL)
430 X509_free(c->pkeys[i].x509);
431 c->pkeys[i].x509 = X509_up_ref(x);
432 c->key= &(c->pkeys[i]);
438 #ifndef OPENSSL_NO_STDIO
439 int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type)
446 in=BIO_new(BIO_s_file());
449 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_BUF_LIB);
453 if (BIO_read_filename(in,file) <= 0)
455 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_SYS_LIB);
458 if (type == SSL_FILETYPE_ASN1)
460 reason_code=ERR_R_ASN1_LIB;
461 x=d2i_X509_bio(in,NULL);
463 else if (type == SSL_FILETYPE_PEM)
465 reason_code=ERR_R_PEM_LIB;
466 x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
470 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, SSL_R_BAD_SSL_FILETYPE);
476 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file,reason_code);
480 ret=SSL_CTX_use_certificate(ctx,x);
482 if (x != NULL) X509_free(x);
483 if (in != NULL) BIO_free(in);
488 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d)
493 x=d2i_X509(NULL,&d,(long)len);
496 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_ASN1, ERR_R_ASN1_LIB);
500 ret=SSL_CTX_use_certificate(ctx,x);
505 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
512 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
515 if (!ssl_cert_inst(&ctx->cert))
517 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, ERR_R_MALLOC_FAILURE);
520 if ((pkey=EVP_PKEY_new()) == NULL)
522 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, ERR_R_EVP_LIB);
527 EVP_PKEY_assign_RSA(pkey,rsa);
529 ret=ssl_set_pkey(ctx->cert, pkey);
534 #ifndef OPENSSL_NO_STDIO
535 int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type)
537 int reason_code,ret=0;
541 in=BIO_new(BIO_s_file());
544 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_BUF_LIB);
548 if (BIO_read_filename(in,file) <= 0)
550 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_SYS_LIB);
553 if (type == SSL_FILETYPE_ASN1)
555 reason_code=ERR_R_ASN1_LIB;
556 rsa=d2i_RSAPrivateKey_bio(in,NULL);
558 else if (type == SSL_FILETYPE_PEM)
560 reason_code=ERR_R_PEM_LIB;
561 rsa=PEM_read_bio_RSAPrivateKey(in,NULL,
562 ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
566 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
571 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file,reason_code);
574 ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa);
577 if (in != NULL) BIO_free(in);
582 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len)
585 const unsigned char *p;
589 if ((rsa=d2i_RSAPrivateKey(NULL,&p,(long)len)) == NULL)
591 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
595 ret=SSL_CTX_use_RSAPrivateKey(ctx,rsa);
600 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey)
604 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER);
607 if (!ssl_cert_inst(&ctx->cert))
609 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey, ERR_R_MALLOC_FAILURE);
612 return(ssl_set_pkey(ctx->cert,pkey));
615 #ifndef OPENSSL_NO_STDIO
616 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type)
618 int reason_code,ret=0;
622 in=BIO_new(BIO_s_file());
625 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_BUF_LIB);
629 if (BIO_read_filename(in,file) <= 0)
631 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_SYS_LIB);
634 if (type == SSL_FILETYPE_PEM)
636 reason_code=ERR_R_PEM_LIB;
637 pkey=PEM_read_bio_PrivateKey(in,NULL,
638 ctx->default_passwd_callback,ctx->default_passwd_callback_userdata);
640 else if (type == SSL_FILETYPE_ASN1)
642 reason_code = ERR_R_ASN1_LIB;
643 pkey = d2i_PrivateKey_bio(in,NULL);
647 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
652 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file,reason_code);
655 ret=SSL_CTX_use_PrivateKey(ctx,pkey);
658 if (in != NULL) BIO_free(in);
663 int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
667 const unsigned char *p;
671 if ((pkey=d2i_PrivateKey(type,NULL,&p,(long)len)) == NULL)
673 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_ASN1, ERR_R_ASN1_LIB);
677 ret=SSL_CTX_use_PrivateKey(ctx,pkey);
683 #ifndef OPENSSL_NO_STDIO
684 /* Read a file that contains our certificate in "PEM" format,
685 * possibly followed by a sequence of CA certificates that should be
686 * sent to the peer in the Certificate message.
688 int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file)
694 ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
696 in = BIO_new(BIO_s_file());
699 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_BUF_LIB);
703 if (BIO_read_filename(in,file) <= 0)
705 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_SYS_LIB);
709 x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback,
710 ctx->default_passwd_callback_userdata);
713 OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_PEM_LIB);
717 ret = SSL_CTX_use_certificate(ctx, x);
719 if (ERR_peek_error() != 0)
720 ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */
723 /* If we could set up our certificate, now proceed to
724 * the CA certificates.
730 SSL_CTX_clear_chain_certs(ctx);
732 while ((ca = PEM_read_bio_X509(in, NULL,
733 ctx->default_passwd_callback,
734 ctx->default_passwd_callback_userdata))
737 r = SSL_CTX_add0_chain_cert(ctx, ca);
744 /* Note that we must not free r if it was successfully
745 * added to the chain (while we must free the main
746 * certificate, since its reference count is increased
747 * by SSL_CTX_use_certificate). */
749 /* When the while loop ends, it's usually just EOF. */
750 err = ERR_peek_last_error();
751 if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
754 ret = 0; /* some real error */
758 if (x != NULL) X509_free(x);
759 if (in != NULL) BIO_free(in);
762 #endif /* OPENSSL_NO_STDIO */