summaryrefslogtreecommitdiff
path: root/lib/x509/verify-high.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x509/verify-high.c')
-rw-r--r--lib/x509/verify-high.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
index 9d9d0956cd..d78a2d4b7b 100644
--- a/lib/x509/verify-high.c
+++ b/lib/x509/verify-high.c
@@ -52,7 +52,6 @@ struct node_st {
/* The trusted CRLs */
gnutls_x509_crl_t *crls;
unsigned int crl_size;
-
};
struct gnutls_x509_trust_list_iter {
@@ -1175,6 +1174,15 @@ gnutls_x509_trust_list_verify_crt(gnutls_x509_trust_list_t list,
NULL, 0, flags, voutput, func);
}
+#define LAST_DN cert_list[cert_list_size-1]->raw_dn
+#define LAST_IDN cert_list[cert_list_size-1]->raw_issuer_dn
+/* This macro is introduced to detect a verification output
+ * which indicates an unknown signer, or a signer which uses
+ * an insecure algorithm (e.g., sha1), something that indicates
+ * a superceded signer */
+#define SIGNER_OLD_OR_UNKNOWN(output) ((output & GNUTLS_CERT_SIGNER_NOT_FOUND) || (output & GNUTLS_CERT_INSECURE_ALGORITHM))
+#define SIGNER_WAS_KNOWN(output) (!(output & GNUTLS_CERT_SIGNER_NOT_FOUND))
+
/**
* gnutls_x509_trust_list_verify_crt2:
* @list: The list
@@ -1238,6 +1246,7 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
const char *hostname = NULL, *purpose = NULL, *email = NULL;
unsigned hostname_size = 0;
unsigned have_set_name = 0;
+ unsigned saved_output;
gnutls_datum_t ip = {NULL, 0};
if (cert_list == NULL || cert_list_size < 1)
@@ -1313,11 +1322,9 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
list->
node[hash].trusted_ca_size,
flags, purpose, func);
+ saved_output = *voutput;
-#define LAST_DN cert_list[cert_list_size-1]->raw_dn
-#define LAST_IDN cert_list[cert_list_size-1]->raw_issuer_dn
-
- if ((*voutput) & GNUTLS_CERT_SIGNER_NOT_FOUND &&
+ if (SIGNER_OLD_OR_UNKNOWN(*voutput) &&
(LAST_DN.size != LAST_IDN.size ||
memcmp(LAST_DN.data, LAST_IDN.data, LAST_IDN.size) != 0)) {
@@ -1329,16 +1336,25 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
data, cert_list[cert_list_size - 1]->raw_dn.size);
hash %= list->size;
+ _gnutls_debug_log("issuer in verification was not found or insecure; trying against trust list\n");
+
*voutput =
_gnutls_verify_crt_status(cert_list, cert_list_size,
list->node[hash].trusted_cas,
list->
node[hash].trusted_ca_size,
flags, purpose, func);
+ if (*voutput != 0) {
+ if (SIGNER_WAS_KNOWN(saved_output))
+ *voutput = saved_output;
+ gnutls_assert();
+ }
}
+ saved_output = *voutput;
+
#ifdef ENABLE_PKCS11
- if ((*voutput & GNUTLS_CERT_SIGNER_NOT_FOUND) && list->pkcs11_token) {
+ if (SIGNER_OLD_OR_UNKNOWN(*voutput) && list->pkcs11_token) {
/* use the token for verification */
*voutput = _gnutls_pkcs11_verify_crt_status(list->pkcs11_token,
@@ -1346,6 +1362,8 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list,
purpose,
flags, func);
if (*voutput != 0) {
+ if (SIGNER_WAS_KNOWN(saved_output))
+ *voutput = saved_output;
gnutls_assert();
}
}