[Openvpn-devel] Patch: Export NotBefore and NotAfter items to the environment in client-connect
| Message ID | 65530ded0938659345877e870f49d2ad4b9768ae.camel@target-holding.nl |
|---|---|
| State | Changes Requested |
| Headers |
Return-Path: <openvpn-devel-bounces@lists.sourceforge.net> Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director9.mail.ord1d.rsapps.net ([172.27.255.57]) by backend30.mail.ord1d.rsapps.net with LMTP id qDV4CQtuVl1wYgAAIUCqbw for <patchwork@openvpn.net>; Fri, 16 Aug 2019 04:49:15 -0400 Received: from proxy14.mail.iad3a.rsapps.net ([172.27.255.57]) by director9.mail.ord1d.rsapps.net with LMTP id 6BpqBgtuVl0IUQAAalYnBA ; Fri, 16 Aug 2019 04:49:15 -0400 Received: from smtp16.gate.iad3a ([172.27.255.57]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy14.mail.iad3a.rsapps.net with LMTP id KDFmOwpuVl3RZgAA1+b4IQ ; Fri, 16 Aug 2019 04:49:14 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp16.gate.iad3a.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=pass header.d=lists.sourceforge.net; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=pass (p=none; dis=none) header.from=lists.sourceforge.net X-Suspicious-Flag: NO X-Classification-ID: b905b6a0-c002-11e9-bce7-5254004ee196-1-1 Received: from [216.105.38.7] ([216.105.38.7:58888] helo=lists.sourceforge.net) by smtp16.gate.iad3a.rsapps.net (envelope-from <openvpn-devel-bounces@lists.sourceforge.net>) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id E2/CF-04785-A0E665D5; Fri, 16 Aug 2019 04:49:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Type:Cc:Reply-To:From: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:Message-ID:Date:To:Sender:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=zOxr+ZOGTYQgGQNjLncuCa9XgI9srhxWvlV5kUndCLQ=; b=KPdp6Ym9ES8bCs/Y4Ni/WJxCed SHi2ofZUA6tpMqcu+r2OY34zuJpYYLiYuMJ9xOu3N5fdzoEdg773Uc1EwaSAM2lQ2Wz6wt3p5UcLQ bCprdsW60JEG+gPDk1+UxXUvzq3uQjemK31Mwy6vnl2fK0WNziym7G1W8GfzzRn+emHc=; Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from <openvpn-devel-bounces@lists.sourceforge.net>) id 1hyXuD-0002DS-70; Fri, 16 Aug 2019 08:48:17 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from <rolf.fokkens@target-holding.nl>) id 1hyXuB-0002D4-1t for openvpn-devel@lists.sourceforge.net; Fri, 16 Aug 2019 08:48:15 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=MIME-Version:Content-Type:Message-ID:Date:Subject: CC:To:From:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Y0T3W1q5uuCI5WOJCwwfyqQjbhtR6IMFOZy6IAD72y8=; b=PNRMlMDGKWrimXfeZ1XJ6Mzg5d 5j0zVypcgQdjtw4ArptelsGDdJ+7/GKCN+dtX2g9TRqCziyPjpdgy60f47QjwwLaejLUMt5QvREIR OoWxrxbxWW+meQA/8qdr9OZGTlHcXOn39+0NietywuzUsPrO1ucuP/chcqk0MY6NdPYM=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=MIME-Version:Content-Type:Message-ID:Date:Subject:CC:To:From:Sender: Reply-To:Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date :Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=Y0T3W1q5uuCI5WOJCwwfyqQjbhtR6IMFOZy6IAD72y8=; b=Z DKpE3OtLFQFk0kwoDTjmCjZB9MqrOzbeJqbpnMsqi+IC2pZvNWWj1M1u+EJRX0qDMtcdgn12308nv FIe0VyGaUUoIQUv54hWm4zjChDbmnYCmZ/RZTE/BEeZeIVMLo81vQ8UPAgazahfmO8p1z6FNogwmW /FXT9yN9ibjG98D4=; Received: from edge1.exchange-login.net ([93.94.224.194] helo=owa.exchange-login.net) by sfi-mx-3.v28.lw.sourceforge.com with esmtps (TLSv1:ECDHE-RSA-AES256-SHA:256) (Exim 4.90_1) id 1hyXu1-005fiZ-49 for openvpn-devel@lists.sourceforge.net; Fri, 16 Aug 2019 08:48:14 +0000 Received: from HC1.hosted.exchange-login.net (93.94.224.200) by edge1.hosted.exchange-login.net (93.94.224.194) with Microsoft SMTP Server (TLS) id 14.3.468.0; Fri, 16 Aug 2019 10:27:31 +0200 Received: from MBX1.hosted.exchange-login.net ([fe80::a957:8775:7bf4:6581]) by hc1.hosted.exchange-login.net ([2002:5d5e:e0c8::5d5e:e0c8]) with mapi id 14.03.0468.000; Fri, 16 Aug 2019 10:27:31 +0200 To: "openvpn-devel@lists.sourceforge.net" <openvpn-devel@lists.sourceforge.net> Thread-Topic: Patch: Export NotBefore and NotAfter items to the environment in client-connect Thread-Index: AQHVVAxx4co68Gquzkq/9hO7GCSedA== Date: Fri, 16 Aug 2019 08:27:30 +0000 Message-ID: <65530ded0938659345877e870f49d2ad4b9768ae.camel@target-holding.nl> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: yes X-MS-TNEF-Correlator: user-agent: Evolution 3.32.4 (3.32.4-1.fc30) MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record X-Headers-End: 1hyXu1-005fiZ-49 Subject: [Openvpn-devel] Patch: Export NotBefore and NotAfter items to the environment in client-connect X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: <openvpn-devel.lists.sourceforge.net> List-Unsubscribe: <https://lists.sourceforge.net/lists/options/openvpn-devel>, <mailto:openvpn-devel-request@lists.sourceforge.net?subject=unsubscribe> List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=openvpn-devel> List-Post: <mailto:openvpn-devel@lists.sourceforge.net> List-Help: <mailto:openvpn-devel-request@lists.sourceforge.net?subject=help> List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/openvpn-devel>, <mailto:openvpn-devel-request@lists.sourceforge.net?subject=subscribe> From: Rolf Fokkens via Openvpn-devel <openvpn-devel@lists.sourceforge.net> Reply-To: Rolf Fokkens <rolf.fokkens@target-holding.nl> Cc: Valentin Bajrami <valentin.bajrami@target-holding.nl>, Jasper Siero <jasper.siero@target-holding.nl> Content-Type: multipart/mixed; boundary="===============6083979231950097004==" Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox |
| Series |
[Openvpn-devel] Patch: Export NotBefore and NotAfter items to the environment in client-connect
|
|
Commit Message
haixiao.yan.cn--- via Openvpn-devel
Aug. 15, 2019, 10:27 p.m. UTC
We're considering to use shorter-lived client certificates for our VPN users. In an effort to prevent negative impact for our staff due to expired certificates, we 'd like to keep track of imminent expiration of certificates in the client-connect script (which we're using anyway to check is the certificate matches the user id). Many certificate attributes are passed to the script, but not the "NotAfter" and "NotBefore" attributes. The attached patch adds these to the mix. Rolf
Comments
On 16/08/2019 10:27, Rolf Fokkens via Openvpn-devel wrote: > We're considering to use shorter-lived client certificates for our VPN > users. In an effort to prevent negative impact for our staff due to > expired certificates, we 'd like to keep track of imminent expiration > of certificates in the client-connect script (which we're using anyway > to check is the certificate matches the user id). Many certificate > attributes are passed to the script, but not the "NotAfter" and > "NotBefore" attributes. > > The attached patch adds these to the mix. This gets a Feature-ACK from me. This is useful information, and something other users in the community have asked for earlier too. But there are a few things here before starting to dive into the details. First of all, we want to have patches first into git master, and then we need to discuss in the community if this feature is something we want to backport to the 2.4 release. After a new release has stabilized (which 2.4 has), we are quite reluctant to add new features to those releases. Another thing is that I think it would be valuable to also print this information into the logs as well. The X509_get_notBefore() value is probably not so important unless that has a value which is in the future. The X509_get_notAfter() is fine to always log, but would be nice if it would come a M_WARN log entry if it has expired. To achieve this logging feature, setenv_ASN1_TIME() would need to be refactored a bit - possibly by returning a string as well as "is now() after the time stamp?" bool flag. The "printing" could happen to a gc_arena allocated buffer (which is available in verify_cert_set_env()). The logging should probably already happen in verify_cert(), which also has its own gc_arena. There are various alternatives to avoid doing the ASN1_TIME_print() preparations and processing multiple times (for logging and setenv), but I don't have a clear idea right now what could be a reasonable approach. And lastly, this code will break compilation if using ./configure --with-crypto-library=mbedtls ... This should also be improved. Other than that, the code looks reasonable at first glance (I have not compile tested it yet)
On Fri, 2019-08-16 at 13:45 +0200, David Sommerseth wrote: > This gets a Feature-ACK from me. This is useful information, and > something > other users in the community have asked for earlier too. But there > are a few > things here before starting to dive into the details. > > First of all, we want to have patches first into git master, and then > we need > to discuss in the community if this feature is something we want to > backport > to the 2.4 release. After a new release has stabilized (which 2.4 > has), we > are quite reluctant to add new features to those releases. I started off by creating a pull request: https://github.com/OpenVPN/openvpn/pull/129 During creation of the pull request I was pointed to the openvpn-devel list, so I attached the patch there too. That one was based on 2.4, because that's what we're using and how we're testing (and using) the patch. > Another thing is that I think it would be valuable to also print this > information into the logs as well. The X509_get_notBefore() value is > probably > not so important unless that has a value which is in the future. The > X509_get_notAfter() is fine to always log, but would be nice if it > would come > a M_WARN log entry if it has expired. > > To achieve this logging feature, setenv_ASN1_TIME() would need to be > refactored a bit - possibly by returning a string as well as "is > now() after > the time stamp?" bool flag. The "printing" could happen to a > gc_arena > allocated buffer (which is available in verify_cert_set_env()). The > logging > should probably already happen in verify_cert(), which also has its > own > gc_arena. There are various alternatives to avoid doing the > ASN1_TIME_print() > preparations and processing multiple times (for logging and setenv), > but I > don't have a clear idea right now what could be a reasonable > approach. > > And lastly, this code will break compilation if using > ./configure --with-crypto-library=mbedtls ... This should also be > improved. > I updated my pull request based on your feedback. I'm not sure if I correcty understood the structure of the software, but I think it's a decent attempt. - The notAfter information is in the logs now (appended to the "VERIFY OK" lines) - Warnings are issued if the now is before notBefore of after notAfter - openssl specifics are moved to ssl_verify_openssl.c. ssl_verify_mbedtls.c has a dummy equivalent which should make openvpn both compile and run. Attached you'll find the updated patch too. diff -ruN openvpn-2.4.7.orig/src/openvpn/ssl_verify_backend.h openvpn-2.4.7/src/openvpn/ssl_verify_backend.h --- openvpn-2.4.7.orig/src/openvpn/ssl_verify_backend.h 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7/src/openvpn/ssl_verify_backend.h 2019-08-17 13:35:38.832574389 +0200 @@ -267,4 +267,25 @@ */ bool tls_verify_crl_missing(const struct tls_options *opt); +/* + * Get certificate notBefore and notAfter attributes + * + * @param cert Certificate to retrieve attributes from + * @param notsize Size of char buffers for notbefore and notafter + * @param notbefore Charachter representation of notBefore attribute + * @param cmpbefore Compare notBefore with "now"; > 0 if notBefore in the past + * @param notafter Character representation of notAfter attribute + * @param cmpafter Compare notAfter with "now"; > 0 if notAfter in the past + * + * On failing to retrieve notBefore attributes: + * - notbefore[0] = '\0' + * - cmpbefore = 0 + * + * On failing to retrieve notAfter attributes: + * - notafter[0] = '\0' + * - cmpafter = 0 + */ + +void x509_get_validity(openvpn_x509_cert_t *cert, int notsize, char *notbefore, int *cmpbefore, char *notafter, int *cmpafter); + #endif /* SSL_VERIFY_BACKEND_H_ */ diff -ruN openvpn-2.4.7.orig/src/openvpn/ssl_verify.c openvpn-2.4.7/src/openvpn/ssl_verify.c --- openvpn-2.4.7.orig/src/openvpn/ssl_verify.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7/src/openvpn/ssl_verify.c 2019-08-17 13:39:43.229250136 +0200 @@ -447,6 +447,17 @@ return SUCCESS; } +static void +setenv_validity (struct env_set *es, char *envprefix, int depth, char *dt) +{ + char varname[32]; + + if (!dt[0]) return; + + openvpn_snprintf(varname, sizeof(varname), "%s_%d", envprefix, depth); + setenv_str(es, varname, dt); +} + /* * Export the subject, common_name, and raw certificate fields to the * environment for later verification by scripts and plugins. @@ -673,6 +684,8 @@ char common_name[TLS_USERNAME_LEN+1] = {0}; /* null-terminated */ const struct tls_options *opt; struct gc_arena gc = gc_new(); + char notbefore_buf[32], notafter_buf[32]; + int notbefore_cmp, notafter_cmp; opt = session->opt; ASSERT(opt); @@ -767,6 +780,13 @@ /* export current untrusted IP */ setenv_untrusted(session); + x509_get_validity(cert, sizeof (notbefore_buf), notbefore_buf, ¬before_cmp, notafter_buf, ¬after_cmp); + setenv_validity (opt->es, "tls_notbefore", cert_depth, notbefore_buf); + setenv_validity (opt->es, "tls_notafter", cert_depth, notafter_buf); + + if (notbefore_cmp < 0) msg(M_WARN, "Certificate notBefore (%s)", notbefore_buf); + if (notafter_cmp > 0) msg(M_WARN, "Certificate notAfter (%s)", notafter_buf); + /* If this is the peer's own certificate, verify it */ if (cert_depth == 0 && SUCCESS != verify_peer_cert(opt, cert, subject, common_name)) { @@ -806,7 +826,8 @@ } } - msg(D_HANDSHAKE, "VERIFY OK: depth=%d, %s", cert_depth, subject); + msg(D_HANDSHAKE, "VERIFY OK: depth=%d, %s, notAfter=%s", cert_depth, subject, + (notafter_buf[0] ? notafter_buf : "-")); session->verified = true; ret = SUCCESS; diff -ruN openvpn-2.4.7.orig/src/openvpn/ssl_verify_mbedtls.c openvpn-2.4.7/src/openvpn/ssl_verify_mbedtls.c --- openvpn-2.4.7.orig/src/openvpn/ssl_verify_mbedtls.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7/src/openvpn/ssl_verify_mbedtls.c 2019-08-17 13:23:46.250827837 +0200 @@ -550,4 +550,14 @@ return false; } +void +x509_get_validity(mbedtls_x509_crt *cert, int notsize, char *notbefore, int *cmpbefore, char *notafter, int *cmpafter) +{ + notbefore[0] = '\0'; + notafter[0] = '\0'; + + *cmpbefore = 0; + *cmpafter = 0; +} + #endif /* #if defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_MBEDTLS) */ diff -ruN openvpn-2.4.7.orig/src/openvpn/ssl_verify_openssl.c openvpn-2.4.7/src/openvpn/ssl_verify_openssl.c --- openvpn-2.4.7.orig/src/openvpn/ssl_verify_openssl.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7/src/openvpn/ssl_verify_openssl.c 2019-08-17 13:36:58.222439208 +0200 @@ -802,4 +802,35 @@ return true; } +static int +get_ASN1_TIME(const ASN1_TIME *asn1_time, char *dt, int dtsize, int *cmpnow) +{ + BIO *mem; + int ret, pday, psec; + + mem = BIO_new(BIO_s_mem()); + if ((ret = ASN1_TIME_print (mem, asn1_time))) { + dt[BIO_read(mem, dt, dtsize-1)] = '\0'; + } + BIO_free(mem); + if (!ret) goto fail; + + if (!ASN1_TIME_diff(&pday, &psec, asn1_time, NULL)) goto fail; + *cmpnow = (pday ? pday : psec); + + return 1; + +fail: + dt[0] = '\0'; + *cmpnow = 0; + return 0; +} + +void +x509_get_validity(X509 *cert, int notsize, char *notbefore, int *cmpbefore, char *notafter, int *cmpafter) +{ + get_ASN1_TIME(X509_get_notBefore(cert), notbefore, notsize, cmpbefore); + get_ASN1_TIME(X509_get_notAfter(cert), notafter, notsize, cmpafter); +} + #endif /* defined(ENABLE_CRYPTO) && defined(ENABLE_CRYPTO_OPENSSL) */
Hi Rolf, I know this is old....but... Is this something you'd consider resending based on current master? Would you also have any chance of testing it again after rebase? Cheers, On 17/08/2019 14:12, Rolf Fokkens via Openvpn-devel wrote: > On Fri, 2019-08-16 at 13:45 +0200, David Sommerseth wrote: >> This gets a Feature-ACK from me. This is useful information, and >> something >> other users in the community have asked for earlier too. But there >> are a few >> things here before starting to dive into the details. >> >> First of all, we want to have patches first into git master, and then >> we need >> to discuss in the community if this feature is something we want to >> backport >> to the 2.4 release. After a new release has stabilized (which 2.4 >> has), we >> are quite reluctant to add new features to those releases. > > I started off by creating a pull request: > https://github.com/OpenVPN/openvpn/pull/129 > > During creation of the pull request I was pointed to the openvpn-devel > list, so I attached the patch there too. That one was based on 2.4, > because that's what we're using and how we're testing (and using) the > patch. > >> Another thing is that I think it would be valuable to also print this >> information into the logs as well. The X509_get_notBefore() value is >> probably >> not so important unless that has a value which is in the future. The >> X509_get_notAfter() is fine to always log, but would be nice if it >> would come >> a M_WARN log entry if it has expired. >> >> To achieve this logging feature, setenv_ASN1_TIME() would need to be >> refactored a bit - possibly by returning a string as well as "is >> now() after >> the time stamp?" bool flag. The "printing" could happen to a >> gc_arena >> allocated buffer (which is available in verify_cert_set_env()). The >> logging >> should probably already happen in verify_cert(), which also has its >> own >> gc_arena. There are various alternatives to avoid doing the >> ASN1_TIME_print() >> preparations and processing multiple times (for logging and setenv), >> but I >> don't have a clear idea right now what could be a reasonable >> approach. >> >> And lastly, this code will break compilation if using >> ./configure --with-crypto-library=mbedtls ... This should also be >> improved. >> > > I updated my pull request based on your feedback. I'm not sure if I > correcty understood the structure of the software, but I think it's a > decent attempt. > > - The notAfter information is in the logs now (appended to the "VERIFY > OK" lines) > - Warnings are issued if the now is before notBefore of after notAfter > - openssl specifics are moved to ssl_verify_openssl.c. > ssl_verify_mbedtls.c has a dummy equivalent which should make openvpn > both compile and run. > > Attached you'll find the updated patch too. > > > > _______________________________________________ > Openvpn-devel mailing list > Openvpn-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/openvpn-devel >
diff -ruN openvpn-2.4.7.orig/src/openvpn/ssl_verify.c openvpn-2.4.7/src/openvpn/ssl_verify.c --- openvpn-2.4.7.orig/src/openvpn/ssl_verify.c 2019-02-20 13:28:23.000000000 +0100 +++ openvpn-2.4.7/src/openvpn/ssl_verify.c 2019-08-15 20:57:29.803381111 +0200 @@ -448,6 +448,25 @@ } /* + * Export ASN1_TIME items to the environment + */ +static void +setenv_ASN1_TIME(struct env_set *es, char *envname, int envnamesize, + char *envprefix, int depth, const ASN1_TIME *asn1_time) +{ + char timestamp[32]; + BIO *mem; + + mem = BIO_new(BIO_s_mem()); + if (ASN1_TIME_print (mem, asn1_time)) { + timestamp[BIO_read(mem, timestamp, sizeof(timestamp)-1)] = '\0'; + openvpn_snprintf(envname, envnamesize, "%s_%d", envprefix, depth); + setenv_str(es, envname, timestamp); + } + BIO_free(mem); +} + +/* * Export the subject, common_name, and raw certificate fields to the * environment for later verification by scripts and plugins. */ @@ -505,6 +524,12 @@ openvpn_snprintf(envname, sizeof(envname), "tls_serial_hex_%d", cert_depth); setenv_str(es, envname, serial); + setenv_ASN1_TIME(es, envname, sizeof(envname), "tls_notbefore", cert_depth, + X509_get_notBefore(peer_cert)); + + setenv_ASN1_TIME(es, envname, sizeof(envname), "tls_notafter", cert_depth, + X509_get_notAfter(peer_cert)); + gc_free(&gc); }