/* Read a file that contains our certificate in "PEM" format, * possibly followed by a sequence of CA certificates that should be * sent to the peer in the Certificate message. */ int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) { BIO *in; int ret=0; X509 *x=NULL; ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */ in = BIO_new(BIO_s_file_internal()); if (in == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in,file) <= 0) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_SYS_LIB); goto end; } x=PEM_read_bio_X509_AUX(in,NULL,ctx->default_passwd_callback, ctx->default_passwd_callback_userdata); if (x == NULL) { SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE,ERR_R_PEM_LIB); goto end; } ret = SSL_CTX_use_certificate(ctx, x); if (ERR_peek_error() != 0) ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */ if (ret) { /* If we could set up our certificate, now proceed to * the CA certificates. */ X509 *ca; int r; unsigned long err; SSL_CTX_clear_chain_certs(ctx); while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata)) != NULL) { r = SSL_CTX_add0_chain_cert(ctx, ca); if (!r) { X509_free(ca); ret = 0; goto end; } /* Note that we must not free r if it was successfully * added to the chain (while we must free the main * certificate, since its reference count is increased * by SSL_CTX_use_certificate). */ } /* When the while loop ends, it's usually just EOF. */ err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) ERR_clear_error(); else ret = 0; /* some real error */ } end: if (x != NULL) X509_free(x); if (in != NULL) BIO_free(in); return(ret); }
/* * Read a file that contains our certificate in "PEM" format, possibly * followed by a sequence of CA certificates that should be sent to the peer * in the Certificate message. */ static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file) { BIO *in; int ret = 0; X509 *x = NULL; pem_password_cb *passwd_callback; void *passwd_callback_userdata; ERR_clear_error(); /* clear error stack for * SSL_CTX_use_certificate() */ if (ctx != NULL) { passwd_callback = ctx->default_passwd_callback; passwd_callback_userdata = ctx->default_passwd_callback_userdata; } else { passwd_callback = ssl->default_passwd_callback; passwd_callback_userdata = ssl->default_passwd_callback_userdata; } in = BIO_new(BIO_s_file()); if (in == NULL) { SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); goto end; } if (BIO_read_filename(in, file) <= 0) { SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); goto end; } x = PEM_read_bio_X509_AUX(in, NULL, passwd_callback, passwd_callback_userdata); if (x == NULL) { SSLerr(SSL_F_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); goto end; } if (ctx) ret = SSL_CTX_use_certificate(ctx, x); else ret = SSL_use_certificate(ssl, x); if (ERR_peek_error() != 0) ret = 0; /* Key/certificate mismatch doesn't imply * ret==0 ... */ if (ret) { /* * If we could set up our certificate, now proceed to the CA * certificates. */ X509 *ca; int r; unsigned long err; if (ctx) r = SSL_CTX_clear_chain_certs(ctx); else r = SSL_clear_chain_certs(ssl); if (r == 0) { ret = 0; goto end; } while ((ca = PEM_read_bio_X509(in, NULL, passwd_callback, passwd_callback_userdata)) != NULL) { if (ctx) r = SSL_CTX_add0_chain_cert(ctx, ca); else r = SSL_add0_chain_cert(ssl, ca); /* * Note that we must not free ca if it was successfully added to * the chain (while we must free the main certificate, since its * reference count is increased by SSL_CTX_use_certificate). */ if (!r) { X509_free(ca); ret = 0; goto end; } } /* When the while loop ends, it's usually just EOF. */ err = ERR_peek_last_error(); if (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) ERR_clear_error(); else ret = 0; /* some real error */ } end: X509_free(x); BIO_free(in); return (ret); }