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

Side by Side Diff: net/third_party/mozilla_security_manager/nsNSSCertificateDB.cpp

Issue 10916094: Move the NSS functions out of CertDatabase into a new NSSCertDatabase class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 8 years, 3 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 /* ***** BEGIN LICENSE BLOCK ***** 1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 * 3 *
4 * The contents of this file are subject to the Mozilla Public License Version 4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with 5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at 6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/ 7 * http://www.mozilla.org/MPL/
8 * 8 *
9 * Software distributed under the License is distributed on an "AS IS" basis, 9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 * If we're using an older version, rename it ourselves. 55 * If we're using an older version, rename it ourselves.
56 */ 56 */
57 #define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER 57 #define CERTDB_TERMINAL_RECORD CERTDB_VALID_PEER
58 #endif 58 #endif
59 59
60 namespace mozilla_security_manager { 60 namespace mozilla_security_manager {
61 61
62 // Based on nsNSSCertificateDB::handleCACertDownload, minus the UI bits. 62 // Based on nsNSSCertificateDB::handleCACertDownload, minus the UI bits.
63 bool ImportCACerts(const net::CertificateList& certificates, 63 bool ImportCACerts(const net::CertificateList& certificates,
64 net::X509Certificate* root, 64 net::X509Certificate* root,
65 net::CertDatabase::TrustBits trustBits, 65 net::NSSCertDatabase::TrustBits trustBits,
66 net::CertDatabase::ImportCertFailureList* not_imported) { 66 net::NSSCertDatabase::ImportCertFailureList* not_imported) {
67 if (certificates.empty() || !root) 67 if (certificates.empty() || !root)
68 return false; 68 return false;
69 69
70 crypto::ScopedPK11Slot slot(crypto::GetPublicNSSKeySlot()); 70 crypto::ScopedPK11Slot slot(crypto::GetPublicNSSKeySlot());
71 if (!slot.get()) { 71 if (!slot.get()) {
72 LOG(ERROR) << "Couldn't get internal key slot!"; 72 LOG(ERROR) << "Couldn't get internal key slot!";
73 return false; 73 return false;
74 } 74 }
75 75
76 // Mozilla had some code here to check if a perm version of the cert exists 76 // Mozilla had some code here to check if a perm version of the cert exists
77 // already and use that, but CERT_NewTempCertificate actually does that 77 // already and use that, but CERT_NewTempCertificate actually does that
78 // itself, so we skip it here. 78 // itself, so we skip it here.
79 79
80 if (!CERT_IsCACert(root->os_cert_handle(), NULL)) { 80 if (!CERT_IsCACert(root->os_cert_handle(), NULL)) {
81 not_imported->push_back(net::CertDatabase::ImportCertFailure( 81 not_imported->push_back(net::NSSCertDatabase::ImportCertFailure(
82 root, net::ERR_IMPORT_CA_CERT_NOT_CA)); 82 root, net::ERR_IMPORT_CA_CERT_NOT_CA));
83 } else if (root->os_cert_handle()->isperm) { 83 } else if (root->os_cert_handle()->isperm) {
84 // Mozilla just returns here, but we continue in case there are other certs 84 // Mozilla just returns here, but we continue in case there are other certs
85 // in the list which aren't already imported. 85 // in the list which aren't already imported.
86 // TODO(mattm): should we set/add trust if it differs from the present 86 // TODO(mattm): should we set/add trust if it differs from the present
87 // settings? 87 // settings?
88 not_imported->push_back(net::CertDatabase::ImportCertFailure( 88 not_imported->push_back(net::NSSCertDatabase::ImportCertFailure(
89 root, net::ERR_IMPORT_CERT_ALREADY_EXISTS)); 89 root, net::ERR_IMPORT_CERT_ALREADY_EXISTS));
90 } else { 90 } else {
91 // Mozilla uses CERT_AddTempCertToPerm, however it is privately exported, 91 // Mozilla uses CERT_AddTempCertToPerm, however it is privately exported,
92 // and it doesn't take the slot as an argument either. Instead, we use 92 // and it doesn't take the slot as an argument either. Instead, we use
93 // PK11_ImportCert and CERT_ChangeCertTrust. 93 // PK11_ImportCert and CERT_ChangeCertTrust.
94 SECStatus srv = PK11_ImportCert( 94 SECStatus srv = PK11_ImportCert(
95 slot.get(), 95 slot.get(),
96 root->os_cert_handle(), 96 root->os_cert_handle(),
97 CK_INVALID_HANDLE, 97 CK_INVALID_HANDLE,
98 root->GetDefaultNickname(net::CA_CERT).c_str(), 98 root->GetDefaultNickname(net::CA_CERT).c_str(),
(...skipping 16 matching lines...) Expand all
115 for (size_t i = 0; i < certificates.size(); i++) { 115 for (size_t i = 0; i < certificates.size(); i++) {
116 const scoped_refptr<net::X509Certificate>& cert = certificates[i]; 116 const scoped_refptr<net::X509Certificate>& cert = certificates[i];
117 if (cert == root) { 117 if (cert == root) {
118 // we already processed that one 118 // we already processed that one
119 continue; 119 continue;
120 } 120 }
121 121
122 // Mozilla uses CERT_FilterCertListByUsage(certList, certUsageAnyCA, 122 // Mozilla uses CERT_FilterCertListByUsage(certList, certUsageAnyCA,
123 // PR_TRUE). Afaict, checking !CERT_IsCACert on each cert is equivalent. 123 // PR_TRUE). Afaict, checking !CERT_IsCACert on each cert is equivalent.
124 if (!CERT_IsCACert(cert->os_cert_handle(), NULL)) { 124 if (!CERT_IsCACert(cert->os_cert_handle(), NULL)) {
125 not_imported->push_back(net::CertDatabase::ImportCertFailure( 125 not_imported->push_back(net::NSSCertDatabase::ImportCertFailure(
126 cert, net::ERR_IMPORT_CA_CERT_NOT_CA)); 126 cert, net::ERR_IMPORT_CA_CERT_NOT_CA));
127 VLOG(1) << "skipping cert (non-ca)"; 127 VLOG(1) << "skipping cert (non-ca)";
128 continue; 128 continue;
129 } 129 }
130 130
131 if (cert->os_cert_handle()->isperm) { 131 if (cert->os_cert_handle()->isperm) {
132 not_imported->push_back(net::CertDatabase::ImportCertFailure( 132 not_imported->push_back(net::NSSCertDatabase::ImportCertFailure(
133 cert, net::ERR_IMPORT_CERT_ALREADY_EXISTS)); 133 cert, net::ERR_IMPORT_CERT_ALREADY_EXISTS));
134 VLOG(1) << "skipping cert (perm)"; 134 VLOG(1) << "skipping cert (perm)";
135 continue; 135 continue;
136 } 136 }
137 137
138 if (CERT_VerifyCert(CERT_GetDefaultCertDB(), cert->os_cert_handle(), 138 if (CERT_VerifyCert(CERT_GetDefaultCertDB(), cert->os_cert_handle(),
139 PR_TRUE, certUsageVerifyCA, now, NULL, NULL) != SECSuccess) { 139 PR_TRUE, certUsageVerifyCA, now, NULL, NULL) != SECSuccess) {
140 // TODO(mattm): use better error code (map PORT_GetError to an appropriate 140 // TODO(mattm): use better error code (map PORT_GetError to an appropriate
141 // error value). (maybe make MapSecurityError or MapCertErrorToCertStatus 141 // error value). (maybe make MapSecurityError or MapCertErrorToCertStatus
142 // public.) 142 // public.)
143 not_imported->push_back(net::CertDatabase::ImportCertFailure( 143 not_imported->push_back(net::NSSCertDatabase::ImportCertFailure(
144 cert, net::ERR_FAILED)); 144 cert, net::ERR_FAILED));
145 VLOG(1) << "skipping cert (verify) " << PORT_GetError(); 145 VLOG(1) << "skipping cert (verify) " << PORT_GetError();
146 continue; 146 continue;
147 } 147 }
148 148
149 // Mozilla uses CERT_ImportCerts, which doesn't take a slot arg. We use 149 // Mozilla uses CERT_ImportCerts, which doesn't take a slot arg. We use
150 // PK11_ImportCert instead. 150 // PK11_ImportCert instead.
151 SECStatus srv = PK11_ImportCert( 151 SECStatus srv = PK11_ImportCert(
152 slot.get(), 152 slot.get(),
153 cert->os_cert_handle(), 153 cert->os_cert_handle(),
154 CK_INVALID_HANDLE, 154 CK_INVALID_HANDLE,
155 cert->GetDefaultNickname(net::CA_CERT).c_str(), 155 cert->GetDefaultNickname(net::CA_CERT).c_str(),
156 PR_FALSE /* includeTrust (unused) */); 156 PR_FALSE /* includeTrust (unused) */);
157 if (srv != SECSuccess) { 157 if (srv != SECSuccess) {
158 LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError(); 158 LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError();
159 // TODO(mattm): Should we bail or continue on error here? Mozilla doesn't 159 // TODO(mattm): Should we bail or continue on error here? Mozilla doesn't
160 // check error code at all. 160 // check error code at all.
161 not_imported->push_back(net::CertDatabase::ImportCertFailure( 161 not_imported->push_back(net::NSSCertDatabase::ImportCertFailure(
162 cert, net::ERR_IMPORT_CA_CERT_FAILED)); 162 cert, net::ERR_IMPORT_CA_CERT_FAILED));
163 } 163 }
164 } 164 }
165 165
166 // Any errors importing individual certs will be in listed in |not_imported|. 166 // Any errors importing individual certs will be in listed in |not_imported|.
167 return true; 167 return true;
168 } 168 }
169 169
170 // Based on nsNSSCertificateDB::ImportServerCertificate. 170 // Based on nsNSSCertificateDB::ImportServerCertificate.
171 bool ImportServerCert(const net::CertificateList& certificates, 171 bool ImportServerCert(
172 net::CertDatabase::TrustBits trustBits, 172 const net::CertificateList& certificates,
173 net::CertDatabase::ImportCertFailureList* not_imported) { 173 net::NSSCertDatabase::TrustBits trustBits,
174 net::NSSCertDatabase::ImportCertFailureList* not_imported) {
174 if (certificates.empty()) 175 if (certificates.empty())
175 return false; 176 return false;
176 177
177 crypto::ScopedPK11Slot slot(crypto::GetPublicNSSKeySlot()); 178 crypto::ScopedPK11Slot slot(crypto::GetPublicNSSKeySlot());
178 if (!slot.get()) { 179 if (!slot.get()) {
179 LOG(ERROR) << "Couldn't get internal key slot!"; 180 LOG(ERROR) << "Couldn't get internal key slot!";
180 return false; 181 return false;
181 } 182 }
182 183
183 for (size_t i = 0; i < certificates.size(); ++i) { 184 for (size_t i = 0; i < certificates.size(); ++i) {
184 const scoped_refptr<net::X509Certificate>& cert = certificates[i]; 185 const scoped_refptr<net::X509Certificate>& cert = certificates[i];
185 186
186 // Mozilla uses CERT_ImportCerts, which doesn't take a slot arg. We use 187 // Mozilla uses CERT_ImportCerts, which doesn't take a slot arg. We use
187 // PK11_ImportCert instead. 188 // PK11_ImportCert instead.
188 SECStatus srv = PK11_ImportCert( 189 SECStatus srv = PK11_ImportCert(
189 slot.get(), 190 slot.get(),
190 cert->os_cert_handle(), 191 cert->os_cert_handle(),
191 CK_INVALID_HANDLE, 192 CK_INVALID_HANDLE,
192 cert->GetDefaultNickname(net::SERVER_CERT).c_str(), 193 cert->GetDefaultNickname(net::SERVER_CERT).c_str(),
193 PR_FALSE /* includeTrust (unused) */); 194 PR_FALSE /* includeTrust (unused) */);
194 if (srv != SECSuccess) { 195 if (srv != SECSuccess) {
195 LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError(); 196 LOG(ERROR) << "PK11_ImportCert failed with error " << PORT_GetError();
196 not_imported->push_back(net::CertDatabase::ImportCertFailure( 197 not_imported->push_back(net::NSSCertDatabase::ImportCertFailure(
197 cert, net::ERR_IMPORT_SERVER_CERT_FAILED)); 198 cert, net::ERR_IMPORT_SERVER_CERT_FAILED));
198 continue; 199 continue;
199 } 200 }
200 } 201 }
201 202
202 SetCertTrust(certificates[0].get(), net::SERVER_CERT, trustBits); 203 SetCertTrust(certificates[0].get(), net::SERVER_CERT, trustBits);
203 // TODO(mattm): Report SetCertTrust result? Putting in not_imported 204 // TODO(mattm): Report SetCertTrust result? Putting in not_imported
204 // wouldn't quite match up since it was imported... 205 // wouldn't quite match up since it was imported...
205 206
206 // Any errors importing individual certs will be in listed in |not_imported|. 207 // Any errors importing individual certs will be in listed in |not_imported|.
207 return true; 208 return true;
208 } 209 }
209 210
210 // Based on nsNSSCertificateDB::SetCertTrust. 211 // Based on nsNSSCertificateDB::SetCertTrust.
211 bool 212 bool
212 SetCertTrust(const net::X509Certificate* cert, 213 SetCertTrust(const net::X509Certificate* cert,
213 net::CertType type, 214 net::CertType type,
214 net::CertDatabase::TrustBits trustBits) 215 net::NSSCertDatabase::TrustBits trustBits)
215 { 216 {
216 const unsigned kSSLTrustBits = net::CertDatabase::TRUSTED_SSL | 217 const unsigned kSSLTrustBits = net::NSSCertDatabase::TRUSTED_SSL |
217 net::CertDatabase::DISTRUSTED_SSL; 218 net::NSSCertDatabase::DISTRUSTED_SSL;
218 const unsigned kEmailTrustBits = net::CertDatabase::TRUSTED_EMAIL | 219 const unsigned kEmailTrustBits = net::NSSCertDatabase::TRUSTED_EMAIL |
219 net::CertDatabase::DISTRUSTED_EMAIL; 220 net::NSSCertDatabase::DISTRUSTED_EMAIL;
220 const unsigned kObjSignTrustBits = net::CertDatabase::TRUSTED_OBJ_SIGN | 221 const unsigned kObjSignTrustBits = net::NSSCertDatabase::TRUSTED_OBJ_SIGN |
221 net::CertDatabase::DISTRUSTED_OBJ_SIGN; 222 net::NSSCertDatabase::DISTRUSTED_OBJ_SIGN;
222 if ((trustBits & kSSLTrustBits) == kSSLTrustBits || 223 if ((trustBits & kSSLTrustBits) == kSSLTrustBits ||
223 (trustBits & kEmailTrustBits) == kEmailTrustBits || 224 (trustBits & kEmailTrustBits) == kEmailTrustBits ||
224 (trustBits & kObjSignTrustBits) == kObjSignTrustBits) { 225 (trustBits & kObjSignTrustBits) == kObjSignTrustBits) {
225 LOG(ERROR) << "SetCertTrust called with conflicting trust bits " 226 LOG(ERROR) << "SetCertTrust called with conflicting trust bits "
226 << trustBits; 227 << trustBits;
227 NOTREACHED(); 228 NOTREACHED();
228 return false; 229 return false;
229 } 230 }
230 231
231 SECStatus srv; 232 SECStatus srv;
232 CERTCertificate *nsscert = cert->os_cert_handle(); 233 CERTCertificate *nsscert = cert->os_cert_handle();
233 if (type == net::CA_CERT) { 234 if (type == net::CA_CERT) {
234 // Note that we start with CERTDB_VALID_CA for default trust and explicit 235 // Note that we start with CERTDB_VALID_CA for default trust and explicit
235 // trust, but explicitly distrusted usages will be set to 236 // trust, but explicitly distrusted usages will be set to
236 // CERTDB_TERMINAL_RECORD only. 237 // CERTDB_TERMINAL_RECORD only.
237 CERTCertTrust trust = {CERTDB_VALID_CA, CERTDB_VALID_CA, CERTDB_VALID_CA}; 238 CERTCertTrust trust = {CERTDB_VALID_CA, CERTDB_VALID_CA, CERTDB_VALID_CA};
238 239
239 if (trustBits & net::CertDatabase::DISTRUSTED_SSL) 240 if (trustBits & net::NSSCertDatabase::DISTRUSTED_SSL)
240 trust.sslFlags = CERTDB_TERMINAL_RECORD; 241 trust.sslFlags = CERTDB_TERMINAL_RECORD;
241 else if (trustBits & net::CertDatabase::TRUSTED_SSL) 242 else if (trustBits & net::NSSCertDatabase::TRUSTED_SSL)
242 trust.sslFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; 243 trust.sslFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA;
243 244
244 if (trustBits & net::CertDatabase::DISTRUSTED_EMAIL) 245 if (trustBits & net::NSSCertDatabase::DISTRUSTED_EMAIL)
245 trust.emailFlags = CERTDB_TERMINAL_RECORD; 246 trust.emailFlags = CERTDB_TERMINAL_RECORD;
246 else if (trustBits & net::CertDatabase::TRUSTED_EMAIL) 247 else if (trustBits & net::NSSCertDatabase::TRUSTED_EMAIL)
247 trust.emailFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; 248 trust.emailFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA;
248 249
249 if (trustBits & net::CertDatabase::DISTRUSTED_OBJ_SIGN) 250 if (trustBits & net::NSSCertDatabase::DISTRUSTED_OBJ_SIGN)
250 trust.objectSigningFlags = CERTDB_TERMINAL_RECORD; 251 trust.objectSigningFlags = CERTDB_TERMINAL_RECORD;
251 else if (trustBits & net::CertDatabase::TRUSTED_OBJ_SIGN) 252 else if (trustBits & net::NSSCertDatabase::TRUSTED_OBJ_SIGN)
252 trust.objectSigningFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA; 253 trust.objectSigningFlags |= CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA;
253 254
254 srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust); 255 srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust);
255 } else if (type == net::SERVER_CERT) { 256 } else if (type == net::SERVER_CERT) {
256 CERTCertTrust trust = {0}; 257 CERTCertTrust trust = {0};
257 // We only modify the sslFlags, so copy the other flags. 258 // We only modify the sslFlags, so copy the other flags.
258 CERT_GetCertTrust(nsscert, &trust); 259 CERT_GetCertTrust(nsscert, &trust);
259 trust.sslFlags = 0; 260 trust.sslFlags = 0;
260 261
261 if (trustBits & net::CertDatabase::DISTRUSTED_SSL) 262 if (trustBits & net::NSSCertDatabase::DISTRUSTED_SSL)
262 trust.sslFlags |= CERTDB_TERMINAL_RECORD; 263 trust.sslFlags |= CERTDB_TERMINAL_RECORD;
263 else if (trustBits & net::CertDatabase::TRUSTED_SSL) 264 else if (trustBits & net::NSSCertDatabase::TRUSTED_SSL)
264 trust.sslFlags |= CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD; 265 trust.sslFlags |= CERTDB_TRUSTED | CERTDB_TERMINAL_RECORD;
265 266
266 srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust); 267 srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nsscert, &trust);
267 } else { 268 } else {
268 // ignore user and email/unknown certs 269 // ignore user and email/unknown certs
269 return true; 270 return true;
270 } 271 }
271 if (srv != SECSuccess) 272 if (srv != SECSuccess)
272 LOG(ERROR) << "SetCertTrust failed with error " << PORT_GetError(); 273 LOG(ERROR) << "SetCertTrust failed with error " << PORT_GetError();
273 return srv == SECSuccess; 274 return srv == SECSuccess;
274 } 275 }
275 276
276 } // namespace mozilla_security_manager 277 } // namespace mozilla_security_manager
OLDNEW
« net/base/cert_database.cc ('K') | « net/third_party/mozilla_security_manager/nsNSSCertificateDB.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698