talloc_set_destructor(ssn, _tls_session_free);
ssn->ctx = conf->ctx;
+ ssn->mtu = conf->fragment_size;
SSL_CTX_set_mode(ssn->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_AUTO_RETRY);
SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_SSN, (void *)ssn);
SSL_set_fd(ssn->ssl, fd);
ret = SSL_connect(ssn->ssl);
+
+ if (ret < 0) {
+ switch (SSL_get_error(ssn->ssl, ret)) {
+ default:
+ break;
+
+
+
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ ssn->connected = false;
+ return ssn;
+ }
+ }
+
if (ret <= 0) {
tls_error_io_log(NULL, ssn, ret, "Failed in " STRINGIFY(__FUNCTION__) " (SSL_connect)");
talloc_free(ssn);
return NULL;
}
- ssn->mtu = conf->fragment_size;
-
+ ssn->connected = true;
return ssn;
}
static void session_close(tls_session_t *ssn)
{
- SSL_set_quiet_shutdown(ssn->ssl, 1);
- SSL_shutdown(ssn->ssl);
-
if (ssn->ssl) {
+ SSL_set_quiet_shutdown(ssn->ssl, 1);
+ SSL_shutdown(ssn->ssl);
+
SSL_free(ssn->ssl);
ssn->ssl = NULL;
}
t.tm_year -= 1900;
}
- if ((end - p) < 10) {
+ if ((end - p) < 4) {
fr_strerror_printf("ASN1 string too short, expected 10 additional bytes, got %zu bytes",
end - p);
return -1;
t.tm_mon += (*(p++) - '0') - 1; // -1 since January is 0 not 1.
t.tm_mday = (*(p++) - '0') * 10;
t.tm_mday += (*(p++) - '0');
+
+ if ((end - p) < 2) goto done;
t.tm_hour = (*(p++) - '0') * 10;
t.tm_hour += (*(p++) - '0');
+
+ if ((end - p) < 2) goto done;
t.tm_min = (*(p++) - '0') * 10;
t.tm_min += (*(p++) - '0');
+
+ if ((end - p) < 2) goto done;
t.tm_sec = (*(p++) - '0') * 10;
t.tm_sec += (*(p++) - '0');
/* Apparently OpenSSL converts all timestamps to UTC? Maybe? */
+done:
*out = timegm(&t);
return 0;
}
/* not safe to un-persist a session w/o VPs */
RWDEBUG("Failed loading persisted VPs for session %s", buffer);
SSL_SESSION_free(sess);
+ sess = NULL;
goto error;
}
time_t expires;
if (ocsp_asn1time_to_epoch(&expires, vp->vp_strvalue) < 0) {
- RDEBUG2("Failed getting certificate expiration, removing cache entry for session %s", buffer);
+ RDEBUG2("Failed getting certificate expiration, removing cache entry for session %s - %s", buffer, fr_strerror());
SSL_SESSION_free(sess);
+ sess = NULL;
goto error;
}
if (expires <= request->timestamp) {
RDEBUG2("Certificate has expired, removing cache entry for session %s", buffer);
SSL_SESSION_free(sess);
+ sess = NULL;
goto error;
}
char cn_str[1024];
char buf[64];
X509 *client_cert;
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
const STACK_OF(X509_EXTENSION) *ext_list;
#else
STACK_OF(X509_EXTENSION) *ext_list;
}
}
if (names != NULL)
- sk_GENERAL_NAME_free(names);
+ GENERAL_NAMES_free(names);
}
/*
}
if (lookup == 0) {
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
ext_list = X509_get0_extensions(client_cert);
#else
X509_CINF *client_inf;
true, true, EXEC_TIMEOUT) != 0) {
AUTH(LOG_PREFIX ": Certificate CN (%s) fails external verification!", common_name);
my_ok = 0;
- } else {
+
+ } else if (request) {
RDEBUG("Client certificate CN %s passed external validation", common_name);
}
SSL_CTX_set_verify_depth(ctx, conf->verify_depth);
}
+#ifndef LIBRESSL_VERSION_NUMBER
/* Load randomness */
if (conf->random_file) {
if (!(RAND_load_file(conf->random_file, 1024*10))) {
return NULL;
}
}
+#endif
/*
* Set the cipher list if we were told to
return 0;
}
-static fr_tls_server_conf_t *tls_server_conf_alloc(TALLOC_CTX *ctx)
+fr_tls_server_conf_t *tls_server_conf_alloc(TALLOC_CTX *ctx)
{
fr_tls_server_conf_t *conf;
* Only check for certificate things if we don't have a
* PSK query.
*/
+#ifdef PSK_MAX_IDENTITY_LEN
if (conf->psk_identity) {
if (conf->private_key_file) {
WARN(LOG_PREFIX ": Ignoring private key file due to psk_identity being used");
WARN(LOG_PREFIX ": Ignoring certificate file due to psk_identity being used");
}
- } else {
+ } else
+#endif
+ {
if (!conf->private_key_file) {
ERROR(LOG_PREFIX ": TLS Server requires a private key file");
goto error;