int tls_log_io_error(REQUEST *request, tls_session_t *session, int ret, char const *msg, ...)
CC_HINT(format (printf, 4, 5));
+#define tls_log_certificate_chain(_request, _chain, _cert) \
+ _tls_log_certificate_chain( __FILE__, __LINE__, _request, _chain, _cert)
+void _tls_log_certificate_chain(char const *file, int line,
+ REQUEST *request, STACK_OF(X509) *chain, X509 *cert);
/*
* tls/ocsp.c
*/
return 0;
}
-static void _tls_ctx_print_cert_line(int index, X509 *cert)
-{
- char subject[1024];
-
- X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject));
- subject[sizeof(subject) - 1] = '\0';
-
- DEBUG3("[%i] %s %s", index, tls_utils_x509_pkey_type(cert), subject);
-}
-
/** Create SSL context
*
* - Load the trusted CAs
ret = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_NEXT)) {
STACK_OF(X509) *our_chain;
X509 *our_cert;
- int i;
our_cert = SSL_CTX_get0_certificate(ctx);
goto error;
}
- for (i = sk_X509_num(our_chain); i > 0 ; i--) {
- _tls_ctx_print_cert_line(i, sk_X509_value(our_chain, i - 1));
- }
- _tls_ctx_print_cert_line(i, our_cert);
+ if (DEBUG_ENABLED3) tls_log_certificate_chain(NULL, our_chain, our_cert);
}
(void)SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST); /* Reset */
}
return ret;
}
+static void _tls_ctx_print_cert_line(char const *file, int line,
+ REQUEST *request, int index, X509 *cert)
+{
+ char subject[1024];
+
+ X509_NAME_oneline(X509_get_subject_name(cert), subject, sizeof(subject));
+ subject[sizeof(subject) - 1] = '\0';
+
+ if (request) {
+ log_request(L_DBG, fr_debug_lvl, request, file, line,
+ "[%i] %s %s", index, tls_utils_x509_pkey_type(cert), subject);
+ } else {
+ fr_log(LOG_DST, fr_debug_lvl, file, line,
+ "[%i] %s %s", index, tls_utils_x509_pkey_type(cert), subject);
+ }
+}
+
+/** Print out the current stack of certs
+ *
+ * @param[in] file File where this function is being called.
+ * @param[in] line Line where this function is being called.
+ * @param[in] request Current request, may be NULL.
+ * @param[in] chain The certificate chain.
+ * @param[in] cert The leaf certificate.
+ */
+void _tls_log_certificate_chain(char const *file, int line,
+ REQUEST *request, STACK_OF(X509) *chain, X509 *cert)
+{
+ int i;
+
+ for (i = sk_X509_num(chain); i > 0 ; i--) {
+ _tls_ctx_print_cert_line(file, line, request, i, sk_X509_value(chain, i - 1));
+ }
+ _tls_ctx_print_cert_line(file, line, request, i, cert);
+}
+
+
/** Print errors raised by OpenSSL I/O functions
*
* Drains the thread local OpenSSL error queue, and prints out errors
goto error;
}
- if ((X509_STORE_CTX_get1_issuer(&issuer_cert, server_store_ctx, cert) != 1) || !issuer_cert) {
- tls_log_error(request, "Can't get server certificate's issuer");
+ /*
+ * Print out the current chain in the certificate store
+ * to help with debugging issues where we can't find the
+ * server cert.
+ */
+ if (RDEBUG_ENABLED3) {
+ STACK_OF(X509) *chain;
+
+ RDEBUG3("Current SSL session cert store contents");
+ chain = X509_STORE_CTX_get_chain(server_store_ctx);
+ RINDENT();
+ tls_log_certificate_chain(request, chain, cert);
+ REXDENT();
+ }
+
+ ret = X509_STORE_CTX_get1_issuer(&issuer_cert, server_store_ctx, cert);
+ if (ret != 1) {
+ X509_NAME *subject;
+ X509_NAME *issuer = X509_get_issuer_name(cert);
+ char *subject_str;
+ char *issuer_str;
+
+ subject = X509_get_subject_name(cert);
+ if (!subject) {
+ tls_log_error(request, "Couldn't retrieve subject name of SSL session cert");
+ goto error;
+ }
+ MEM(subject_str = X509_NAME_oneline(subject, NULL, 0));
+
+ issuer = X509_get_issuer_name(cert);
+ if (!issuer) {
+ tls_log_error(request, "Couldn't retrieve issuer name of SSL session cert");
+ OPENSSL_free(subject_str);
+ goto error;
+ }
+ MEM(issuer_str = X509_NAME_oneline(issuer, NULL, 0));
+
+ switch (ret) {
+ case 0:
+ tls_log_error(request, "Issuer \"%s\" of \"%s\" not found in certificate store",
+ issuer_str, subject_str);
+ break;
+ default:
+ tls_log_error(request, "Error retrieving issuer \"%s\" of \"%s\" from certificate store",
+ issuer_str, subject_str);
+ break;
+ }
+
+ OPENSSL_free(subject_str);
+ OPENSSL_free(issuer_str);
goto error;
}
+ rad_assert(issuer_cert);
+
ret = tls_ocsp_check(request, ssl, server_store, issuer_cert, cert, conf, true);
switch (ret) {
default: