summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbeck <>2016-06-25 15:38:44 +0000
committerbeck <>2016-06-25 15:38:44 +0000
commite3be7f350ab12561f21fccc6641ed88238c551f4 (patch)
tree9ff83921432b7ebf58639bb6a0e1973fa56c4eca
parentb789abd90ce8dc508846bc7556ffad3b18c4cd06 (diff)
downloadopenbsd-e3be7f350ab12561f21fccc6641ed88238c551f4.tar.gz
openbsd-e3be7f350ab12561f21fccc6641ed88238c551f4.tar.bz2
openbsd-e3be7f350ab12561f21fccc6641ed88238c551f4.zip
Fix the ocsp code to actually check for errors when comparing time values
which was not being done due to a lack of checking of the return code for X509_cmp_time. Ensure that we only compare GERNERALIZEDTIME values because this is what is specified by RFC6960. Issue reported, and fix provided by Kazuki Yamaguchi <k@rhe.jp> ok bcook@
-rw-r--r--src/lib/libcrypto/ocsp/ocsp_cl.c38
-rw-r--r--src/lib/libssl/src/crypto/ocsp/ocsp_cl.c38
2 files changed, 62 insertions, 14 deletions
diff --git a/src/lib/libcrypto/ocsp/ocsp_cl.c b/src/lib/libcrypto/ocsp/ocsp_cl.c
index a4320d9278..83615e5434 100644
--- a/src/lib/libcrypto/ocsp/ocsp_cl.c
+++ b/src/lib/libcrypto/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.9 2016/06/25 15:38:44 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_cl.c b/src/lib/libssl/src/crypto/ocsp/ocsp_cl.c
index a4320d9278..83615e5434 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.9 2016/06/25 15:38:44 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;