| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/cert_net/nss_ocsp.h" | 5 #include "net/cert_net/nss_ocsp.h" |
| 6 | 6 |
| 7 #include <certt.h> | 7 #include <certt.h> |
| 8 #include <certdb.h> | 8 #include <certdb.h> |
| 9 #include <nspr.h> | 9 #include <nspr.h> |
| 10 #include <nss.h> | 10 #include <nss.h> |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 *pPollDesc = NULL; | 721 *pPollDesc = NULL; |
| 722 | 722 |
| 723 if (req->Started() || req->Finished()) { | 723 if (req->Started() || req->Finished()) { |
| 724 // We support blocking mode only, so this function shouldn't be called | 724 // We support blocking mode only, so this function shouldn't be called |
| 725 // again when req has stareted or finished. | 725 // again when req has stareted or finished. |
| 726 NOTREACHED(); | 726 NOTREACHED(); |
| 727 PORT_SetError(SEC_ERROR_BAD_HTTP_RESPONSE); // Simple approximation. | 727 PORT_SetError(SEC_ERROR_BAD_HTTP_RESPONSE); // Simple approximation. |
| 728 return SECFailure; | 728 return SECFailure; |
| 729 } | 729 } |
| 730 | 730 |
| 731 const base::Time start_time = base::Time::Now(); | |
| 732 bool request_ok = true; | |
| 733 req->Start(); | 731 req->Start(); |
| 734 if (!req->Wait() || req->http_response_code() == static_cast<PRUint16>(-1)) { | 732 if (!req->Wait() || req->http_response_code() == static_cast<PRUint16>(-1)) { |
| 735 // If the response code is -1, the request failed and there is no response. | 733 // If the response code is -1, the request failed and there is no response. |
| 736 request_ok = false; | |
| 737 } | |
| 738 const base::TimeDelta duration = base::Time::Now() - start_time; | |
| 739 | |
| 740 // For metrics, we want to know if the request was 'successful' or not. | |
| 741 // |request_ok| determines if we'll pass the response back to NSS and |ok| | |
| 742 // keep track of if we think the response was good. | |
| 743 bool ok = true; | |
| 744 if (!request_ok || | |
| 745 (req->http_response_code() >= 400 && req->http_response_code() < 600) || | |
| 746 req->http_response_data().size() == 0 || | |
| 747 // 0x30 is the ASN.1 DER encoding of a SEQUENCE. All valid OCSP/CRL/CRT | |
| 748 // responses must start with this. If we didn't check for this then a | |
| 749 // captive portal could provide an HTML reply that we would count as a | |
| 750 // 'success' (although it wouldn't count in NSS, of course). | |
| 751 req->http_response_data().data()[0] != 0x30) { | |
| 752 ok = false; | |
| 753 } | |
| 754 | |
| 755 // We want to know if this was: | |
| 756 // 1) An OCSP request | |
| 757 // 2) A CRL request | |
| 758 // 3) A request for a missing intermediate certificate | |
| 759 // There's no sure way to do this, so we use heuristics like MIME type and | |
| 760 // URL. | |
| 761 const char* mime_type = ""; | |
| 762 if (ok) | |
| 763 mime_type = req->http_response_content_type().c_str(); | |
| 764 bool is_ocsp = | |
| 765 strcasecmp(mime_type, "application/ocsp-response") == 0; | |
| 766 bool is_crl = strcasecmp(mime_type, "application/x-pkcs7-crl") == 0 || | |
| 767 strcasecmp(mime_type, "application/x-x509-crl") == 0 || | |
| 768 strcasecmp(mime_type, "application/pkix-crl") == 0; | |
| 769 bool is_cert = | |
| 770 strcasecmp(mime_type, "application/x-x509-ca-cert") == 0 || | |
| 771 strcasecmp(mime_type, "application/x-x509-server-cert") == 0 || | |
| 772 strcasecmp(mime_type, "application/pkix-cert") == 0 || | |
| 773 strcasecmp(mime_type, "application/pkcs7-mime") == 0; | |
| 774 | |
| 775 if (!is_cert && !is_crl && !is_ocsp) { | |
| 776 // We didn't get a hint from the MIME type, so do the best that we can. | |
| 777 const std::string path = req->url().path(); | |
| 778 const std::string host = req->url().host(); | |
| 779 is_crl = strcasestr(path.c_str(), ".crl") != NULL; | |
| 780 is_cert = strcasestr(path.c_str(), ".crt") != NULL || | |
| 781 strcasestr(path.c_str(), ".p7c") != NULL || | |
| 782 strcasestr(path.c_str(), ".cer") != NULL; | |
| 783 is_ocsp = strcasestr(host.c_str(), "ocsp") != NULL || | |
| 784 req->http_request_method() == "POST"; | |
| 785 } | |
| 786 | |
| 787 if (is_ocsp) { | |
| 788 if (ok) { | |
| 789 UMA_HISTOGRAM_TIMES("Net.OCSPRequestTimeMs", duration); | |
| 790 UMA_HISTOGRAM_BOOLEAN("Net.OCSPRequestSuccess", true); | |
| 791 } else { | |
| 792 UMA_HISTOGRAM_TIMES("Net.OCSPRequestFailedTimeMs", duration); | |
| 793 UMA_HISTOGRAM_BOOLEAN("Net.OCSPRequestSuccess", false); | |
| 794 } | |
| 795 } else if (is_crl) { | |
| 796 if (ok) { | |
| 797 UMA_HISTOGRAM_TIMES("Net.CRLRequestTimeMs", duration); | |
| 798 UMA_HISTOGRAM_BOOLEAN("Net.CRLRequestSuccess", true); | |
| 799 } else { | |
| 800 UMA_HISTOGRAM_TIMES("Net.CRLRequestFailedTimeMs", duration); | |
| 801 UMA_HISTOGRAM_BOOLEAN("Net.CRLRequestSuccess", false); | |
| 802 } | |
| 803 } else if (is_cert) { | |
| 804 if (ok) | |
| 805 UMA_HISTOGRAM_TIMES("Net.CRTRequestTimeMs", duration); | |
| 806 } else { | |
| 807 if (ok) | |
| 808 UMA_HISTOGRAM_TIMES("Net.UnknownTypeRequestTimeMs", duration); | |
| 809 } | |
| 810 | |
| 811 if (!request_ok) { | |
| 812 PORT_SetError(SEC_ERROR_BAD_HTTP_RESPONSE); // Simple approximation. | 734 PORT_SetError(SEC_ERROR_BAD_HTTP_RESPONSE); // Simple approximation. |
| 813 return SECFailure; | 735 return SECFailure; |
| 814 } | 736 } |
| 815 | 737 |
| 816 return OCSPSetResponse( | 738 return OCSPSetResponse( |
| 817 req, http_response_code, | 739 req, http_response_code, |
| 818 http_response_content_type, | 740 http_response_content_type, |
| 819 http_response_headers, | 741 http_response_headers, |
| 820 http_response_data, | 742 http_response_data, |
| 821 http_response_data_len); | 743 http_response_data_len); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) { | 866 void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) { |
| 945 pthread_mutex_lock(&g_request_context_lock); | 867 pthread_mutex_lock(&g_request_context_lock); |
| 946 if (request_context) { | 868 if (request_context) { |
| 947 DCHECK(!g_request_context); | 869 DCHECK(!g_request_context); |
| 948 } | 870 } |
| 949 g_request_context = request_context; | 871 g_request_context = request_context; |
| 950 pthread_mutex_unlock(&g_request_context_lock); | 872 pthread_mutex_unlock(&g_request_context_lock); |
| 951 } | 873 } |
| 952 | 874 |
| 953 } // namespace net | 875 } // namespace net |
| OLD | NEW |