From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] PATCH 6/8: x509 client certificate verification
Date: Mon, 13 Aug 2007 20:48:57 +0100 [thread overview]
Message-ID: <20070813194857.GH30789@redhat.com> (raw)
In-Reply-To: <20070813192517.GB30789@redhat.com>
This patch adds support for requesting and validating client certificates.
In effect the client certificates are being used as the authentication
mechansim, making VNC passwords unccessary, though using a combination of
both is also possible.
Example usage of just certificate verification
qemu [...OPTIONS...] -vnc :1,tls,x509verify -monitor stdio
Or, combined with passwords:
qemu [...OPTIONS...] -vnc :1,password,tls,x509verify -monitor stdio
(qemu) change vnc password
Password: ********
(qemu)
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
diff -r bfd4dbe12342 vnc.c
--- a/vnc.c Wed Aug 08 12:53:50 2007 -0400
+++ b/vnc.c Wed Aug 08 12:54:10 2007 -0400
@@ -142,6 +142,7 @@ struct VncState
int auth;
#if CONFIG_VNC_TLS
int subauth;
+ int x509verify;
#endif
char challenge[VNC_AUTH_CHALLENGE_SIZE];
@@ -1427,6 +1428,85 @@ static gnutls_certificate_credentials_t
return x509_cred;
}
+static int vnc_validate_certificate(struct VncState *vs)
+{
+ int ret;
+ unsigned int status;
+ const gnutls_datum_t *certs;
+ unsigned int nCerts, i;
+ time_t now;
+
+ VNC_DEBUG("Validating client certificate\n");
+ if ((ret = gnutls_certificate_verify_peers2 (vs->tls_session, &status)) < 0) {
+ VNC_DEBUG("Verify failed %s\n", gnutls_strerror(ret));
+ return -1;
+ }
+
+ if ((now = time(NULL)) == ((time_t)-1)) {
+ return -1;
+ }
+
+ if (status != 0) {
+ if (status & GNUTLS_CERT_INVALID)
+ VNC_DEBUG("The certificate is not trusted.\n");
+
+ if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
+ VNC_DEBUG("The certificate hasn't got a known issuer.\n");
+
+ if (status & GNUTLS_CERT_REVOKED)
+ VNC_DEBUG("The certificate has been revoked.\n");
+
+ if (status & GNUTLS_CERT_INSECURE_ALGORITHM)
+ VNC_DEBUG("The certificate uses an insecure algorithm\n");
+
+ return -1;
+ } else {
+ VNC_DEBUG("Certificate is valid!\n");
+ }
+
+ /* Only support x509 for now */
+ if (gnutls_certificate_type_get(vs->tls_session) != GNUTLS_CRT_X509)
+ return -1;
+
+ if (!(certs = gnutls_certificate_get_peers(vs->tls_session, &nCerts)))
+ return -1;
+
+ for (i = 0 ; i < nCerts ; i++) {
+ gnutls_x509_crt_t cert;
+ VNC_DEBUG ("Checking certificate chain %d\n", i);
+ if (gnutls_x509_crt_init (&cert) < 0)
+ return -1;
+
+ if (gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER) < 0) {
+ gnutls_x509_crt_deinit (cert);
+ return -1;
+ }
+
+ if (gnutls_x509_crt_get_expiration_time (cert) < now) {
+ VNC_DEBUG("The certificate has expired\n");
+ gnutls_x509_crt_deinit (cert);
+ return -1;
+ }
+
+ if (gnutls_x509_crt_get_activation_time (cert) > now) {
+ VNC_DEBUG("The certificate is not yet activated\n");
+ gnutls_x509_crt_deinit (cert);
+ return -1;
+ }
+
+ if (gnutls_x509_crt_get_activation_time (cert) > now) {
+ VNC_DEBUG("The certificate is not yet activated\n");
+ gnutls_x509_crt_deinit (cert);
+ return -1;
+ }
+
+ gnutls_x509_crt_deinit (cert);
+ }
+
+ return 0;
+}
+
+
static int start_auth_vencrypt_subauth(VncState *vs)
{
switch (vs->subauth) {
@@ -1473,6 +1553,16 @@ static int vnc_continue_handshake(struct
VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));
vnc_client_error(vs);
return -1;
+ }
+
+ if (vs->x509verify) {
+ if (vnc_validate_certificate(vs) < 0) {
+ VNC_DEBUG("Client verification failed\n");
+ vnc_client_error(vs);
+ return -1;
+ } else {
+ VNC_DEBUG("Client verification passed\n");
+ }
}
VNC_DEBUG("Handshake done, switching to TLS data mode\n");
@@ -1556,6 +1646,11 @@ static int vnc_start_tls(struct VncState
vnc_client_error(vs);
return -1;
}
+ if (vs->x509verify) {
+ VNC_DEBUG("Requesting a client certificate\n");
+ gnutls_certificate_server_set_request (vs->tls_session, GNUTLS_CERT_REQUEST);
+ }
+
} else {
gnutls_anon_server_credentials anon_cred = vnc_tls_initialize_anon_cred();
if (!anon_cred) {
@@ -1838,6 +1933,7 @@ void vnc_display_close(DisplayState *ds)
vs->auth = VNC_AUTH_INVALID;
#if CONFIG_VNC_TLS
vs->subauth = VNC_AUTH_INVALID;
+ vs->x509verify = 0;
#endif
}
@@ -1884,14 +1980,18 @@ int vnc_display_open(DisplayState *ds, c
options = display;
while ((options = strchr(options, ','))) {
options++;
- if (strncmp(options, "password", 8) == 0)
+ if (strncmp(options, "password", 8) == 0) {
password = 1; /* Require password auth */
#if CONFIG_VNC_TLS
- else if (strncmp(options, "tls", 3) == 0)
+ } else if (strncmp(options, "tls", 3) == 0) {
tls = 1; /* Require TLS */
- else if (strncmp(options, "x509", 4) == 0)
+ } else if (strncmp(options, "x509verify", 10) == 0) {
+ x509 = 1; /* Require x509 certificates... */
+ vs->x509verify = 1;/* ...and verify client certs */
+ } else if (strncmp(options, "x509", 4) == 0) {
x509 = 1; /* Require x509 certificates */
#endif
+ }
}
if (password) {
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
next prev parent reply other threads:[~2007-08-13 19:49 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-08-13 19:25 [Qemu-devel] PATCH 0/8: Authentication support for the VNC server Daniel P. Berrange
2007-08-13 19:41 ` [Qemu-devel] PATCH 1/8: Refactor VNC server setup API Daniel P. Berrange
2007-08-13 19:42 ` [Qemu-devel] PATCH 2/8: Extend monitor 'change' command for VNC Daniel P. Berrange
2007-08-13 19:44 ` [Qemu-devel] PATCH 3/8: VNC password authentication Daniel P. Berrange
2007-08-13 19:46 ` [Qemu-devel] PATCH 4/8: VeNCrypt basic TLS support Daniel P. Berrange
2007-08-13 19:47 ` [Qemu-devel] PATCH 5/8: x509 certificate for server Daniel P. Berrange
2007-08-13 19:48 ` Daniel P. Berrange [this message]
2007-08-13 19:50 ` [Qemu-devel] PATCH 7/8: custom location for x509 cert paths Daniel P. Berrange
2007-08-13 19:51 ` [Qemu-devel] PATCH 8/8: document all VNC authentication options Daniel P. Berrange
2007-08-15 4:32 ` [Qemu-devel] PATCH 0/8: Authentication support for the VNC server Anthony Liguori
-- strict thread matches above, loose matches on Subject: below --
2007-07-31 19:23 Daniel P. Berrange
2007-07-31 19:28 ` [Qemu-devel] PATCH 6/8: x509 client certificate verification Daniel P. Berrange
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20070813194857.GH30789@redhat.com \
--to=berrange@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.