const char *prompt_info;
} PW_CB_DATA;
+#ifndef OPENSSL_NO_ENGINE
/* The openssl configuration file and engines can be loaded only once */
static CONF *ssl_config = NULL;
static ENGINE *cert_engine = NULL;
static ENGINE *pkey_engine = NULL;
+#endif
/* TLSv1.3 do we have a session ticket ? */
static int have_session_ticket = 0;
-int ssl_verify_callback(int, X509_STORE_CTX *);
+int ssl_verify_callback(int, X509_STORE_CTX *);
void ssl_msg_callback(int write_p, int version, int ct, const void *buf,
size_t len, SSL * ssl, void *arg);
int ssl_new_session_cb(SSL *s, SSL_SESSION *sess);
}
dbglog( "Loading OpenSSL built-ins" );
+#ifndef OPENSSL_NO_ENGINE
ENGINE_load_builtin_engines();
+#endif
OPENSSL_load_builtin_modules();
dbglog( "Loading OpenSSL configured modules" );
return config;
}
+#ifndef OPENSSL_NO_ENGINE
ENGINE *eaptls_ssl_load_engine( char *engine_name )
{
ENGINE *e = NULL;
return e;
}
-
+#endif
/*
SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
char *certfile, char *peer_certfile, char *privkeyfile)
{
+#ifndef OPENSSL_NO_ENGINE
char *cert_engine_name = NULL;
char *cert_identifier = NULL;
char *pkey_engine_name = NULL;
char *pkey_identifier = NULL;
+#endif
SSL_CTX *ctx;
SSL *ssl;
X509_STORE *certstore;
SSL_library_init();
SSL_load_error_strings();
+#ifndef OPENSSL_NO_ENGINE
/* load the openssl config file only once and load it before triggering
the loading of a global openssl config file via SSL_CTX_new()
*/
if (!ssl_config)
ssl_config = eaptls_ssl_load_config();
+#endif
ctx = SSL_CTX_new(TLS_method());
goto fail;
}
+#ifndef OPENSSL_NO_ENGINE
/* if the certificate filename is of the form engine:id. e.g.
pkcs11:12345
then we try to load and use this engine.
else
pkey_engine = eaptls_ssl_load_engine( pkey_engine_name );
}
+#endif
SSL_CTX_set_default_passwd_cb (ctx, password_callback);
if (init_server)
SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile));
+#ifndef OPENSSL_NO_ENGINE
if (cert_engine)
{
struct
}
}
else
+#endif
{
if (!SSL_CTX_use_certificate_chain_file(ctx, certfile))
{
}
SSL_free(ssl);
+#ifndef OPENSSL_NO_ENGINE
if (pkey_engine)
{
EVP_PKEY *pkey = NULL;
}
}
else
+#endif
{
if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM))
{
if (!esp->es_server.ea_session)
fatal("Allocation error");
ets = esp->es_server.ea_session;
+ ets->client = 0;
if (!esp->es_server.ea_peer) {
error("EAP-TLS: Error: client name not set (BUG)");
if (!esp->es_client.ea_session)
fatal("Allocation error");
ets = esp->es_client.ea_session;
+ ets->client = 1;
/*
* If available, copy server name in ets; it will be used in cert
int err, depth;
SSL *ssl;
struct eaptls_session *ets;
+ char *ptr1 = NULL, *ptr2 = NULL;
peer_cert = X509_STORE_CTX_get_current_cert(ctx);
err = X509_STORE_CTX_get_error(ctx);
if (!depth)
{
- /* This is the peer certificate */
-
- X509_NAME_oneline(X509_get_subject_name(peer_cert),
- subject, 256);
+ /* Verify certificate based on certificate type and extended key usage */
+ if (tls_verify_key_usage) {
+ int purpose = ets->client ? X509_PURPOSE_SSL_SERVER : X509_PURPOSE_SSL_CLIENT ;
+ if (X509_check_purpose(peer_cert, purpose, 0) == 0) {
+ error("Certificate verification error: nsCertType mismatch");
+ return 0;
+ }
- X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
- NID_commonName, cn_str, 256);
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+ int flags = ets->client ? XKU_SSL_SERVER : XKU_SSL_CLIENT;
+ if (!(X509_get_extended_key_usage(peer_cert) & flags)) {
+ error("Certificate verification error: invalid extended key usage");
+ return 0;
+ }
+#endif
+ info("Certificate key usage: OK");
+ }
/*
* If acting as client and the name of the server wasn't specified
* explicitely, we can't verify the server authenticity
*/
- if (!ets->peer[0]) {
- warn("Peer name not specified: no check");
+ if (!tls_verify_method)
+ tls_verify_method = TLS_VERIFY_NONE;
+
+ if (!ets->peer[0] || !strcmp(TLS_VERIFY_NONE, tls_verify_method)) {
+ warn("Certificate verication disabled or no peer name was specified");
return ok;
}
- /*
- * Check the CN
- */
- if (strcmp(cn_str, ets->peer)) {
- error
- ("Certificate verification error: CN (%s) != peer_name (%s)",
- cn_str, ets->peer);
+ /* This is the peer certificate */
+ X509_NAME_oneline(X509_get_subject_name(peer_cert),
+ subject, 256);
+
+ X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
+ NID_commonName, cn_str, 256);
+
+ /* Verify based on subject name */
+ ptr1 = ets->peer;
+ if (!strcmp(TLS_VERIFY_SUBJECT, tls_verify_method)) {
+ ptr2 = subject;
+ }
+
+ /* Verify based on common name (default) */
+ if (strlen(tls_verify_method) == 0 ||
+ !strcmp(TLS_VERIFY_NAME, tls_verify_method)) {
+ ptr2 = cn_str;
+ }
+
+ /* Match the suffix of common name */
+ if (!strcmp(TLS_VERIFY_SUFFIX, tls_verify_method)) {
+ int len = strlen(ptr1);
+ int off = strlen(cn_str) - len;
+ ptr2 = cn_str;
+ if (off > 0) {
+ ptr2 = cn_str + off;
+ }
+ }
+
+ if (strcmp(ptr1, ptr2)) {
+ error("Certificate verification error: CN (%s) != %s", ptr1, ptr2);
return 0;
}
- warn("Certificate CN: %s , peer name %s", cn_str, ets->peer);
+ info("Certificate CN: %s, peer name %s", cn_str, ets->peer);
/*
* If a peer certificate file was specified, here we check it