Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
michael@0 | 3 | /* Copyright 2013 Mozilla Foundation |
michael@0 | 4 | * |
michael@0 | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
michael@0 | 6 | * you may not use this file except in compliance with the License. |
michael@0 | 7 | * You may obtain a copy of the License at |
michael@0 | 8 | * |
michael@0 | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
michael@0 | 10 | * |
michael@0 | 11 | * Unless required by applicable law or agreed to in writing, software |
michael@0 | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
michael@0 | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
michael@0 | 14 | * See the License for the specific language governing permissions and |
michael@0 | 15 | * limitations under the License. |
michael@0 | 16 | */ |
michael@0 | 17 | |
michael@0 | 18 | #ifndef mozilla_psm_OCSPCache_h |
michael@0 | 19 | #define mozilla_psm_OCSPCache_h |
michael@0 | 20 | |
michael@0 | 21 | #include "certt.h" |
michael@0 | 22 | #include "hasht.h" |
michael@0 | 23 | #include "pkix/pkixtypes.h" |
michael@0 | 24 | #include "mozilla/Mutex.h" |
michael@0 | 25 | #include "mozilla/Vector.h" |
michael@0 | 26 | #include "prerror.h" |
michael@0 | 27 | |
michael@0 | 28 | namespace mozilla { namespace psm { |
michael@0 | 29 | |
michael@0 | 30 | // make SHA384Buffer be of type "array of uint8_t of length SHA384_LENGTH" |
michael@0 | 31 | typedef uint8_t SHA384Buffer[SHA384_LENGTH]; |
michael@0 | 32 | |
michael@0 | 33 | // OCSPCache can store and retrieve OCSP response verification results. Each |
michael@0 | 34 | // result is keyed on the certificate that purportedly corresponds to it (where |
michael@0 | 35 | // certificates are distinguished based on serial number, issuer, and |
michael@0 | 36 | // issuer public key, much like in an encoded OCSP response itself). A maximum |
michael@0 | 37 | // of 1024 distinct entries can be stored. |
michael@0 | 38 | // OCSPCache is thread-safe. |
michael@0 | 39 | class OCSPCache |
michael@0 | 40 | { |
michael@0 | 41 | public: |
michael@0 | 42 | OCSPCache(); |
michael@0 | 43 | ~OCSPCache(); |
michael@0 | 44 | |
michael@0 | 45 | // Returns true if the status of the given certificate (issued by the given |
michael@0 | 46 | // issuer) is in the cache, and false otherwise. |
michael@0 | 47 | // If it is in the cache, returns by reference the error code of the cached |
michael@0 | 48 | // status and the time through which the status is considered trustworthy. |
michael@0 | 49 | bool Get(const CERTCertificate* aCert, const CERTCertificate* aIssuerCert, |
michael@0 | 50 | /* out */ PRErrorCode& aErrorCode, /* out */ PRTime& aValidThrough); |
michael@0 | 51 | |
michael@0 | 52 | // Caches the status of the given certificate (issued by the given issuer). |
michael@0 | 53 | // The status is considered trustworthy through the given time. |
michael@0 | 54 | // A status with an error code of SEC_ERROR_REVOKED_CERTIFICATE will not |
michael@0 | 55 | // be replaced or evicted. |
michael@0 | 56 | // A status with an error code of SEC_ERROR_OCSP_UNKNOWN_CERT will not |
michael@0 | 57 | // be evicted when the cache is full. |
michael@0 | 58 | // A status with a more recent thisUpdate will not be replaced with a |
michael@0 | 59 | // status with a less recent thisUpdate unless the less recent status |
michael@0 | 60 | // indicates the certificate is revoked. |
michael@0 | 61 | SECStatus Put(const CERTCertificate* aCert, |
michael@0 | 62 | const CERTCertificate* aIssuerCert, |
michael@0 | 63 | PRErrorCode aErrorCode, |
michael@0 | 64 | PRTime aThisUpdate, |
michael@0 | 65 | PRTime aValidThrough); |
michael@0 | 66 | |
michael@0 | 67 | // Removes everything from the cache. |
michael@0 | 68 | void Clear(); |
michael@0 | 69 | |
michael@0 | 70 | private: |
michael@0 | 71 | class Entry |
michael@0 | 72 | { |
michael@0 | 73 | public: |
michael@0 | 74 | SECStatus Init(const CERTCertificate* aCert, |
michael@0 | 75 | const CERTCertificate* aIssuerCert, |
michael@0 | 76 | PRErrorCode aErrorCode, PRTime aThisUpdate, |
michael@0 | 77 | PRTime aValidThrough); |
michael@0 | 78 | |
michael@0 | 79 | PRErrorCode mErrorCode; |
michael@0 | 80 | PRTime mThisUpdate; |
michael@0 | 81 | PRTime mValidThrough; |
michael@0 | 82 | // The SHA-384 hash of the concatenation of the DER encodings of the |
michael@0 | 83 | // issuer name and issuer key, followed by the serial number. |
michael@0 | 84 | // See the documentation for CertIDHash in OCSPCache.cpp. |
michael@0 | 85 | SHA384Buffer mIDHash; |
michael@0 | 86 | }; |
michael@0 | 87 | |
michael@0 | 88 | int32_t FindInternal(const CERTCertificate* aCert, |
michael@0 | 89 | const CERTCertificate* aIssuerCert, |
michael@0 | 90 | const MutexAutoLock& aProofOfLock); |
michael@0 | 91 | void MakeMostRecentlyUsed(size_t aIndex, const MutexAutoLock& aProofOfLock); |
michael@0 | 92 | void LogWithCerts(const char* aMessage, const CERTCertificate* aCert, |
michael@0 | 93 | const CERTCertificate* aIssuerCert); |
michael@0 | 94 | |
michael@0 | 95 | Mutex mMutex; |
michael@0 | 96 | static const size_t MaxEntries = 1024; |
michael@0 | 97 | // Sorted with the most-recently-used entry at the end. |
michael@0 | 98 | // Using 256 here reserves as much possible inline storage as the vector |
michael@0 | 99 | // implementation will give us. 1024 bytes is the maximum it allows, |
michael@0 | 100 | // which results in 256 Entry pointers or 128 Entry pointers, depending |
michael@0 | 101 | // on the size of a pointer. |
michael@0 | 102 | Vector<Entry*, 256> mEntries; |
michael@0 | 103 | }; |
michael@0 | 104 | |
michael@0 | 105 | } } // namespace mozilla::psm |
michael@0 | 106 | |
michael@0 | 107 | #endif // mozilla_psm_OCSPCache_h |