summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbeck <>2016-06-25 16:43:03 +0000
committerbeck <>2016-06-25 16:43:03 +0000
commitb077748469d9568fe5688f513af8f8e344421e23 (patch)
tree7a61054c968d5c5f161b62ad1161b6244ffc10e8
parentde29bcd6dcc8ee744dcb71b3bd8f3a66b6000e8c (diff)
downloadopenbsd-b077748469d9568fe5688f513af8f8e344421e23.tar.gz
openbsd-b077748469d9568fe5688f513af8f8e344421e23.tar.bz2
openbsd-b077748469d9568fe5688f513af8f8e344421e23.zip
Fix several issues in the OCSP code that could result in the incorrect
generation and parsing of OCSP requests. This remediates a lack of error checking on time parsing in these functions, and ensures that only GENERALIZEDTIME formats are accepted for OCSP, as per RFC 6960 Issues reported, and fixes provided by Kazuki Yamaguchi <k@rhe.jp> and Kinichiro Inoguchi <kinichiro.inoguchi@gmail.com>
-rw-r--r--src/lib/libssl/src/crypto/ocsp/ocsp_cl.c38
-rw-r--r--src/lib/libssl/src/crypto/ocsp/ocsp_srv.c4
2 files changed, 33 insertions, 9 deletions
diff --git a/src/lib/libssl/src/crypto/ocsp/ocsp_cl.c b/src/lib/libssl/src/crypto/ocsp/ocsp_cl.c
index a4320d9278..1968550a7e 100644
--- a/src/lib/libssl/src/crypto/ocsp/ocsp_cl.c
+++ b/src/lib/libssl/src/crypto/ocsp/ocsp_cl.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ocsp_cl.c,v 1.8 2014/10/18 17:20:40 jsing Exp $ */ 1/* $OpenBSD: ocsp_cl.c,v 1.8.2.1 2016/06/25 16:43:01 beck Exp $ */
2/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL 2/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
3 * project. */ 3 * project. */
4 4
@@ -71,6 +71,9 @@
71#include <openssl/x509.h> 71#include <openssl/x509.h>
72#include <openssl/x509v3.h> 72#include <openssl/x509v3.h>
73 73
74int asn1_time_parse(const char *, size_t, struct tm *, int);
75int asn1_tm_cmp(struct tm *, struct tm *);
76
74/* Utility functions related to sending OCSP requests and extracting 77/* Utility functions related to sending OCSP requests and extracting
75 * relevant information from the response. 78 * relevant information from the response.
76 */ 79 */
@@ -329,25 +332,43 @@ OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
329{ 332{
330 int ret = 1; 333 int ret = 1;
331 time_t t_now, t_tmp; 334 time_t t_now, t_tmp;
335 struct tm tm_this, tm_next, tm_tmp;
332 336
333 time(&t_now); 337 time(&t_now);
338
339 /*
340 * Times must explicitly be a GENERALIZEDTIME as per section
341 * 4.2.2.1 of RFC 6960 - It is invalid to accept other times
342 * (such as UTCTIME permitted/required by RFC 5280 for certificates)
343 */
344
334 /* Check thisUpdate is valid and not more than nsec in the future */ 345 /* Check thisUpdate is valid and not more than nsec in the future */
335 if (!ASN1_GENERALIZEDTIME_check(thisupd)) { 346 if (asn1_time_parse(thisupd->data, thisupd->length, &tm_this,
347 V_ASN1_GENERALIZEDTIME) != V_ASN1_GENERALIZEDTIME) {
336 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, 348 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
337 OCSP_R_ERROR_IN_THISUPDATE_FIELD); 349 OCSP_R_ERROR_IN_THISUPDATE_FIELD);
338 ret = 0; 350 ret = 0;
339 } else { 351 } else {
340 t_tmp = t_now + nsec; 352 t_tmp = t_now + nsec;
341 if (X509_cmp_time(thisupd, &t_tmp) > 0) { 353 if (gmtime_r(&t_tmp, &tm_tmp) == NULL)
354 return 0;
355 if (asn1_tm_cmp(&tm_this, &tm_tmp) > 0) {
342 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, 356 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
343 OCSP_R_STATUS_NOT_YET_VALID); 357 OCSP_R_STATUS_NOT_YET_VALID);
344 ret = 0; 358 ret = 0;
345 } 359 }
346 360
347 /* If maxsec specified check thisUpdate is not more than maxsec in the past */ 361 /*
362 * If maxsec specified check thisUpdate is not more than maxsec
363 * in the past
364 */
348 if (maxsec >= 0) { 365 if (maxsec >= 0) {
349 t_tmp = t_now - maxsec; 366 t_tmp = t_now - maxsec;
350 if (X509_cmp_time(thisupd, &t_tmp) < 0) { 367 if (gmtime_r(&t_tmp, &tm_tmp) == NULL)
368 return 0;
369 if (gmtime_r(&t_tmp, &tm_tmp) == NULL)
370 return 0;
371 if (asn1_tm_cmp(&tm_this, &tm_tmp) < 0) {
351 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, 372 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
352 OCSP_R_STATUS_TOO_OLD); 373 OCSP_R_STATUS_TOO_OLD);
353 ret = 0; 374 ret = 0;
@@ -359,13 +380,16 @@ OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
359 return ret; 380 return ret;
360 381
361 /* Check nextUpdate is valid and not more than nsec in the past */ 382 /* Check nextUpdate is valid and not more than nsec in the past */
362 if (!ASN1_GENERALIZEDTIME_check(nextupd)) { 383 if (asn1_time_parse(nextupd->data, nextupd->length, &tm_next,
384 V_ASN1_GENERALIZEDTIME) != V_ASN1_GENERALIZEDTIME) {
363 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, 385 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
364 OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); 386 OCSP_R_ERROR_IN_NEXTUPDATE_FIELD);
365 ret = 0; 387 ret = 0;
366 } else { 388 } else {
367 t_tmp = t_now - nsec; 389 t_tmp = t_now - nsec;
368 if (X509_cmp_time(nextupd, &t_tmp) < 0) { 390 if (gmtime_r(&t_tmp, &tm_tmp) == NULL)
391 return 0;
392 if (asn1_tm_cmp(&tm_next, &tm_tmp) < 0) {
369 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, 393 OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY,
370 OCSP_R_STATUS_EXPIRED); 394 OCSP_R_STATUS_EXPIRED);
371 ret = 0; 395 ret = 0;
diff --git a/src/lib/libssl/src/crypto/ocsp/ocsp_srv.c b/src/lib/libssl/src/crypto/ocsp/ocsp_srv.c
index 8f28916757..e300631eb1 100644
--- a/src/lib/libssl/src/crypto/ocsp/ocsp_srv.c
+++ b/src/lib/libssl/src/crypto/ocsp/ocsp_srv.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ocsp_srv.c,v 1.7 2014/10/18 17:20:40 jsing Exp $ */ 1/* $OpenBSD: ocsp_srv.c,v 1.7.2.1 2016/06/25 16:43:01 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2001. 3 * project 2001.
4 */ 4 */
@@ -260,7 +260,7 @@ OCSP_basic_sign(OCSP_BASICRESP *brsp, X509 *signer, EVP_PKEY *key,
260 } 260 }
261 261
262 if (!(flags & OCSP_NOTIME) && 262 if (!(flags & OCSP_NOTIME) &&
263 !X509_gmtime_adj(brsp->tbsResponseData->producedAt, 0)) 263 !ASN1_GENERALIZEDTIME_set(brsp->tbsResponseData->producedAt, time(NULL)))
264 goto err; 264 goto err;
265 265
266 /* Right now, I think that not doing double hashing is the right 266 /* Right now, I think that not doing double hashing is the right