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

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

Issue 13006020: net: extract net/cert out of net/base (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase 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
« no previous file with comments | « net/base/x509_certificate_net_log_param.cc ('k') | net/base/x509_certificate_openssl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/base/x509_certificate.h"
6
7 #include <cert.h>
8 #include <cryptohi.h>
9 #include <keyhi.h>
10 #include <nss.h>
11 #include <pk11pub.h>
12 #include <prtime.h>
13 #include <seccomon.h>
14 #include <secder.h>
15 #include <sechash.h>
16
17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/pickle.h"
20 #include "base/time.h"
21 #include "crypto/nss_util.h"
22 #include "crypto/rsa_private_key.h"
23 #include "crypto/scoped_nss_types.h"
24 #include "net/base/x509_util_nss.h"
25
26 namespace net {
27
28 void X509Certificate::Initialize() {
29 x509_util::ParsePrincipal(&cert_handle_->subject, &subject_);
30 x509_util::ParsePrincipal(&cert_handle_->issuer, &issuer_);
31
32 x509_util::ParseDate(&cert_handle_->validity.notBefore, &valid_start_);
33 x509_util::ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_);
34
35 fingerprint_ = CalculateFingerprint(cert_handle_);
36 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
37
38 serial_number_ = x509_util::ParseSerialNumber(cert_handle_);
39 }
40
41 // static
42 X509Certificate* X509Certificate::CreateFromBytesWithNickname(
43 const char* data,
44 int length,
45 const char* nickname) {
46 OSCertHandle cert_handle = CreateOSCertHandleFromBytesWithNickname(data,
47 length,
48 nickname);
49 if (!cert_handle)
50 return NULL;
51
52 X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles());
53 FreeOSCertHandle(cert_handle);
54
55 if (nickname)
56 cert->default_nickname_ = nickname;
57
58 return cert;
59 }
60
61 std::string X509Certificate::GetDefaultNickname(CertType type) const {
62 if (!default_nickname_.empty())
63 return default_nickname_;
64
65 std::string result;
66 if (type == USER_CERT && cert_handle_->slot) {
67 // Find the private key for this certificate and see if it has a
68 // nickname. If there is a private key, and it has a nickname, then
69 // we return that nickname.
70 SECKEYPrivateKey* private_key = PK11_FindPrivateKeyFromCert(
71 cert_handle_->slot,
72 cert_handle_,
73 NULL); // wincx
74 if (private_key) {
75 char* private_key_nickname = PK11_GetPrivateKeyNickname(private_key);
76 if (private_key_nickname) {
77 result = private_key_nickname;
78 PORT_Free(private_key_nickname);
79 SECKEY_DestroyPrivateKey(private_key);
80 return result;
81 }
82 SECKEY_DestroyPrivateKey(private_key);
83 }
84 }
85
86 switch (type) {
87 case CA_CERT: {
88 char* nickname = CERT_MakeCANickname(cert_handle_);
89 result = nickname;
90 PORT_Free(nickname);
91 break;
92 }
93 case USER_CERT: {
94 // Create a nickname for a user certificate.
95 // We use the scheme used by Firefox:
96 // --> <subject's common name>'s <issuer's common name> ID.
97 // TODO(gspencer): internationalize this: it's wrong to
98 // hard code English.
99
100 std::string username, ca_name;
101 char* temp_username = CERT_GetCommonName(
102 &cert_handle_->subject);
103 char* temp_ca_name = CERT_GetCommonName(&cert_handle_->issuer);
104 if (temp_username) {
105 username = temp_username;
106 PORT_Free(temp_username);
107 }
108 if (temp_ca_name) {
109 ca_name = temp_ca_name;
110 PORT_Free(temp_ca_name);
111 }
112 result = username + "'s " + ca_name + " ID";
113 break;
114 }
115 case SERVER_CERT:
116 result = subject_.GetDisplayName();
117 break;
118 case UNKNOWN_CERT:
119 default:
120 break;
121 }
122 return result;
123 }
124
125 // static
126 X509Certificate* X509Certificate::CreateSelfSigned(
127 crypto::RSAPrivateKey* key,
128 const std::string& subject,
129 uint32 serial_number,
130 base::TimeDelta valid_duration) {
131 DCHECK(key);
132 base::Time not_valid_before = base::Time::Now();
133 base::Time not_valid_after = not_valid_before + valid_duration;
134 CERTCertificate* cert = x509_util::CreateSelfSignedCert(key->public_key(),
135 key->key(),
136 subject,
137 serial_number,
138 not_valid_before,
139 not_valid_after);
140 if (!cert)
141 return NULL;
142
143 X509Certificate* x509_cert = X509Certificate::CreateFromHandle(
144 cert, X509Certificate::OSCertHandles());
145 CERT_DestroyCertificate(cert);
146 return x509_cert;
147 }
148
149 void X509Certificate::GetSubjectAltName(
150 std::vector<std::string>* dns_names,
151 std::vector<std::string>* ip_addrs) const {
152 x509_util::GetSubjectAltName(cert_handle_, dns_names, ip_addrs);
153 }
154
155 bool X509Certificate::VerifyNameMatch(const std::string& hostname) const {
156 return CERT_VerifyCertName(cert_handle_, hostname.c_str()) == SECSuccess;
157 }
158
159 bool X509Certificate::IsIssuedByEncoded(
160 const std::vector<std::string>& valid_issuers) {
161 // Get certificate chain as scoped list of CERTCertificate objects.
162 std::vector<CERTCertificate*> cert_chain;
163 cert_chain.push_back(cert_handle_);
164 for (size_t n = 0; n < intermediate_ca_certs_.size(); ++n) {
165 cert_chain.push_back(intermediate_ca_certs_[n]);
166 }
167 // Convert encoded issuers to scoped CERTName* list.
168 std::vector<CERTName*> issuers;
169 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
170 if (!x509_util::GetIssuersFromEncodedList(valid_issuers,
171 arena.get(),
172 &issuers)) {
173 return false;
174 }
175 return x509_util::IsCertificateIssuedBy(cert_chain, issuers);
176 }
177
178 // static
179 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle,
180 std::string* encoded) {
181 if (!cert_handle->derCert.len)
182 return false;
183 encoded->assign(reinterpret_cast<char*>(cert_handle->derCert.data),
184 cert_handle->derCert.len);
185 return true;
186 }
187
188 // static
189 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
190 X509Certificate::OSCertHandle b) {
191 DCHECK(a && b);
192 if (a == b)
193 return true;
194 return a->derCert.len == b->derCert.len &&
195 memcmp(a->derCert.data, b->derCert.data, a->derCert.len) == 0;
196 }
197
198 // static
199 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
200 const char* data, int length) {
201 return CreateOSCertHandleFromBytesWithNickname(data, length, NULL);
202 }
203
204 // static
205 X509Certificate::OSCertHandle
206 X509Certificate::CreateOSCertHandleFromBytesWithNickname(
207 const char* data,
208 int length,
209 const char* nickname) {
210 if (length < 0)
211 return NULL;
212
213 crypto::EnsureNSSInit();
214
215 if (!NSS_IsInitialized())
216 return NULL;
217
218 SECItem der_cert;
219 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
220 der_cert.len = length;
221 der_cert.type = siDERCertBuffer;
222
223 // Parse into a certificate structure.
224 return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert,
225 const_cast<char*>(nickname),
226 PR_FALSE, PR_TRUE);
227 }
228
229 // static
230 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
231 const char* data,
232 int length,
233 Format format) {
234 return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
235 }
236
237 // static
238 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
239 OSCertHandle cert_handle) {
240 return CERT_DupCertificate(cert_handle);
241 }
242
243 // static
244 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
245 CERT_DestroyCertificate(cert_handle);
246 }
247
248 // static
249 SHA1HashValue X509Certificate::CalculateFingerprint(
250 OSCertHandle cert) {
251 SHA1HashValue sha1;
252 memset(sha1.data, 0, sizeof(sha1.data));
253
254 DCHECK(NULL != cert->derCert.data);
255 DCHECK_NE(0U, cert->derCert.len);
256
257 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data,
258 cert->derCert.data, cert->derCert.len);
259 DCHECK_EQ(SECSuccess, rv);
260
261 return sha1;
262 }
263
264 // static
265 SHA1HashValue X509Certificate::CalculateCAFingerprint(
266 const OSCertHandles& intermediates) {
267 SHA1HashValue sha1;
268 memset(sha1.data, 0, sizeof(sha1.data));
269
270 HASHContext* sha1_ctx = HASH_Create(HASH_AlgSHA1);
271 if (!sha1_ctx)
272 return sha1;
273 HASH_Begin(sha1_ctx);
274 for (size_t i = 0; i < intermediates.size(); ++i) {
275 CERTCertificate* ca_cert = intermediates[i];
276 HASH_Update(sha1_ctx, ca_cert->derCert.data, ca_cert->derCert.len);
277 }
278 unsigned int result_len;
279 HASH_End(sha1_ctx, sha1.data, &result_len, HASH_ResultLenContext(sha1_ctx));
280 HASH_Destroy(sha1_ctx);
281
282 return sha1;
283 }
284
285 // static
286 X509Certificate::OSCertHandle
287 X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) {
288 return x509_util::ReadOSCertHandleFromPickle(pickle_iter);
289 }
290
291 // static
292 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
293 Pickle* pickle) {
294 return pickle->WriteData(
295 reinterpret_cast<const char*>(cert_handle->derCert.data),
296 cert_handle->derCert.len);
297 }
298
299 // static
300 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
301 size_t* size_bits,
302 PublicKeyType* type) {
303 x509_util::GetPublicKeyInfo(cert_handle, size_bits, type);
304 }
305
306 } // namespace net
OLDNEW
« no previous file with comments | « net/base/x509_certificate_net_log_param.cc ('k') | net/base/x509_certificate_openssl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698