From 411e89ae6fa195885dc13c594235893c22cb33d8 Mon Sep 17 00:00:00 2001 From: james Date: Sat, 12 Nov 2005 08:26:57 +0000 Subject: Merged --remote-cert-ku, --remote-cert-eku, and --remote-cert-tls from Alon's branch: svn merge -r 793:796 $SO/contrib/alon/BETA21/openvpn . git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@797 e7ae566f-a301-0410-adde-c780ea21d3b5 --- ssl.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) (limited to 'ssl.c') diff --git a/ssl.c b/ssl.c index 2b78bd0..d76cda6 100644 --- a/ssl.c +++ b/ssl.c @@ -389,6 +389,91 @@ set_common_name (struct tls_session *session, const char *common_name) } } +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + +bool verify_cert_eku (X509 *x509, const char * const expected_oid) { + + EXTENDED_KEY_USAGE *eku = NULL; + bool fFound = false; + + if ((eku = (EXTENDED_KEY_USAGE *)X509_get_ext_d2i (x509, NID_ext_key_usage, NULL, NULL)) == NULL) { + msg (D_HANDSHAKE, "Certificate does not have extended key usage extension"); + } + else { + int i; + + msg (D_HANDSHAKE, "Validating certificate extended key usage"); + for(i = 0; !fFound && i < sk_ASN1_OBJECT_num (eku); i++) { + ASN1_OBJECT *oid = sk_ASN1_OBJECT_value (eku, i); + char szOid[1024]; + + if (!fFound && OBJ_obj2txt (szOid, sizeof (szOid), oid, 0) != -1) { + msg (D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s", szOid, expected_oid); + if (!strcmp (expected_oid, szOid)) { + fFound = true; + } + } + if (!fFound && OBJ_obj2txt (szOid, sizeof (szOid), oid, 1) != -1) { + msg (D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s", szOid, expected_oid); + if (!strcmp (expected_oid, szOid)) { + fFound = true; + } + } + } + } + + if (eku != NULL) { + sk_ASN1_OBJECT_pop_free (eku, ASN1_OBJECT_free); + } + + return fFound; +} + +bool verify_cert_ku (X509 *x509, const unsigned * const expected_ku, int expected_len) { + + ASN1_BIT_STRING *ku = NULL; + bool fFound = false; + + if ((ku = (ASN1_BIT_STRING *)X509_get_ext_d2i (x509, NID_key_usage, NULL, NULL)) == NULL) { + msg (D_HANDSHAKE, "Certificate does not have key usage extension"); + } + else { + unsigned nku = 0; + int i; + for (i=0;i<8;i++) { + if (ASN1_BIT_STRING_get_bit (ku, i)) { + nku |= 1<<(7-i); + } + } + + /* + * Fixup if no LSB bits + */ + if ((nku & 0xff) == 0) { + nku >>= 8; + } + + msg (D_HANDSHAKE, "Validating certificate key usage"); + for (i=0;!fFound && i= 0x00907000L + + /* verify certificate ku */ + if (opt->remote_cert_ku[0] != 0 && ctx->error_depth == 0) + { + if (verify_cert_ku (ctx->current_cert, opt->remote_cert_ku, MAX_PARMS)) + { + msg (D_HANDSHAKE, "VERIFY KU OK"); + } + else + { + msg (D_HANDSHAKE, "VERIFY KU ERROR"); + goto err; /* Reject connection */ + } + } + + /* verify certificate eku */ + if (opt->remote_cert_eku != NULL && ctx->error_depth == 0) + { + if (verify_cert_eku (ctx->current_cert, opt->remote_cert_eku)) + { + msg (D_HANDSHAKE, "VERIFY EKU OK"); + } + else + { + msg (D_HANDSHAKE, "VERIFY EKU ERROR"); + goto err; /* Reject connection */ + } + } + +#endif /* OPENSSL_VERSION_NUMBER */ + /* verify X509 name or common name against --tls-remote */ if (opt->verify_x509name && strlen (opt->verify_x509name) > 0 && ctx->error_depth == 0) { -- cgit v1.1