From 5b23427b37d8c082c8050d5cfdba734a5c6026db Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 22 Nov 2019 14:59:49 +0100 Subject: [PATCH 1/4] credentials: Add getter for nonce in OCSP request and response interface --- src/libstrongswan/credentials/certificates/ocsp_request.h | 8 ++++++++ .../credentials/certificates/ocsp_response.h | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/libstrongswan/credentials/certificates/ocsp_request.h b/src/libstrongswan/credentials/certificates/ocsp_request.h index 508a65f3e..d47514bf4 100644 --- a/src/libstrongswan/credentials/certificates/ocsp_request.h +++ b/src/libstrongswan/credentials/certificates/ocsp_request.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2019 Tobias Brunner * Copyright (C) 2008 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -34,6 +35,13 @@ struct ocsp_request_t { * Implements certificate_t interface */ certificate_t interface; + + /** + * Get the nonce sent in this OCSP request. + * + * @return nonce in the request (internal data) + */ + chunk_t (*get_nonce)(ocsp_request_t *this); }; #endif /** OCSP_REQUEST_H_ @}*/ diff --git a/src/libstrongswan/credentials/certificates/ocsp_response.h b/src/libstrongswan/credentials/certificates/ocsp_response.h index e701061d7..581c9da2d 100644 --- a/src/libstrongswan/credentials/certificates/ocsp_response.h +++ b/src/libstrongswan/credentials/certificates/ocsp_response.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2019 Tobias Brunner * Copyright (C) 2008 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -54,6 +55,13 @@ struct ocsp_response_t { */ certificate_t certificate; + /** + * Get the nonce received with this OCSP response. + * + * @return nonce in the response (internal data) + */ + chunk_t (*get_nonce)(ocsp_response_t *this); + /** * Check the status of a certificate by this OCSP response. * From 5333db58ac4cade55bb0a4c58a541e47c737a811 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 22 Nov 2019 15:04:01 +0100 Subject: [PATCH 2/4] x509: Add getter for nonce in OCSP request/response implementations --- src/libstrongswan/plugins/x509/x509_ocsp_request.c | 8 ++++++++ src/libstrongswan/plugins/x509/x509_ocsp_response.c | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c index 50e3c6160..58270d3b4 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2017-2019 Tobias Brunner * Copyright (C) 2008-2009 Martin Willi * Copyright (C) 2007-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil @@ -464,6 +465,12 @@ METHOD(certificate_t, destroy, void, } } +METHOD(ocsp_request_t, get_nonce, chunk_t, + private_x509_ocsp_request_t *this) +{ + return this->nonce; +} + /** * create an empty but initialized OCSP request */ @@ -488,6 +495,7 @@ static private_x509_ocsp_request_t *create_empty() .get_ref = _get_ref, .destroy = _destroy, }, + .get_nonce = _get_nonce, }, }, .candidates = linked_list_create(), diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c index aa4999cbd..75eb9d779 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Tobias Brunner + * Copyright (C) 2017-2019 Tobias Brunner * Copyright (C) 2008-2009 Martin Willi * Copyright (C) 2007-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil @@ -271,6 +271,12 @@ METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*, filter, NULL, NULL); } +METHOD(ocsp_response_t, get_nonce, chunk_t, + private_x509_ocsp_response_t *this) +{ + return this->nonce; +} + /** * ASN.1 definition of singleResponse */ @@ -871,6 +877,7 @@ static x509_ocsp_response_t *load(chunk_t blob) .get_ref = _get_ref, .destroy = _destroy, }, + .get_nonce = _get_nonce, .get_status = _get_status, .create_cert_enumerator = _create_cert_enumerator, .create_response_enumerator = _create_response_enumerator, From cd0e4d5297882b88b17e52ba7bc042764771e352 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 22 Nov 2019 16:36:20 +0100 Subject: [PATCH 3/4] x509: Correctly parse nonce in OCSP response Fixes: d7dc677ee572 ("x509: Correctly encode nonce in OCSP request") --- src/libstrongswan/plugins/x509/x509_ocsp_response.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c index 75eb9d779..f3ade37e4 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c @@ -577,7 +577,9 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this, DBG2(DBG_ASN, " %s", critical ? "TRUE" : "FALSE"); break; case BASIC_RESPONSE_EXT_VALUE: - if (extn_oid == OID_NONCE) + if (extn_oid == OID_NONCE && + asn1_parse_simple_object(&object, ASN1_OCTET_STRING, + parser->get_level(parser)+1, "nonce")) { this->nonce = object; } From 27756b081c1b894d579961b088e2a12ae841874b Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 22 Nov 2019 15:09:55 +0100 Subject: [PATCH 4/4] revocation: Check that nonce in OCSP response matches --- .../plugins/revocation/revocation_validator.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/plugins/revocation/revocation_validator.c b/src/libstrongswan/plugins/revocation/revocation_validator.c index 68292e3cd..d2f662dc6 100644 --- a/src/libstrongswan/plugins/revocation/revocation_validator.c +++ b/src/libstrongswan/plugins/revocation/revocation_validator.c @@ -64,6 +64,8 @@ static certificate_t *fetch_ocsp(char *url, certificate_t *subject, certificate_t *issuer) { certificate_t *request, *response; + ocsp_request_t *ocsp_request; + ocsp_response_t *ocsp_response; chunk_t send, receive = chunk_empty; /* TODO: requestor name, signature */ @@ -83,7 +85,6 @@ static certificate_t *fetch_ocsp(char *url, certificate_t *subject, request->destroy(request); return NULL; } - request->destroy(request); DBG1(DBG_CFG, " requesting ocsp status from '%s' ...", url); if (lib->fetcher->fetch(lib->fetcher, url, &receive, @@ -92,6 +93,7 @@ static certificate_t *fetch_ocsp(char *url, certificate_t *subject, FETCH_END) != SUCCESS) { DBG1(DBG_CFG, "ocsp request to %s failed", url); + request->destroy(request); chunk_free(&receive); chunk_free(&send); return NULL; @@ -105,8 +107,19 @@ static certificate_t *fetch_ocsp(char *url, certificate_t *subject, if (!response) { DBG1(DBG_CFG, "parsing ocsp response failed"); + request->destroy(request); return NULL; } + ocsp_request = (ocsp_request_t*)request; + ocsp_response = (ocsp_response_t*)response; + if (!chunk_equals_const(ocsp_request->get_nonce(ocsp_request), + ocsp_response->get_nonce(ocsp_response))) + { + DBG1(DBG_CFG, "nonce in ocsp response doesn't match"); + request->destroy(request); + return NULL; + } + request->destroy(request); return response; }