src/ssl_sock.c
int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s, char *sni_filter)
{
	BIO *in;
	X509 *x = NULL, *ca;
	int i, len, err;
	int ret = -1;
	int order = 0;
	X509_NAME *xname;
	char *str;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	STACK_OF(GENERAL_NAME) *names;
#endif

	in = BIO_new(BIO_s_file());
	if (in == NULL)
		goto end;

	if (BIO_read_filename(in, file) <= 0)
		goto end;

	x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
	if (x == NULL)
		goto end;

	if (sni_filter) {
		while (*sni_filter) {
			while (isspace(*sni_filter))
				sni_filter++;
			str = sni_filter;
			while (!isspace(*sni_filter) && *sni_filter)
				sni_filter++;
			len = sni_filter - str;
			order = ssl_sock_add_cert_sni(ctx, s, str, len, order);
		}
	}
	else {
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
		names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
		if (names) {
			for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
				GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
				if (name->type == GEN_DNS) {
					if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
						len = strlen(str);
						order = ssl_sock_add_cert_sni(ctx, s, str, len, order);
						OPENSSL_free(str);
					}
				}
			}
			sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
		}
#endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */
		xname = X509_get_subject_name(x);
		i = -1;
		while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
			X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
			if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
				len = strlen(str);
				order = ssl_sock_add_cert_sni(ctx, s, str, len, order);
				OPENSSL_free(str);
			}
		}
	}

	ret = 0; /* the caller must not free the SSL_CTX argument anymore */
	if (!SSL_CTX_use_certificate(ctx, x))
		goto end;

	if (ctx->extra_certs != NULL) {
		sk_X509_pop_free(ctx->extra_certs, X509_free);
		ctx->extra_certs = NULL;
	}

	while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
		if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
			X509_free(ca);
			goto end;
		}
	}

	err = ERR_get_error();
	if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
		/* we successfully reached the last cert in the file */
		ret = 1;
	}
	ERR_clear_error();

end:
	if (x)
		X509_free(x);

	if (in)
		BIO_free(in);

	return ret;
}
/* Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
 * an early error happens and the caller must call SSL_CTX_free() by itelf.
 */
Loads a certificate key and CA chain from a file. Returns 0 on error, -1 if
an early error happens and the caller must call SSL_CTX_free() by itelf.
Loads a certificate key and CA chain from a file . Returns 0 on error - 1 if an early error happens and the caller must call SSL_CTX_free () by itelf .
int ssl_sock_load_cert_chain_file(SSL_CTX *ctx, const char *file, struct bind_conf *s, char *sni_filter)
{
	BIO *in;
	X509 *x = NULL, *ca;
	int i, len, err;
	int ret = -1;
	int order = 0;
	X509_NAME *xname;
	char *str;
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	STACK_OF(GENERAL_NAME) *names;
#endif
	in = BIO_new(BIO_s_file());
	if (in == NULL)
		goto end;
	if (BIO_read_filename(in, file) <= 0)
		goto end;
	x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata);
	if (x == NULL)
		goto end;
	if (sni_filter) {
		while (*sni_filter) {
			while (isspace(*sni_filter))
				sni_filter++;
			str = sni_filter;
			while (!isspace(*sni_filter) && *sni_filter)
				sni_filter++;
			len = sni_filter - str;
			order = ssl_sock_add_cert_sni(ctx, s, str, len, order);
		}
	}
	else {
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
		names = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
		if (names) {
			for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
				GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
				if (name->type == GEN_DNS) {
					if (ASN1_STRING_to_UTF8((unsigned char **)&str, name->d.dNSName) >= 0) {
						len = strlen(str);
						order = ssl_sock_add_cert_sni(ctx, s, str, len, order);
						OPENSSL_free(str);
					}
				}
			}
			sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
		}
#endif 
		xname = X509_get_subject_name(x);
		i = -1;
		while ((i = X509_NAME_get_index_by_NID(xname, NID_commonName, i)) != -1) {
			X509_NAME_ENTRY *entry = X509_NAME_get_entry(xname, i);
			if (ASN1_STRING_to_UTF8((unsigned char **)&str, entry->value) >= 0) {
				len = strlen(str);
				order = ssl_sock_add_cert_sni(ctx, s, str, len, order);
				OPENSSL_free(str);
			}
		}
	}
	ret = 0; 
	if (!SSL_CTX_use_certificate(ctx, x))
		goto end;
	if (ctx->extra_certs != NULL) {
		sk_X509_pop_free(ctx->extra_certs, X509_free);
		ctx->extra_certs = NULL;
	}
	while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, ctx->default_passwd_callback_userdata))) {
		if (!SSL_CTX_add_extra_chain_cert(ctx, ca)) {
			X509_free(ca);
			goto end;
		}
	}
	err = ERR_get_error();
	if (!err || (ERR_GET_LIB(err) == ERR_LIB_PEM && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
		ret = 1;
	}
	ERR_clear_error();
end:
	if (x)
		X509_free(x);
	if (in)
		BIO_free(in);
	return ret;
}
int ssl_sock_load_cert_chain_file ( SSL_CTX * ctx , const char * file , struct bind_conf * s , char * sni_filter ) { BIO * in ; X509 * x = NULL , * ca ; int i , len , err ; int ret = -1 ; int order = 0 ; X509_NAME * xname ; char * str ; #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME STACK_OF ( GENERAL_NAME ) * names ; #endif in = BIO_new ( BIO_s_file ( ) ) ; if ( in == NULL ) goto end ; if ( BIO_read_filename ( in , file ) <= 0 ) goto end ; x = PEM_read_bio_X509_AUX ( in , NULL , ctx -> default_passwd_callback , ctx -> default_passwd_callback_userdata ) ; if ( x == NULL ) goto end ; if ( sni_filter ) { while ( * sni_filter ) { while ( isspace ( * sni_filter ) ) sni_filter ++ ; str = sni_filter ; while ( ! isspace ( * sni_filter ) && * sni_filter ) sni_filter ++ ; len = sni_filter - str ; order = ssl_sock_add_cert_sni ( ctx , s , str , len , order ) ; } } else { #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME names = X509_get_ext_d2i ( x , NID_subject_alt_name , NULL , NULL ) ; if ( names ) { for ( i = 0 ; i < sk_GENERAL_NAME_num ( names ) ; i ++ ) { GENERAL_NAME * name = sk_GENERAL_NAME_value ( names , i ) ; if ( name -> type == GEN_DNS ) { if ( ASN1_STRING_to_UTF8 ( ( unsigned char * * ) & str , name -> d . dNSName ) >= 0 ) { len = strlen ( str ) ; order = ssl_sock_add_cert_sni ( ctx , s , str , len , order ) ; OPENSSL_free ( str ) ; } } } sk_GENERAL_NAME_pop_free ( names , GENERAL_NAME_free ) ; } #endif xname = X509_get_subject_name ( x ) ; i = -1 ; while ( ( i = X509_NAME_get_index_by_NID ( xname , NID_commonName , i ) ) != -1 ) { X509_NAME_ENTRY * entry = X509_NAME_get_entry ( xname , i ) ; if ( ASN1_STRING_to_UTF8 ( ( unsigned char * * ) & str , entry -> value ) >= 0 ) { len = strlen ( str ) ; order = ssl_sock_add_cert_sni ( ctx , s , str , len , order ) ; OPENSSL_free ( str ) ; } } } ret = 0 ; if ( ! SSL_CTX_use_certificate ( ctx , x ) ) goto end ; if ( ctx -> extra_certs != NULL ) { sk_X509_pop_free ( ctx -> extra_certs , X509_free ) ; ctx -> extra_certs = NULL ; } while ( ( ca = PEM_read_bio_X509 ( in , NULL , ctx -> default_passwd_callback , ctx -> default_passwd_callback_userdata ) ) ) { if ( ! SSL_CTX_add_extra_chain_cert ( ctx , ca ) ) { X509_free ( ca ) ; goto end ; } } err = ERR_get_error ( ) ; if ( ! err || ( ERR_GET_LIB ( err ) == ERR_LIB_PEM && ERR_GET_REASON ( err ) == PEM_R_NO_START_LINE ) ) { ret = 1 ; } ERR_clear_error ( ) ; end : if ( x ) X509_free ( x ) ; if ( in ) BIO_free ( in ) ; return ret ; }
Loads a certificate key and CA chain from a file.
Loads a certificate key and CA chain from a file .
/* SSL_CTRL_SET_TLSEXT_HOSTNAME */ /* the caller must not free the SSL_CTX argument anymore */ /* we successfully reached the last cert in the file */