+ cred = gnutls_auth_get_type(c->ssl_state.gnutls_session);
+ if (cred == GNUTLS_CRD_CERTIFICATE && connect) {
+ cert_seen = true;
+ int verify =
+ gnutls_certificate_verify_peers2(c->
+ ssl_state.gnutls_session,
+ &status);
+Log(LOG_ERR, "DEBUG: verify = %d", verify);
+ if (verify < 0) {
+ Log(LOG_ERR,
+ "gnutls_certificate_verify_peers2 failed: %s",
+ gnutls_strerror(verify));
+ goto done_cn_validation;
+ } else if (status) {
+ gnutls_datum_t out;
+
+ if (gnutls_certificate_verification_status_print
+ (status, gnutls_certificate_type_get(sess), &out,
+ 0) == GNUTLS_E_SUCCESS) {
+ Log(LOG_ERR,
+ "Certificate validation failed: %s",
+ out.data);
+ gnutls_free(out.data);
+ }
+ }
+Log(LOG_ERR, "DEBUG: status = %d", status);
+
+ gnutls_x509_crt_t cert;
+ unsigned cert_list_size;
+ const gnutls_datum_t *cert_list =
+ gnutls_certificate_get_peers(sess, &cert_list_size);
+ if (!cert_list || cert_list_size == 0) {
+ Log(LOG_ERR, "No certificates found");
+ goto done_cn_validation;
+ }
+ int err = gnutls_x509_crt_init(&cert);
+ if (err < 0) {
+ Log(LOG_ERR,
+ "Failed to initialize x509 certificate: %s",
+ gnutls_strerror(err));
+ goto done_cn_validation;
+ }
+ err = gnutls_x509_crt_import(cert, cert_list,
+ GNUTLS_X509_FMT_DER);
+ if (err < 0) {
+ Log(LOG_ERR, "Failed to parse the certificate: %s",
+ gnutls_strerror(err));
+ goto done_cn_validation;
+ }
+ err = gnutls_x509_crt_check_hostname(cert, c->host);
+ if (err == 0)
+ Log(LOG_ERR,
+ "Failed to verify the hostname, expected \"%s\"",
+ c->host);
+ else
+ cert_ok = verify == 0 && status == 0;
+
+ snprintf(msg, sizeof(msg), "%svalid peer certificate",
+ cert_ok ? "" : "in");
+ LogGnuTLS_CertInfo(cert_ok ? LOG_DEBUG : LOG_ERR, cert, msg);
+
+ gnutls_x509_crt_deinit(cert);
+done_cn_validation:
+ ;
+ }