Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: nss/lib/certhigh/ocsp.c

Issue 13898013: Update NSS to NSS_3_15_BETA2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Update NSS versions and tag in README.chromium Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 4
5 /* 5 /*
6 * Implementation of OCSP services, for both client and server. 6 * Implementation of OCSP services, for both client and server.
7 * (XXX, really, mostly just for client right now, but intended to do both.) 7 * (XXX, really, mostly just for client right now, but intended to do both.)
8 * 8 *
9 * $Id$ 9 * $Id$
10 */ 10 */
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 void *pwArg, 117 void *pwArg,
118 PRBool *certIDWasConsumed, 118 PRBool *certIDWasConsumed,
119 SECStatus *rv_ocsp); 119 SECStatus *rv_ocsp);
120 120
121 static SECStatus 121 static SECStatus
122 ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle, 122 ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle,
123 CERTOCSPCertID *certID, 123 CERTOCSPCertID *certID,
124 CERTCertificate *cert, 124 CERTCertificate *cert,
125 int64 time, 125 int64 time,
126 void *pwArg, 126 void *pwArg,
127 » » » SECItem *encodedResponse, 127 » » » const SECItem *encodedResponse,
128 » » » PRBool cacheInvalid,
128 PRBool *certIDWasConsumed, 129 PRBool *certIDWasConsumed,
129 PRBool cacheNegative,
130 SECStatus *rv_ocsp); 130 SECStatus *rv_ocsp);
131 131
132 static SECStatus 132 static SECStatus
133 ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle, 133 ocsp_GetVerifiedSingleResponseForCertID(CERTCertDBHandle *handle,
134 CERTOCSPResponse *response, 134 CERTOCSPResponse *response,
135 CERTOCSPCertID *certID, 135 CERTOCSPCertID *certID,
136 CERTCertificate *signerCert, 136 CERTCertificate *signerCert,
137 int64 time, 137 int64 time,
138 CERTOCSPSingleResponse **pSingleResponse ); 138 CERTOCSPSingleResponse **pSingleResponse );
139 139
140 static SECStatus 140 static SECStatus
141 ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, int64 time); 141 ocsp_CertRevokedAfter(ocspRevokedInfo *revokedInfo, int64 time);
142 142
143 static CERTOCSPCertID *
144 cert_DupOCSPCertID(CERTOCSPCertID *src);
wtc 2013/04/24 22:49:45 The argument should be 'const'.
145
143 #ifndef DEBUG 146 #ifndef DEBUG
144 #define OCSP_TRACE(msg) 147 #define OCSP_TRACE(msg)
145 #define OCSP_TRACE_TIME(msg, time) 148 #define OCSP_TRACE_TIME(msg, time)
146 #define OCSP_TRACE_CERT(cert) 149 #define OCSP_TRACE_CERT(cert)
147 #define OCSP_TRACE_CERTID(certid) 150 #define OCSP_TRACE_CERTID(certid)
148 #else 151 #else
149 #define OCSP_TRACE(msg) ocsp_Trace msg 152 #define OCSP_TRACE(msg) ocsp_Trace msg
150 #define OCSP_TRACE_TIME(msg, time) ocsp_dumpStringWithTime(msg, time) 153 #define OCSP_TRACE_TIME(msg, time) ocsp_dumpStringWithTime(msg, time)
151 #define OCSP_TRACE_CERT(cert) dumpCertificate(cert) 154 #define OCSP_TRACE_CERT(cert) dumpCertificate(cert)
152 #define OCSP_TRACE_CERTID(certid) dumpCertID(certid) 155 #define OCSP_TRACE_CERTID(certid) dumpCertID(certid)
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 now = PR_Now(); 762 now = PR_Now();
760 retval = (cacheItem->nextFetchAttemptTime > now); 763 retval = (cacheItem->nextFetchAttemptTime > now);
761 OCSP_TRACE(("OCSP ocsp_IsCacheItemFresh: %d\n", retval)); 764 OCSP_TRACE(("OCSP ocsp_IsCacheItemFresh: %d\n", retval));
762 PR_ExitMonitor(OCSP_Global.monitor); 765 PR_ExitMonitor(OCSP_Global.monitor);
763 return retval; 766 return retval;
764 } 767 }
765 768
766 /* 769 /*
767 * Status in *certIDWasConsumed will always be correct, regardless of 770 * Status in *certIDWasConsumed will always be correct, regardless of
768 * return value. 771 * return value.
772 * If the caller is unable to transfer ownership of certID,
773 * then the caller must set certIDWasConsumed to NULL,
774 * and this function will potentially duplicate the certID object.
769 */ 775 */
770 static SECStatus 776 static SECStatus
771 ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache, 777 ocsp_CreateOrUpdateCacheEntry(OCSPCacheData *cache,
772 CERTOCSPCertID *certID, 778 CERTOCSPCertID *certID,
773 CERTOCSPSingleResponse *single, 779 CERTOCSPSingleResponse *single,
774 PRBool *certIDWasConsumed) 780 PRBool *certIDWasConsumed)
775 { 781 {
776 SECStatus rv; 782 SECStatus rv;
777 OCSPCacheItem *cacheItem; 783 OCSPCacheItem *cacheItem;
778 OCSP_TRACE(("OCSP ocsp_CreateOrUpdateCacheEntry\n")); 784 OCSP_TRACE(("OCSP ocsp_CreateOrUpdateCacheEntry\n"));
779 785
780 if (!certIDWasConsumed) { 786 if (certIDWasConsumed)
781 PORT_SetError(SEC_ERROR_INVALID_ARGS);
782 return SECFailure;
783 }
784 *certIDWasConsumed = PR_FALSE; 787 *certIDWasConsumed = PR_FALSE;
wtc 2013/04/24 22:49:45 We should fix the indentation.
785 788
786 PR_EnterMonitor(OCSP_Global.monitor); 789 PR_EnterMonitor(OCSP_Global.monitor);
787 PORT_Assert(OCSP_Global.maxCacheEntries >= 0); 790 PORT_Assert(OCSP_Global.maxCacheEntries >= 0);
788 791
789 cacheItem = ocsp_FindCacheEntry(cache, certID); 792 cacheItem = ocsp_FindCacheEntry(cache, certID);
790 if (!cacheItem) { 793 if (!cacheItem) {
791 rv = ocsp_CreateCacheItemAndConsumeCertID(cache, certID, 794 CERTOCSPCertID *myCertID;
795 if (certIDWasConsumed) {
796 myCertID = certID;
797 *certIDWasConsumed = PR_TRUE;
798 } else {
799 myCertID = cert_DupOCSPCertID(certID);
800 if (!myCertID) {
801 PR_ExitMonitor(OCSP_Global.monitor);
802 PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
803 return SECFailure;
804 }
805 }
806
807 rv = ocsp_CreateCacheItemAndConsumeCertID(cache, myCertID,
792 &cacheItem); 808 &cacheItem);
793 if (rv != SECSuccess) { 809 if (rv != SECSuccess) {
794 PR_ExitMonitor(OCSP_Global.monitor); 810 PR_ExitMonitor(OCSP_Global.monitor);
795 return rv; 811 return rv;
796 } 812 }
797 *certIDWasConsumed = PR_TRUE;
798 } 813 }
799 if (single) { 814 if (single) {
800 rv = ocsp_SetCacheItemResponse(cacheItem, single); 815 PRTime thisUpdate;
801 if (rv != SECSuccess) { 816 rv = DER_GeneralizedTimeToTime(&thisUpdate, &single->thisUpdate);
802 ocsp_RemoveCacheItem(cache, cacheItem); 817
803 PR_ExitMonitor(OCSP_Global.monitor); 818 if (!cacheItem->haveThisUpdate ||
804 return rv; 819 (rv == SECSuccess && cacheItem->thisUpdate < thisUpdate)) {
820 rv = ocsp_SetCacheItemResponse(cacheItem, single);
821 if (rv != SECSuccess) {
822 ocsp_RemoveCacheItem(cache, cacheItem);
823 PR_ExitMonitor(OCSP_Global.monitor);
824 return rv;
825 }
826 } else {
827 OCSP_TRACE(("Not caching response because the response is not newer than the cache"));
wtc 2013/04/24 22:49:45 Fold this long line.
805 } 828 }
806 } else { 829 } else {
807 cacheItem->missingResponseError = PORT_GetError(); 830 cacheItem->missingResponseError = PORT_GetError();
831 if (cacheItem->certStatusArena) {
832 PORT_FreeArena(cacheItem->certStatusArena, PR_FALSE);
833 cacheItem->certStatusArena = NULL;
834 }
808 } 835 }
809 ocsp_FreshenCacheItemNextFetchAttemptTime(cacheItem); 836 ocsp_FreshenCacheItemNextFetchAttemptTime(cacheItem);
810 ocsp_CheckCacheSize(cache); 837 ocsp_CheckCacheSize(cache);
811 838
812 PR_ExitMonitor(OCSP_Global.monitor); 839 PR_ExitMonitor(OCSP_Global.monitor);
813 return SECSuccess; 840 return SECSuccess;
814 } 841 }
815 842
816 extern SECStatus 843 extern SECStatus
817 CERT_SetOCSPFailureMode(SEC_OcspFailureMode ocspFailureMode) 844 CERT_SetOCSPFailureMode(SEC_OcspFailureMode ocspFailureMode)
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
1538 } 1565 }
1539 1566
1540 /* 1567 /*
1541 * Digest data using the specified algorithm. 1568 * Digest data using the specified algorithm.
1542 * The necessary storage for the digest data is allocated. If "fill" is 1569 * The necessary storage for the digest data is allocated. If "fill" is
1543 * non-null, the data is put there, otherwise a SECItem is allocated. 1570 * non-null, the data is put there, otherwise a SECItem is allocated.
1544 * Allocation from "arena" if it is non-null, heap otherwise. Any problem 1571 * Allocation from "arena" if it is non-null, heap otherwise. Any problem
1545 * results in a NULL being returned (and an appropriate error set). 1572 * results in a NULL being returned (and an appropriate error set).
1546 */ 1573 */
1547 1574
1548 static SECItem * 1575 SECItem *
1549 ocsp_DigestValue(PRArenaPool *arena, SECOidTag digestAlg, 1576 ocsp_DigestValue(PRArenaPool *arena, SECOidTag digestAlg,
1550 SECItem *fill, const SECItem *src) 1577 SECItem *fill, const SECItem *src)
1551 { 1578 {
1552 const SECHashObject *digestObject; 1579 const SECHashObject *digestObject;
1553 SECItem *result = NULL; 1580 SECItem *result = NULL;
1554 void *mark = NULL; 1581 void *mark = NULL;
1555 void *digestBuff = NULL; 1582 void *digestBuff = NULL;
1556 1583
1557 if ( arena != NULL ) { 1584 if ( arena != NULL ) {
1558 mark = PORT_ArenaMark(arena); 1585 mark = PORT_ArenaMark(arena);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 1772
1746 certID = ocsp_CreateCertID(arena, cert, time); 1773 certID = ocsp_CreateCertID(arena, cert, time);
1747 if (!certID) { 1774 if (!certID) {
1748 PORT_FreeArena(arena, PR_FALSE); 1775 PORT_FreeArena(arena, PR_FALSE);
1749 return NULL; 1776 return NULL;
1750 } 1777 }
1751 certID->poolp = arena; 1778 certID->poolp = arena;
1752 return certID; 1779 return certID;
1753 } 1780 }
1754 1781
1782 static CERTOCSPCertID *
1783 cert_DupOCSPCertID(CERTOCSPCertID *src)
1784 {
1785 CERTOCSPCertID *dest;
1786 PRArenaPool *arena = NULL;
1787
1788 if (!src) {
1789 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1790 return NULL;
1791 }
1792
1793 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
1794 if (!arena)
1795 goto loser;
1796
1797 dest = PORT_ArenaZNew(arena, CERTOCSPCertID);
1798 if (!dest)
wtc 2013/04/24 22:49:45 Fix indentation.
1799 goto loser;
1800
1801 #define DUPHELP(element) \
1802 if (src->element.data) { \
1803 if (SECITEM_CopyItem(arena, &dest->element, &src->element) \
1804 != SECSuccess) \
1805 goto loser; \
wtc 2013/04/24 22:49:45 Add curly braces. Combine nested ifs using &&.
1806 }
1807
1808 DUPHELP(hashAlgorithm.algorithm)
1809 DUPHELP(hashAlgorithm.parameters)
1810 DUPHELP(issuerNameHash)
1811 DUPHELP(issuerKeyHash)
1812 DUPHELP(serialNumber)
1813 DUPHELP(issuerSHA1NameHash)
1814 DUPHELP(issuerMD5NameHash)
1815 DUPHELP(issuerMD2NameHash)
1816 DUPHELP(issuerSHA1KeyHash)
1817 DUPHELP(issuerMD5KeyHash)
1818 DUPHELP(issuerMD2KeyHash)
1819
1820 dest->poolp = arena;
1821 return dest;
1822
1823 loser:
1824 if (arena)
1825 PORT_FreeArena(arena, PR_FALSE);
1826 PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
1827 return NULL;
1828 }
1829
1755 /* 1830 /*
1756 * Callback to set Extensions in request object 1831 * Callback to set Extensions in request object
1757 */ 1832 */
1758 void SetSingleReqExts(void *object, CERTCertExtension **exts) 1833 void SetSingleReqExts(void *object, CERTCertExtension **exts)
1759 { 1834 {
1760 ocspSingleRequest *singleRequest = 1835 ocspSingleRequest *singleRequest =
1761 (ocspSingleRequest *)object; 1836 (ocspSingleRequest *)object;
1762 1837
1763 singleRequest->singleRequestExtensions = exts; 1838 singleRequest->singleRequestExtensions = exts;
1764 } 1839 }
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
2528 * SECItem *src 2603 * SECItem *src
2529 * Pointer to a SECItem holding DER encoded OCSP Response. 2604 * Pointer to a SECItem holding DER encoded OCSP Response.
2530 * RETURN: 2605 * RETURN:
2531 * Returns a pointer to a CERTOCSPResponse (the decoded OCSP Response); 2606 * Returns a pointer to a CERTOCSPResponse (the decoded OCSP Response);
2532 * the caller is responsible for destroying it. Or NULL if error (either 2607 * the caller is responsible for destroying it. Or NULL if error (either
2533 * response could not be decoded (SEC_ERROR_OCSP_MALFORMED_RESPONSE), 2608 * response could not be decoded (SEC_ERROR_OCSP_MALFORMED_RESPONSE),
2534 * it was of an unexpected type (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE), 2609 * it was of an unexpected type (SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE),
2535 * or a low-level or internal error occurred). 2610 * or a low-level or internal error occurred).
2536 */ 2611 */
2537 CERTOCSPResponse * 2612 CERTOCSPResponse *
2538 CERT_DecodeOCSPResponse(SECItem *src) 2613 CERT_DecodeOCSPResponse(const SECItem *src)
2539 { 2614 {
2540 PRArenaPool *arena = NULL; 2615 PRArenaPool *arena = NULL;
2541 CERTOCSPResponse *response = NULL; 2616 CERTOCSPResponse *response = NULL;
2542 SECStatus rv = SECFailure; 2617 SECStatus rv = SECFailure;
2543 ocspResponseStatus sv; 2618 ocspResponseStatus sv;
2544 SECItem newSrc; 2619 SECItem newSrc;
2545 2620
2546 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 2621 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
2547 if (arena == NULL) { 2622 if (arena == NULL) {
2548 goto loser; 2623 goto loser;
(...skipping 2261 matching lines...) Expand 10 before | Expand all | Expand 10 after
4810 * void *pwArg 4885 * void *pwArg
4811 * argument for password prompting, if needed 4886 * argument for password prompting, if needed
4812 * RETURN: 4887 * RETURN:
4813 * SECSuccess if the cert was found in the cache, or if the OCSP response was 4888 * SECSuccess if the cert was found in the cache, or if the OCSP response was
4814 * found to be valid and inserted into the cache. SECFailure otherwise. 4889 * found to be valid and inserted into the cache. SECFailure otherwise.
4815 */ 4890 */
4816 SECStatus 4891 SECStatus
4817 CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle, 4892 CERT_CacheOCSPResponseFromSideChannel(CERTCertDBHandle *handle,
4818 CERTCertificate *cert, 4893 CERTCertificate *cert,
4819 int64 time, 4894 int64 time,
4820 » » » » SECItem *encodedResponse, 4895 » » » » const SECItem *encodedResponse,
4821 void *pwArg) 4896 void *pwArg)
4822 { 4897 {
4823 CERTOCSPCertID *certID; 4898 CERTOCSPCertID *certID = NULL;
4824 PRBool certIDWasConsumed = PR_FALSE; 4899 PRBool certIDWasConsumed = PR_FALSE;
4825 SECStatus rv = SECFailure; 4900 SECStatus rv = SECFailure;
4826 SECStatus rvOcsp; 4901 SECStatus rvOcsp;
4827 SECErrorCodes dummy_error_code; /* we ignore this */ 4902 SECErrorCodes dummy_error_code; /* we ignore this */
4828 4903
4904 /* The OCSP cache can be in three states regarding this certificate:
4905 * + Good (cached, timely, 'good' response, or revoked in the future)
4906 * + Revoked (cached, timely, but doesn't fit in the last category)
4907 * + Miss (no knowledge)
4908 *
4909 * Likewise, the side-channel information can be
4910 * + Good (timely, 'good' response, or revoked in the future)
4911 * + Revoked (timely, but doesn't fit in the last category)
4912 * + Invalid (bad syntax, bad signature, not timely etc)
4913 *
4914 * The common case is that the cache result is Good and so is the
4915 * side-channel information. We want to save processing time in this case
4916 * so we say that any time we see a Good result from the cache we return
4917 * early.
4918 *
4919 * Cache result
4920 * | Good Revoked Miss
4921 * ---+--------------------------------------------
4922 * G | noop Cache more Cache it
4923 * S | recent result
4924 * i |
4925 * d |
4926 * e |
4927 * R | noop Cache more Cache it
4928 * C | recent result
4929 * h |
4930 * a |
4931 * n |
4932 * n I | noop Noop Noop
4933 * e |
4934 * l |
4935 *
4936 * When we fetch from the network we might choose to cache a negative
4937 * result when the response is invalid. This saves us hammering, uselessly,
4938 * at a broken responder. However, side channels are commonly attacker
4939 * controlled and so we must not cache a negative result for an Invalid
4940 * side channel.
4941 */
4942
4943 if (!cert) {
4944 PORT_SetError(SEC_ERROR_INVALID_ARGS);
4945 return SECFailure;
4946 }
4829 certID = CERT_CreateOCSPCertID(cert, time); 4947 certID = CERT_CreateOCSPCertID(cert, time);
4830 if (!certID) 4948 if (!certID)
4831 return SECFailure; 4949 return SECFailure;
4832 rv = ocsp_GetCachedOCSPResponseStatusIfFresh( 4950 rv = ocsp_GetCachedOCSPResponseStatusIfFresh(
4833 certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */ 4951 certID, time, PR_FALSE, /* ignoreGlobalOcspFailureSetting */
4834 &rvOcsp, &dummy_error_code); 4952 &rvOcsp, &dummy_error_code);
4835 if (rv == SECSuccess && rvOcsp == SECSuccess) { 4953 if (rv == SECSuccess && rvOcsp == SECSuccess) {
4836 » /* The cached value is good. We don't want to waste time validating 4954 /* The cached value is good. We don't want to waste time validating
4837 » * this OCSP response. */ 4955 * this OCSP response. This is the first column in the table above. */
4838 CERT_DestroyOCSPCertID(certID); 4956 CERT_DestroyOCSPCertID(certID);
4839 return rv; 4957 return rv;
4840 } 4958 }
4841 4959
4842 /* Since the OCSP response came from a side channel it is attacker 4960 /* The logic for caching the more recent response is handled in
4843 * controlled. The attacker can have chosen any valid OCSP response, 4961 * ocsp_CreateOrUpdateCacheEntry, which is called by this function. */
4844 * including responses from the past. In this case, 4962 rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time,
4845 * ocsp_GetVerifiedSingleResponseForCertID will fail. If we recorded a 4963 pwArg, encodedResponse,
4846 * negative cache entry in this case, then the attacker would have 4964 PR_FALSE /* don't cache if invalid */,
4847 * 'poisoned' our cache (denial of service), so we don't record negative 4965 &certIDWasConsumed,
4848 * results. */
4849 rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time, pwArg,
4850 encodedResponse, &certIDWasConsumed,
4851 PR_FALSE /* don't cache failures */,
4852 &rvOcsp); 4966 &rvOcsp);
4853 if (!certIDWasConsumed) { 4967 if (!certIDWasConsumed) {
4854 CERT_DestroyOCSPCertID(certID); 4968 CERT_DestroyOCSPCertID(certID);
4855 } 4969 }
4856 return rv == SECSuccess ? rvOcsp : rv; 4970 return rv == SECSuccess ? rvOcsp : rv;
4857 } 4971 }
4858 4972
4859 /* 4973 /*
4860 * Status in *certIDWasConsumed will always be correct, regardless of 4974 * Status in *certIDWasConsumed will always be correct, regardless of
4861 * return value. 4975 * return value.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4929 */ 5043 */
4930 encodedResponse = 5044 encodedResponse =
4931 ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert, location, 5045 ocsp_GetEncodedOCSPResponseForSingleCert(NULL, certID, cert, location,
4932 time, locationIsDefault, 5046 time, locationIsDefault,
4933 pwArg, &request); 5047 pwArg, &request);
4934 if (encodedResponse == NULL) { 5048 if (encodedResponse == NULL) {
4935 goto loser; 5049 goto loser;
4936 } 5050 }
4937 5051
4938 rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time, pwArg, 5052 rv = ocsp_CacheEncodedOCSPResponse(handle, certID, cert, time, pwArg,
4939 » encodedResponse, certIDWasConsumed, 5053 encodedResponse,
4940 » PR_TRUE /* cache failures */, rv_ocsp); 5054 PR_TRUE /* cache if invalid */,
5055 certIDWasConsumed, rv_ocsp);
4941 5056
4942 loser: 5057 loser:
4943 if (request != NULL) 5058 if (request != NULL)
4944 CERT_DestroyOCSPRequest(request); 5059 CERT_DestroyOCSPRequest(request);
4945 if (encodedResponse != NULL) 5060 if (encodedResponse != NULL)
4946 SECITEM_FreeItem(encodedResponse, PR_TRUE); 5061 SECITEM_FreeItem(encodedResponse, PR_TRUE);
4947 if (location != NULL) 5062 if (location != NULL)
4948 PORT_Free(location); 5063 PORT_Free(location);
4949 5064
4950 return rv; 5065 return rv;
(...skipping 17 matching lines...) Expand all
4968 * CERTOCSPCertID *certID 5083 * CERTOCSPCertID *certID
4969 * the cert ID corresponding to |cert| 5084 * the cert ID corresponding to |cert|
4970 * CERTCertificate *cert 5085 * CERTCertificate *cert
4971 * the certificate being checked 5086 * the certificate being checked
4972 * int64 time 5087 * int64 time
4973 * time for which status is to be determined 5088 * time for which status is to be determined
4974 * void *pwArg 5089 * void *pwArg
4975 * the opaque argument to the password prompting function. 5090 * the opaque argument to the password prompting function.
4976 * SECItem *encodedResponse 5091 * SECItem *encodedResponse
4977 * the DER encoded bytes of the OCSP response 5092 * the DER encoded bytes of the OCSP response
5093 * PRBool cacheInvalid
5094 * If true then invalid responses will cause a negative cache entry to be
5095 * created. (Invalid means bad syntax, bad signature etc)
4978 * PRBool *certIDWasConsumed 5096 * PRBool *certIDWasConsumed
4979 * (output) on return, this is true iff |certID| was consumed by this 5097 * (output) on return, this is true iff |certID| was consumed by this
4980 * function. 5098 * function.
4981 * SECStatus *rv_ocsp 5099 * SECStatus *rv_ocsp
4982 * (output) on return, this is SECSuccess iff the response is good (see 5100 * (output) on return, this is SECSuccess iff the response is good (see
4983 * definition of 'good' above). 5101 * definition of 'good' above).
4984 * RETURN: 5102 * RETURN:
4985 * SECSuccess iff the response is valid. 5103 * SECSuccess iff the response is valid.
4986 */ 5104 */
4987 static SECStatus 5105 static SECStatus
4988 ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle, 5106 ocsp_CacheEncodedOCSPResponse(CERTCertDBHandle *handle,
4989 CERTOCSPCertID *certID, 5107 CERTOCSPCertID *certID,
4990 CERTCertificate *cert, 5108 CERTCertificate *cert,
4991 int64 time, 5109 int64 time,
4992 void *pwArg, 5110 void *pwArg,
4993 » » » SECItem *encodedResponse, 5111 » » » const SECItem *encodedResponse,
5112 PRBool cacheInvalid,
4994 PRBool *certIDWasConsumed, 5113 PRBool *certIDWasConsumed,
4995 PRBool cacheNegative,
4996 SECStatus *rv_ocsp) 5114 SECStatus *rv_ocsp)
4997 { 5115 {
4998 CERTOCSPResponse *response = NULL; 5116 CERTOCSPResponse *response = NULL;
4999 CERTCertificate *signerCert = NULL; 5117 CERTCertificate *signerCert = NULL;
5000 CERTCertificate *issuerCert = NULL; 5118 CERTCertificate *issuerCert = NULL;
5001 CERTOCSPSingleResponse *single = NULL; 5119 CERTOCSPSingleResponse *single = NULL;
5002 SECStatus rv = SECFailure; 5120 SECStatus rv = SECFailure;
5003 5121
5004 *certIDWasConsumed = PR_FALSE; 5122 *certIDWasConsumed = PR_FALSE;
5005 *rv_ocsp = SECFailure; 5123 *rv_ocsp = SECFailure;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
5044 */ 5162 */
5045 5163
5046 rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID, 5164 rv = ocsp_GetVerifiedSingleResponseForCertID(handle, response, certID,
5047 signerCert, time, &single); 5165 signerCert, time, &single);
5048 if (rv != SECSuccess) 5166 if (rv != SECSuccess)
5049 goto loser; 5167 goto loser;
5050 5168
5051 *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(single, time); 5169 *rv_ocsp = ocsp_SingleResponseCertHasGoodStatus(single, time);
5052 5170
5053 loser: 5171 loser:
5054 if (cacheNegative || *rv_ocsp == SECSuccess) { 5172 /* If single == NULL here then the response was invalid. */
5173 if (single != NULL || cacheInvalid) {
5055 PR_EnterMonitor(OCSP_Global.monitor); 5174 PR_EnterMonitor(OCSP_Global.monitor);
5056 if (OCSP_Global.maxCacheEntries >= 0) { 5175 if (OCSP_Global.maxCacheEntries >= 0) {
5057 /* single == NULL means: remember response failure */ 5176 /* single == NULL means: remember response failure */
5058 ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single, 5177 ocsp_CreateOrUpdateCacheEntry(&OCSP_Global.cache, certID, single,
5059 certIDWasConsumed); 5178 certIDWasConsumed);
5060 /* ignore cache update failures */ 5179 /* ignore cache update failures */
5061 } 5180 }
5062 PR_ExitMonitor(OCSP_Global.monitor); 5181 PR_ExitMonitor(OCSP_Global.monitor);
5063 } 5182 }
5064 5183
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after
5691 case ocspResponse_unauthorized: 5810 case ocspResponse_unauthorized:
5692 PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST); 5811 PORT_SetError(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);
5693 break; 5812 break;
5694 case ocspResponse_unused: 5813 case ocspResponse_unused:
5695 default: 5814 default:
5696 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS); 5815 PORT_SetError(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS);
5697 break; 5816 break;
5698 } 5817 }
5699 return SECFailure; 5818 return SECFailure;
5700 } 5819 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698