handle CertificateFile more cleanly
properly distribute the certificates between the SSL context's trust store and our host cert list. as a drive-by, clean up some nasty type casts at the cost of including a second OpenSSL header into socket.h.
This commit is contained in:
parent
cfaa4848dd
commit
481c12a8b3
|
@ -172,6 +172,7 @@ int ATTR_PRINTFLIKE(2, 0) nfvasprintf( char **str, const char *fmt, va_list va )
|
||||||
int ATTR_PRINTFLIKE(2, 3) nfasprintf( char **str, const char *fmt, ... );
|
int ATTR_PRINTFLIKE(2, 3) nfasprintf( char **str, const char *fmt, ... );
|
||||||
int ATTR_PRINTFLIKE(3, 4) nfsnprintf( char *buf, int blen, const char *fmt, ... );
|
int ATTR_PRINTFLIKE(3, 4) nfsnprintf( char *buf, int blen, const char *fmt, ... );
|
||||||
void ATTR_NORETURN oob( void );
|
void ATTR_NORETURN oob( void );
|
||||||
|
void ATTR_NORETURN oom( void );
|
||||||
|
|
||||||
char *expand_strdup( const char *s );
|
char *expand_strdup( const char *s );
|
||||||
|
|
||||||
|
|
36
src/socket.c
36
src/socket.c
|
@ -194,7 +194,6 @@ verify_cert_host( const server_conf_t *conf, conn_t *sock )
|
||||||
int i;
|
int i;
|
||||||
long err;
|
long err;
|
||||||
X509 *cert;
|
X509 *cert;
|
||||||
STACK_OF(X509_OBJECT) *trusted;
|
|
||||||
|
|
||||||
cert = SSL_get_peer_certificate( sock->ssl );
|
cert = SSL_get_peer_certificate( sock->ssl );
|
||||||
if (!cert) {
|
if (!cert) {
|
||||||
|
@ -202,9 +201,8 @@ verify_cert_host( const server_conf_t *conf, conn_t *sock )
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
trusted = (STACK_OF(X509_OBJECT) *)sock->conf->trusted_certs;
|
for (i = 0; i < sk_X509_num( sock->conf->trusted_certs ); i++) {
|
||||||
for (i = 0; i < sk_X509_OBJECT_num( trusted ); i++) {
|
if (!X509_cmp( cert, sk_X509_value( sock->conf->trusted_certs, i ) )) {
|
||||||
if (!X509_cmp( cert, X509_OBJECT_get0_X509( sk_X509_OBJECT_value( trusted, i ) ) )) {
|
|
||||||
X509_free( cert );
|
X509_free( cert );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -273,11 +271,33 @@ DIAG_POP
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf->cert_file && !SSL_CTX_load_verify_locations( mconf->SSLContext, conf->cert_file, NULL )) {
|
if (!(mconf->trusted_certs = sk_X509_new_null()))
|
||||||
print_ssl_errors( "loading certificate file '%s'", conf->cert_file );
|
oom();
|
||||||
return 0;
|
if (conf->cert_file) {
|
||||||
|
X509_STORE *store;
|
||||||
|
if (!(store = X509_STORE_new()))
|
||||||
|
oom();
|
||||||
|
if (!X509_STORE_load_locations( store, conf->cert_file, NULL )) {
|
||||||
|
print_ssl_errors( "loading certificate file '%s'", conf->cert_file );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects( store );
|
||||||
|
for (int i = 0; i < sk_X509_OBJECT_num( objs ); i++) {
|
||||||
|
X509 *cert = X509_OBJECT_get0_X509( sk_X509_OBJECT_value( objs, i ) );
|
||||||
|
if (cert) {
|
||||||
|
if (X509_check_ca( cert )) {
|
||||||
|
if (!X509_STORE_add_cert( SSL_CTX_get_cert_store( mconf->SSLContext ), cert ))
|
||||||
|
oom();
|
||||||
|
} else {
|
||||||
|
X509_up_ref( cert ); // Locking failure assumed impossible
|
||||||
|
if (!sk_X509_push( mconf->trusted_certs, cert ))
|
||||||
|
oom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
X509_STORE_free( store );
|
||||||
}
|
}
|
||||||
mconf->trusted_certs = (_STACK *)sk_X509_OBJECT_dup( X509_STORE_get0_objects( SSL_CTX_get_cert_store( mconf->SSLContext ) ) );
|
|
||||||
if (mconf->system_certs && !SSL_CTX_set_default_verify_paths( mconf->SSLContext )) {
|
if (mconf->system_certs && !SSL_CTX_set_default_verify_paths( mconf->SSLContext )) {
|
||||||
ulong err;
|
ulong err;
|
||||||
while ((err = ERR_get_error()))
|
while ((err = ERR_get_error()))
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#ifdef HAVE_LIBSSL
|
#ifdef HAVE_LIBSSL
|
||||||
# include <openssl/ssl.h>
|
# include <openssl/ssl.h>
|
||||||
|
# include <openssl/x509.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TLSv1 = 4,
|
TLSv1 = 4,
|
||||||
|
@ -55,7 +56,7 @@ typedef struct {
|
||||||
|
|
||||||
/* these are actually variables and are leaked at the end */
|
/* these are actually variables and are leaked at the end */
|
||||||
char ssl_ctx_valid;
|
char ssl_ctx_valid;
|
||||||
_STACK *trusted_certs;
|
STACK_OF(X509) *trusted_certs;
|
||||||
SSL_CTX *SSLContext;
|
SSL_CTX *SSLContext;
|
||||||
#endif
|
#endif
|
||||||
} server_conf_t;
|
} server_conf_t;
|
||||||
|
|
|
@ -353,7 +353,7 @@ nfsnprintf( char *buf, int blen, const char *fmt, ... )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ATTR_NORETURN
|
void
|
||||||
oom( void )
|
oom( void )
|
||||||
{
|
{
|
||||||
fputs( "Fatal: Out of memory\n", stderr );
|
fputs( "Fatal: Out of memory\n", stderr );
|
||||||
|
|
Loading…
Reference in New Issue
Block a user