Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : *
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef nsCertOverrideService_h
8 : #define nsCertOverrideService_h
9 :
10 : #include "mozilla/Mutex.h"
11 : #include "mozilla/TypedEnumBits.h"
12 : #include "nsICertOverrideService.h"
13 : #include "nsIFile.h"
14 : #include "nsIObserver.h"
15 : #include "nsString.h"
16 : #include "nsTHashtable.h"
17 : #include "nsWeakReference.h"
18 : #include "secoidt.h"
19 :
20 0 : class nsCertOverride
21 : {
22 : public:
23 : enum class OverrideBits {
24 : None = 0,
25 : Untrusted = nsICertOverrideService::ERROR_UNTRUSTED,
26 : Mismatch = nsICertOverrideService::ERROR_MISMATCH,
27 : Time = nsICertOverrideService::ERROR_TIME,
28 : };
29 :
30 0 : nsCertOverride()
31 0 : : mPort(-1)
32 0 : , mOverrideBits(OverrideBits::None)
33 : {
34 0 : }
35 :
36 : nsCertOverride(const nsCertOverride &other)
37 : {
38 : this->operator=(other);
39 : }
40 :
41 0 : nsCertOverride &operator=(const nsCertOverride &other)
42 : {
43 0 : mAsciiHost = other.mAsciiHost;
44 0 : mPort = other.mPort;
45 0 : mIsTemporary = other.mIsTemporary;
46 0 : mFingerprintAlgOID = other.mFingerprintAlgOID;
47 0 : mFingerprint = other.mFingerprint;
48 0 : mOverrideBits = other.mOverrideBits;
49 0 : mDBKey = other.mDBKey;
50 0 : mCert = other.mCert;
51 0 : return *this;
52 : }
53 :
54 : nsCString mAsciiHost;
55 : int32_t mPort;
56 : bool mIsTemporary; // true: session only, false: stored on disk
57 : nsCString mFingerprint;
58 : nsCString mFingerprintAlgOID;
59 : OverrideBits mOverrideBits;
60 : nsCString mDBKey;
61 : nsCOMPtr <nsIX509Cert> mCert;
62 :
63 : static void convertBitsToString(OverrideBits ob, nsACString &str);
64 : static void convertStringToBits(const nsACString &str, OverrideBits &ob);
65 : };
66 :
67 0 : MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsCertOverride::OverrideBits)
68 :
69 : // hash entry class
70 : class nsCertOverrideEntry final : public PLDHashEntryHdr
71 : {
72 : public:
73 : // Hash methods
74 : typedef const char* KeyType;
75 : typedef const char* KeyTypePointer;
76 :
77 : // do nothing with aHost - we require mHead to be set before we're live!
78 0 : explicit nsCertOverrideEntry(KeyTypePointer aHostWithPortUTF8)
79 0 : {
80 0 : }
81 :
82 0 : nsCertOverrideEntry(const nsCertOverrideEntry& toCopy)
83 0 : {
84 0 : mSettings = toCopy.mSettings;
85 0 : mHostWithPort = toCopy.mHostWithPort;
86 0 : }
87 :
88 0 : ~nsCertOverrideEntry()
89 0 : {
90 0 : }
91 :
92 : KeyType GetKey() const
93 : {
94 : return HostWithPortPtr();
95 : }
96 :
97 : KeyTypePointer GetKeyPointer() const
98 : {
99 : return HostWithPortPtr();
100 : }
101 :
102 0 : bool KeyEquals(KeyTypePointer aKey) const
103 : {
104 0 : return !strcmp(HostWithPortPtr(), aKey);
105 : }
106 :
107 0 : static KeyTypePointer KeyToPointer(KeyType aKey)
108 : {
109 0 : return aKey;
110 : }
111 :
112 0 : static PLDHashNumber HashKey(KeyTypePointer aKey)
113 : {
114 0 : return PLDHashTable::HashStringKey(aKey);
115 : }
116 :
117 : enum { ALLOW_MEMMOVE = false };
118 :
119 : // get methods
120 : inline const nsCString &HostWithPort() const { return mHostWithPort; }
121 :
122 0 : inline KeyTypePointer HostWithPortPtr() const
123 : {
124 0 : return mHostWithPort.get();
125 : }
126 :
127 : nsCertOverride mSettings;
128 : nsCString mHostWithPort;
129 : };
130 :
131 : class nsCertOverrideService final : public nsICertOverrideService
132 : , public nsIObserver
133 : , public nsSupportsWeakReference
134 : {
135 : public:
136 : NS_DECL_THREADSAFE_ISUPPORTS
137 : NS_DECL_NSICERTOVERRIDESERVICE
138 : NS_DECL_NSIOBSERVER
139 :
140 : nsCertOverrideService();
141 :
142 : nsresult Init();
143 : void RemoveAllTemporaryOverrides();
144 :
145 : typedef void
146 : (*CertOverrideEnumerator)(const nsCertOverride &aSettings,
147 : void *aUserData);
148 :
149 : // aCert == null: return all overrides
150 : // aCert != null: return overrides that match the given cert
151 : nsresult EnumerateCertOverrides(nsIX509Cert *aCert,
152 : CertOverrideEnumerator enumerator,
153 : void *aUserData);
154 :
155 : // Concates host name and the port number. If the port number is -1 then
156 : // port 443 is automatically used. This method ensures there is always a port
157 : // number separated with colon.
158 : static void GetHostWithPort(const nsACString & aHostName, int32_t aPort, nsACString& _retval);
159 :
160 : protected:
161 : ~nsCertOverrideService();
162 :
163 : mozilla::Mutex mMutex;
164 : nsCOMPtr<nsIFile> mSettingsFile;
165 : nsTHashtable<nsCertOverrideEntry> mSettingsTable;
166 :
167 : SECOidTag mOidTagForStoringNewHashes;
168 : nsCString mDottedOidForStoringNewHashes;
169 :
170 : void CountPermanentOverrideTelemetry(const mozilla::MutexAutoLock& aProofOfLock);
171 :
172 : void RemoveAllFromMemory();
173 : nsresult Read(const mozilla::MutexAutoLock& aProofOfLock);
174 : nsresult Write(const mozilla::MutexAutoLock& aProofOfLock);
175 : nsresult AddEntryToList(const nsACString &host, int32_t port,
176 : nsIX509Cert *aCert,
177 : const bool aIsTemporary,
178 : const nsACString &algo_oid,
179 : const nsACString &fingerprint,
180 : nsCertOverride::OverrideBits ob,
181 : const nsACString &dbKey,
182 : const mozilla::MutexAutoLock& aProofOfLock);
183 : };
184 :
185 : #define NS_CERTOVERRIDE_CID { /* 67ba681d-5485-4fff-952c-2ee337ffdcd6 */ \
186 : 0x67ba681d, \
187 : 0x5485, \
188 : 0x4fff, \
189 : {0x95, 0x2c, 0x2e, 0xe3, 0x37, 0xff, 0xdc, 0xd6} \
190 : }
191 :
192 : #endif // nsCertOverrideService_h
|