From: Adriaan de Jong Date: Wed, 29 Jun 2011 12:20:43 +0000 (+0200) Subject: Refactored key usage verification code X-Git-Tag: v2.3-alpha1~121 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=876752aed66a143295d9d0d4e61dc9a8beca2f5e;p=thirdparty%2Fopenvpn.git Refactored key usage verification code Signed-off-by: Adriaan de Jong Acked-by: James Yonan Signed-off-by: David Sommerseth --- diff --git a/ssl.c b/ssl.c index e16f1a3da..0d92c8a7f 100644 --- a/ssl.c +++ b/ssl.c @@ -342,49 +342,6 @@ bool verify_cert_eku (X509 *x509, const char * const expected_oid) { 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 && cert_depth == 0) - { - if (verify_cert_ku (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 && cert_depth == 0) { diff --git a/ssl_verify.c b/ssl_verify.c index 4ca414f93..2d8ae4980 100644 --- a/ssl_verify.c +++ b/ssl_verify.c @@ -351,6 +351,24 @@ verify_peer_cert(const struct tls_options *opt, x509_cert_t *peer_cert, } } +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + + /* verify certificate ku */ + if (opt->remote_cert_ku[0] != 0) + { + if (verify_cert_ku (peer_cert, opt->remote_cert_ku, MAX_PARMS)) + { + msg (D_HANDSHAKE, "VERIFY KU OK"); + } + else + { + msg (D_HANDSHAKE, "VERIFY KU ERROR"); + return 1; /* Reject connection */ + } + } + + +#endif /* OPENSSL_VERSION_NUMBER */ return 0; } diff --git a/ssl_verify_backend.h b/ssl_verify_backend.h index 6f0e54e9a..9b88f717f 100644 --- a/ssl_verify_backend.h +++ b/ssl_verify_backend.h @@ -154,4 +154,17 @@ void setenv_x509 (struct env_set *es, int cert_depth, x509_cert_t *cert); */ bool verify_nsCertType(const x509_cert_t *cert, const int usage); +/* + * Verify X.509 key usage extension field. + * + * @param cert Certificate to check. + * @param expected_ku Array of valid key usage values + * @param expected_len Length of the key usage array + * + * @return \c true if one of the key usage values matches, \c false + * if key usage is not enabled, or the values do not match. + */ +bool verify_cert_ku (x509_cert_t *x509, const unsigned * const expected_ku, + int expected_len); + #endif /* SSL_VERIFY_BACKEND_H_ */ diff --git a/ssl_verify_openssl.c b/ssl_verify_openssl.c index 033af1dbf..1a6bb2de8 100644 --- a/ssl_verify_openssl.c +++ b/ssl_verify_openssl.c @@ -392,3 +392,57 @@ verify_nsCertType(const x509_cert_t *peer_cert, const int usage) return false; } + +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + +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 < expected_len; i++) + { + if (expected_ku[i] != 0) + { + msg (D_HANDSHAKE, "++ Certificate has key usage %04x, expects " + "%04x", nku, expected_ku[i]); + + if (nku == expected_ku[i]) + fFound = true; + } + } + } + + if (ku != NULL) + ASN1_BIT_STRING_free (ku); + + return fFound; +} + +#endif /* OPENSSL_VERSION_NUMBER */