diff options
author | beck <> | 2016-06-25 15:38:44 +0000 |
---|---|---|
committer | beck <> | 2016-06-25 15:38:44 +0000 |
commit | e3be7f350ab12561f21fccc6641ed88238c551f4 (patch) | |
tree | 9ff83921432b7ebf58639bb6a0e1973fa56c4eca | |
parent | b789abd90ce8dc508846bc7556ffad3b18c4cd06 (diff) | |
download | openbsd-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.c | 38 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/ocsp/ocsp_cl.c | 38 |
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 | ||
74 | int asn1_time_parse(const char *, size_t, struct tm *, int); | ||
75 | int 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 | ||
74 | int asn1_time_parse(const char *, size_t, struct tm *, int); | ||
75 | int 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; |