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

Side by Side Diff: net/base/x509_certificate.cc

Issue 2668005: Bring the handling of <keygen> and support for the application/x-x509-user-ce... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Whitespace/style Created 10 years, 6 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
« no previous file with comments | « net/base/x509_certificate.h ('k') | net/base/x509_certificate_mac.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/base/x509_certificate.h" 5 #include "net/base/x509_certificate.h"
6 6
7 #if defined(OS_MACOSX) 7 #if defined(OS_MACOSX)
8 #include <Security/Security.h> 8 #include <Security/Security.h>
9 #elif defined(USE_NSS) 9 #elif defined(USE_NSS)
10 #include <cert.h> 10 #include <cert.h>
11 #endif 11 #endif
12 12
13 #include "base/histogram.h" 13 #include "base/histogram.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/time.h" 15 #include "base/string_piece.h"
16 #include "net/base/pem_tokenizer.h"
16 17
17 namespace net { 18 namespace net {
18 19
19 namespace { 20 namespace {
20 21
21 // Returns true if this cert fingerprint is the null (all zero) fingerprint. 22 // Returns true if this cert fingerprint is the null (all zero) fingerprint.
22 // We use this as a bogus fingerprint value. 23 // We use this as a bogus fingerprint value.
23 bool IsNullFingerprint(const X509Certificate::Fingerprint& fingerprint) { 24 bool IsNullFingerprint(const X509Certificate::Fingerprint& fingerprint) {
24 for (size_t i = 0; i < arraysize(fingerprint.data); ++i) { 25 for (size_t i = 0; i < arraysize(fingerprint.data); ++i) {
25 if (fingerprint.data[i] != 0) 26 if (fingerprint.data[i] != 0)
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 152
152 // Otherwise, allocate and cache a new object. 153 // Otherwise, allocate and cache a new object.
153 X509Certificate* cert = new X509Certificate(cert_handle, source, 154 X509Certificate* cert = new X509Certificate(cert_handle, source,
154 intermediates); 155 intermediates);
155 cache->Insert(cert); 156 cache->Insert(cert);
156 return cert; 157 return cert;
157 } 158 }
158 159
159 // static 160 // static
160 X509Certificate* X509Certificate::CreateFromBytes(const char* data, 161 X509Certificate* X509Certificate::CreateFromBytes(const char* data,
161 int length) { 162 size_t length,
162 OSCertHandle cert_handle = CreateOSCertHandleFromBytes(data, length); 163 int format) {
163 if (!cert_handle) 164 OSCertHandles certificates;
165
166 // Indicates the order to use when trying to decode binary data, which is
167 // based on (speculation) as to what will be most common -> least common
168 // TODO(rsleevi): Calculate metrics as to which formats end up being
169 // encountered and re-arrange this based on actual data.
170 static CertificateFormat formats[] = { FORMAT_DER, FORMAT_PKCS7,
171 FORMAT_LEGACY_NETSCAPE };
172
173 // If it wasn't PEM encoded, try each of the binary formats in order of
174 // their probability until one successfully decodes.
175 for (size_t i = 0; certificates.empty() && i < arraysize(formats);
176 ++i) {
177 if (format & formats[i])
178 certificates = CreateOSCertHandlesFromBytes(data, length, formats[i]);
179 }
180
181 // No certs were read. Check to see if this is perhaps a PEM-wrapped version.
182 if (certificates.empty()) {
183 base::StringPiece data_string(data, length);
184 std::vector<std::string> pem_headers;
185
186 // To maintain compatibility with NSS/Firefox, CERTIFICATE is a universally
187 // valid PEM block header.
188 pem_headers.push_back("CERTIFICATE");
189 if (format & FORMAT_PKCS7)
190 pem_headers.push_back("PKCS7");
191
192 PEMTokenizer pem_tok(&data_string, pem_headers);
193 while (pem_tok.GetNext()) {
194 std::string decoded(pem_tok.data());
195
196 // Try a single cert decode first. If this succeeds, then the data is
197 // likely a PEM cert sequence and thus all PEM blocks should be parsed
198 // as certificates. If it doesn't parse as a single certificate, then
199 // this is potentially one of the other formats, in which case only the
200 // first PEM block is consulted.
201 OSCertHandle handle = NULL;
202 if (format & FORMAT_PEM)
203 handle = CreateOSCertHandleFromBytes(decoded.c_str(), decoded.size());
204 if (handle != NULL) {
205 format = FORMAT_PEM;
206 certificates.push_back(handle);
207 } else {
208 // If this is the first block, and other formats are specified, try to
209 // decode using the binary contents from the PEM block
210 if (format & ~FORMAT_PEM)
211 return CreateFromBytes(decoded.c_str(), decoded.size(), format);
212
213 // When parsing PEM, the first bad block encountered terminates
214 // parsing
215 break;
216 }
217 }
218 }
219
220 // No certificates parsed.
221 if (certificates.empty())
164 return NULL; 222 return NULL;
165 223
166 return CreateFromHandle(cert_handle, 224 X509Certificate* result = CreateFromHandle(certificates.front(),
167 SOURCE_LONE_CERT_IMPORT, 225 SOURCE_LONE_CERT_IMPORT,
168 OSCertHandles()); 226 certificates.size() == 1 ? OSCertHandles() :
227 OSCertHandles(++certificates.begin(), certificates.end()));
228
229 // CreateFromHandle duplicates the handles to the intermediates, but does
230 // not do so for the primary certificate. Ensure that every intermediate is
231 // freed
232 for (OSCertHandles::iterator it = ++certificates.begin();
233 it != certificates.end(); ++it) {
234 FreeOSCertHandle(*it);
235 }
236
237 return result;
169 } 238 }
170 239
171 X509Certificate::X509Certificate(OSCertHandle cert_handle, 240 X509Certificate::X509Certificate(OSCertHandle cert_handle,
172 Source source, 241 Source source,
173 const OSCertHandles& intermediates) 242 const OSCertHandles& intermediates)
174 : cert_handle_(cert_handle), 243 : cert_handle_(cert_handle),
175 source_(source) { 244 source_(source) {
176 #if defined(OS_MACOSX) || defined(OS_WIN)
177 // Copy/retain the intermediate cert handles. 245 // Copy/retain the intermediate cert handles.
178 for (size_t i = 0; i < intermediates.size(); ++i) 246 for (size_t i = 0; i < intermediates.size(); ++i)
179 intermediate_ca_certs_.push_back(DupOSCertHandle(intermediates[i])); 247 intermediate_ca_certs_.push_back(DupOSCertHandle(intermediates[i]));
180 #endif
181 // Platform-specific initialization. 248 // Platform-specific initialization.
182 Initialize(); 249 Initialize();
183 } 250 }
184 251
185 X509Certificate::X509Certificate(const std::string& subject, 252 X509Certificate::X509Certificate(const std::string& subject,
186 const std::string& issuer, 253 const std::string& issuer,
187 base::Time start_date, 254 base::Time start_date,
188 base::Time expiration_date) 255 base::Time expiration_date)
189 : subject_(subject), 256 : subject_(subject),
190 issuer_(issuer), 257 issuer_(issuer),
191 valid_start_(start_date), 258 valid_start_(start_date),
192 valid_expiry_(expiration_date), 259 valid_expiry_(expiration_date),
193 cert_handle_(NULL), 260 cert_handle_(NULL),
194 source_(SOURCE_UNUSED) { 261 source_(SOURCE_UNUSED) {
195 memset(fingerprint_.data, 0, sizeof(fingerprint_.data)); 262 memset(fingerprint_.data, 0, sizeof(fingerprint_.data));
196 } 263 }
197 264
198 X509Certificate::~X509Certificate() { 265 X509Certificate::~X509Certificate() {
199 // We might not be in the cache, but it is safe to remove ourselves anyway. 266 // We might not be in the cache, but it is safe to remove ourselves anyway.
200 X509Certificate::Cache::GetInstance()->Remove(this); 267 X509Certificate::Cache::GetInstance()->Remove(this);
201 if (cert_handle_) 268 if (cert_handle_)
202 FreeOSCertHandle(cert_handle_); 269 FreeOSCertHandle(cert_handle_);
203 #if defined(OS_MACOSX) || defined(OS_WIN)
204 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) 270 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i)
205 FreeOSCertHandle(intermediate_ca_certs_[i]); 271 FreeOSCertHandle(intermediate_ca_certs_[i]);
206 #endif
207 } 272 }
208 273
209 bool X509Certificate::HasExpired() const { 274 bool X509Certificate::HasExpired() const {
210 return base::Time::Now() > valid_expiry(); 275 return base::Time::Now() > valid_expiry();
211 } 276 }
212 277
213 bool X509Certificate::HasIntermediateCertificate(OSCertHandle cert) { 278 bool X509Certificate::HasIntermediateCertificate(OSCertHandle cert) {
214 #if defined(OS_MACOSX) || defined(OS_WIN)
215 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) { 279 for (size_t i = 0; i < intermediate_ca_certs_.size(); ++i) {
216 if (IsSameOSCert(cert, intermediate_ca_certs_[i])) 280 if (IsSameOSCert(cert, intermediate_ca_certs_[i]))
217 return true; 281 return true;
218 } 282 }
219 return false; 283 return false;
220 #else
221 return true;
222 #endif
223 } 284 }
224 285
225 bool X509Certificate::HasIntermediateCertificates(const OSCertHandles& certs) { 286 bool X509Certificate::HasIntermediateCertificates(const OSCertHandles& certs) {
226 for (size_t i = 0; i < certs.size(); ++i) { 287 for (size_t i = 0; i < certs.size(); ++i) {
227 if (!HasIntermediateCertificate(certs[i])) 288 if (!HasIntermediateCertificate(certs[i]))
228 return false; 289 return false;
229 } 290 }
230 return true; 291 return true;
231 } 292 }
232 293
233 } // namespace net 294 } // namespace net
OLDNEW
« no previous file with comments | « net/base/x509_certificate.h ('k') | net/base/x509_certificate_mac.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698