OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #include <cert.h> | 7 #include <cert.h> |
8 #include <cryptohi.h> | 8 #include <cryptohi.h> |
9 #include <keyhi.h> | 9 #include <keyhi.h> |
10 #include <nss.h> | 10 #include <nss.h> |
11 #include <pk11pub.h> | 11 #include <pk11pub.h> |
12 #include <prtime.h> | 12 #include <prtime.h> |
13 #include <secder.h> | 13 #include <secder.h> |
14 #include <sechash.h> | 14 #include <sechash.h> |
15 | 15 |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
18 #include "base/pickle.h" | 18 #include "base/pickle.h" |
19 #include "base/time.h" | 19 #include "base/time.h" |
20 #include "crypto/nss_util.h" | 20 #include "crypto/nss_util.h" |
21 #include "crypto/rsa_private_key.h" | 21 #include "crypto/rsa_private_key.h" |
22 #include "crypto/scoped_nss_types.h" | |
23 #include "net/base/x509_util_nss.h" | 22 #include "net/base/x509_util_nss.h" |
24 | 23 |
25 namespace net { | 24 namespace net { |
26 | 25 |
27 namespace { | 26 void X509Certificate::Initialize() { |
| 27 x509_util::ParsePrincipal(&cert_handle_->subject, &subject_); |
| 28 x509_util::ParsePrincipal(&cert_handle_->issuer, &issuer_); |
28 | 29 |
29 void ParsePrincipal(CERTName* name, | 30 x509_util::ParseDate(&cert_handle_->validity.notBefore, &valid_start_); |
30 CertPrincipal* principal) { | 31 x509_util::ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_); |
31 typedef char* (*CERTGetNameFunc)(CERTName* name); | |
32 | |
33 // TODO(jcampan): add business_category and serial_number. | |
34 // TODO(wtc): NSS has the CERT_GetOrgName, CERT_GetOrgUnitName, and | |
35 // CERT_GetDomainComponentName functions, but they return only the most | |
36 // general (the first) RDN. NSS doesn't have a function for the street | |
37 // address. | |
38 static const SECOidTag kOIDs[] = { | |
39 SEC_OID_AVA_STREET_ADDRESS, | |
40 SEC_OID_AVA_ORGANIZATION_NAME, | |
41 SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME, | |
42 SEC_OID_AVA_DC }; | |
43 | |
44 std::vector<std::string>* values[] = { | |
45 &principal->street_addresses, | |
46 &principal->organization_names, | |
47 &principal->organization_unit_names, | |
48 &principal->domain_components }; | |
49 DCHECK(arraysize(kOIDs) == arraysize(values)); | |
50 | |
51 CERTRDN** rdns = name->rdns; | |
52 for (size_t rdn = 0; rdns[rdn]; ++rdn) { | |
53 CERTAVA** avas = rdns[rdn]->avas; | |
54 for (size_t pair = 0; avas[pair] != 0; ++pair) { | |
55 SECOidTag tag = CERT_GetAVATag(avas[pair]); | |
56 for (size_t oid = 0; oid < arraysize(kOIDs); ++oid) { | |
57 if (kOIDs[oid] == tag) { | |
58 SECItem* decode_item = CERT_DecodeAVAValue(&avas[pair]->value); | |
59 if (!decode_item) | |
60 break; | |
61 // TODO(wtc): Pass decode_item to CERT_RFC1485_EscapeAndQuote. | |
62 std::string value(reinterpret_cast<char*>(decode_item->data), | |
63 decode_item->len); | |
64 values[oid]->push_back(value); | |
65 SECITEM_FreeItem(decode_item, PR_TRUE); | |
66 break; | |
67 } | |
68 } | |
69 } | |
70 } | |
71 | |
72 // Get CN, L, S, and C. | |
73 CERTGetNameFunc get_name_funcs[4] = { | |
74 CERT_GetCommonName, CERT_GetLocalityName, | |
75 CERT_GetStateName, CERT_GetCountryName }; | |
76 std::string* single_values[4] = { | |
77 &principal->common_name, &principal->locality_name, | |
78 &principal->state_or_province_name, &principal->country_name }; | |
79 for (size_t i = 0; i < arraysize(get_name_funcs); ++i) { | |
80 char* value = get_name_funcs[i](name); | |
81 if (value) { | |
82 single_values[i]->assign(value); | |
83 PORT_Free(value); | |
84 } | |
85 } | |
86 } | |
87 | |
88 void ParseDate(SECItem* der_date, base::Time* result) { | |
89 PRTime prtime; | |
90 SECStatus rv = DER_DecodeTimeChoice(&prtime, der_date); | |
91 DCHECK_EQ(SECSuccess, rv); | |
92 *result = crypto::PRTimeToBaseTime(prtime); | |
93 } | |
94 | |
95 SECStatus PR_CALLBACK | |
96 CollectCertsCallback(void* arg, SECItem** certs, int num_certs) { | |
97 X509Certificate::OSCertHandles* results = | |
98 reinterpret_cast<X509Certificate::OSCertHandles*>(arg); | |
99 | |
100 for (int i = 0; i < num_certs; ++i) { | |
101 X509Certificate::OSCertHandle handle = | |
102 X509Certificate::CreateOSCertHandleFromBytes( | |
103 reinterpret_cast<char*>(certs[i]->data), certs[i]->len); | |
104 if (handle) | |
105 results->push_back(handle); | |
106 } | |
107 | |
108 return SECSuccess; | |
109 } | |
110 | |
111 } // namespace | |
112 | |
113 void X509Certificate::Initialize() { | |
114 ParsePrincipal(&cert_handle_->subject, &subject_); | |
115 ParsePrincipal(&cert_handle_->issuer, &issuer_); | |
116 | |
117 ParseDate(&cert_handle_->validity.notBefore, &valid_start_); | |
118 ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_); | |
119 | 32 |
120 fingerprint_ = CalculateFingerprint(cert_handle_); | 33 fingerprint_ = CalculateFingerprint(cert_handle_); |
121 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); | 34 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_); |
122 | 35 |
123 serial_number_ = std::string( | 36 serial_number_ = x509_util::ParseSerialNumber(cert_handle_); |
124 reinterpret_cast<char*>(cert_handle_->serialNumber.data), | |
125 cert_handle_->serialNumber.len); | |
126 } | 37 } |
127 | 38 |
128 // static | 39 // static |
129 X509Certificate* X509Certificate::CreateFromBytesWithNickname( | 40 X509Certificate* X509Certificate::CreateFromBytesWithNickname( |
130 const char* data, | 41 const char* data, |
131 int length, | 42 int length, |
132 const char* nickname) { | 43 const char* nickname) { |
133 OSCertHandle cert_handle = CreateOSCertHandleFromBytesWithNickname(data, | 44 OSCertHandle cert_handle = CreateOSCertHandleFromBytesWithNickname(data, |
134 length, | 45 length, |
135 nickname); | 46 nickname); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 return result; | 120 return result; |
210 } | 121 } |
211 | 122 |
212 // static | 123 // static |
213 X509Certificate* X509Certificate::CreateSelfSigned( | 124 X509Certificate* X509Certificate::CreateSelfSigned( |
214 crypto::RSAPrivateKey* key, | 125 crypto::RSAPrivateKey* key, |
215 const std::string& subject, | 126 const std::string& subject, |
216 uint32 serial_number, | 127 uint32 serial_number, |
217 base::TimeDelta valid_duration) { | 128 base::TimeDelta valid_duration) { |
218 DCHECK(key); | 129 DCHECK(key); |
219 | |
220 base::Time not_valid_before = base::Time::Now(); | 130 base::Time not_valid_before = base::Time::Now(); |
221 base::Time not_valid_after = not_valid_before + valid_duration; | 131 base::Time not_valid_after = not_valid_before + valid_duration; |
222 CERTCertificate* cert = x509_util::CreateSelfSignedCert(key->public_key(), | 132 CERTCertificate* cert = x509_util::CreateSelfSignedCert(key->public_key(), |
223 key->key(), | 133 key->key(), |
224 subject, | 134 subject, |
225 serial_number, | 135 serial_number, |
226 not_valid_before, | 136 not_valid_before, |
227 not_valid_after); | 137 not_valid_after); |
228 | |
229 if (!cert) | 138 if (!cert) |
230 return NULL; | 139 return NULL; |
231 | 140 |
232 X509Certificate* x509_cert = X509Certificate::CreateFromHandle( | 141 X509Certificate* x509_cert = X509Certificate::CreateFromHandle( |
233 cert, X509Certificate::OSCertHandles()); | 142 cert, X509Certificate::OSCertHandles()); |
234 CERT_DestroyCertificate(cert); | 143 CERT_DestroyCertificate(cert); |
235 return x509_cert; | 144 return x509_cert; |
236 } | 145 } |
237 | 146 |
238 void X509Certificate::GetSubjectAltName( | 147 void X509Certificate::GetSubjectAltName( |
239 std::vector<std::string>* dns_names, | 148 std::vector<std::string>* dns_names, |
240 std::vector<std::string>* ip_addrs) const { | 149 std::vector<std::string>* ip_addrs) const { |
241 if (dns_names) | 150 x509_util::GetSubjectAltName(cert_handle_, dns_names, ip_addrs); |
242 dns_names->clear(); | |
243 if (ip_addrs) | |
244 ip_addrs->clear(); | |
245 | |
246 SECItem alt_name; | |
247 SECStatus rv = CERT_FindCertExtension(cert_handle_, | |
248 SEC_OID_X509_SUBJECT_ALT_NAME, | |
249 &alt_name); | |
250 if (rv != SECSuccess) | |
251 return; | |
252 | |
253 PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
254 DCHECK(arena != NULL); | |
255 | |
256 CERTGeneralName* alt_name_list; | |
257 alt_name_list = CERT_DecodeAltNameExtension(arena, &alt_name); | |
258 SECITEM_FreeItem(&alt_name, PR_FALSE); | |
259 | |
260 CERTGeneralName* name = alt_name_list; | |
261 while (name) { | |
262 // DNSName and IPAddress are encoded as IA5String and OCTET STRINGs | |
263 // respectively, both of which can be byte copied from | |
264 // SECItemType::data into the appropriate output vector. | |
265 if (dns_names && name->type == certDNSName) { | |
266 dns_names->push_back(std::string( | |
267 reinterpret_cast<char*>(name->name.other.data), | |
268 name->name.other.len)); | |
269 } else if (ip_addrs && name->type == certIPAddress) { | |
270 ip_addrs->push_back(std::string( | |
271 reinterpret_cast<char*>(name->name.other.data), | |
272 name->name.other.len)); | |
273 } | |
274 name = CERT_GetNextGeneralName(name); | |
275 if (name == alt_name_list) | |
276 break; | |
277 } | |
278 PORT_FreeArena(arena, PR_FALSE); | |
279 } | 151 } |
280 | 152 |
281 bool X509Certificate::VerifyNameMatch(const std::string& hostname) const { | 153 bool X509Certificate::VerifyNameMatch(const std::string& hostname) const { |
282 return CERT_VerifyCertName(cert_handle_, hostname.c_str()) == SECSuccess; | 154 return CERT_VerifyCertName(cert_handle_, hostname.c_str()) == SECSuccess; |
283 } | 155 } |
284 | 156 |
285 // static | 157 // static |
286 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, | 158 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle, |
287 std::string* encoded) { | 159 std::string* encoded) { |
288 if (!cert_handle->derCert.len) | 160 if (!cert_handle->derCert.len) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, | 203 return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert, |
332 const_cast<char*>(nickname), | 204 const_cast<char*>(nickname), |
333 PR_FALSE, PR_TRUE); | 205 PR_FALSE, PR_TRUE); |
334 } | 206 } |
335 | 207 |
336 // static | 208 // static |
337 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( | 209 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes( |
338 const char* data, | 210 const char* data, |
339 int length, | 211 int length, |
340 Format format) { | 212 Format format) { |
341 OSCertHandles results; | 213 return x509_util::CreateOSCertHandlesFromBytes(data, length, format); |
342 if (length < 0) | |
343 return results; | |
344 | |
345 crypto::EnsureNSSInit(); | |
346 | |
347 if (!NSS_IsInitialized()) | |
348 return results; | |
349 | |
350 switch (format) { | |
351 case FORMAT_SINGLE_CERTIFICATE: { | |
352 OSCertHandle handle = CreateOSCertHandleFromBytes(data, length); | |
353 if (handle) | |
354 results.push_back(handle); | |
355 break; | |
356 } | |
357 case FORMAT_PKCS7: { | |
358 // Make a copy since CERT_DecodeCertPackage may modify it | |
359 std::vector<char> data_copy(data, data + length); | |
360 | |
361 SECStatus result = CERT_DecodeCertPackage(&data_copy[0], | |
362 length, CollectCertsCallback, &results); | |
363 if (result != SECSuccess) | |
364 results.clear(); | |
365 break; | |
366 } | |
367 default: | |
368 NOTREACHED() << "Certificate format " << format << " unimplemented"; | |
369 break; | |
370 } | |
371 | |
372 return results; | |
373 } | 214 } |
374 | 215 |
375 // static | 216 // static |
376 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( | 217 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle( |
377 OSCertHandle cert_handle) { | 218 OSCertHandle cert_handle) { |
378 return CERT_DupCertificate(cert_handle); | 219 return CERT_DupCertificate(cert_handle); |
379 } | 220 } |
380 | 221 |
381 // static | 222 // static |
382 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { | 223 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 unsigned int result_len; | 257 unsigned int result_len; |
417 HASH_End(sha1_ctx, sha1.data, &result_len, HASH_ResultLenContext(sha1_ctx)); | 258 HASH_End(sha1_ctx, sha1.data, &result_len, HASH_ResultLenContext(sha1_ctx)); |
418 HASH_Destroy(sha1_ctx); | 259 HASH_Destroy(sha1_ctx); |
419 | 260 |
420 return sha1; | 261 return sha1; |
421 } | 262 } |
422 | 263 |
423 // static | 264 // static |
424 X509Certificate::OSCertHandle | 265 X509Certificate::OSCertHandle |
425 X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { | 266 X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) { |
426 const char* data; | 267 return x509_util::ReadOSCertHandleFromPickle(pickle_iter); |
427 int length; | |
428 if (!pickle_iter->ReadData(&data, &length)) | |
429 return NULL; | |
430 | |
431 return CreateOSCertHandleFromBytes(data, length); | |
432 } | 268 } |
433 | 269 |
434 // static | 270 // static |
435 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, | 271 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle, |
436 Pickle* pickle) { | 272 Pickle* pickle) { |
437 return pickle->WriteData( | 273 return pickle->WriteData( |
438 reinterpret_cast<const char*>(cert_handle->derCert.data), | 274 reinterpret_cast<const char*>(cert_handle->derCert.data), |
439 cert_handle->derCert.len); | 275 cert_handle->derCert.len); |
440 } | 276 } |
441 | 277 |
442 // static | 278 // static |
443 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, | 279 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle, |
444 size_t* size_bits, | 280 size_t* size_bits, |
445 PublicKeyType* type) { | 281 PublicKeyType* type) { |
446 // Since we might fail, set the output parameters to default values first. | 282 x509_util::GetPublicKeyInfo(cert_handle, size_bits, type); |
447 *type = kPublicKeyTypeUnknown; | |
448 *size_bits = 0; | |
449 | |
450 crypto::ScopedSECKEYPublicKey key(CERT_ExtractPublicKey(cert_handle)); | |
451 if (!key.get()) | |
452 return; | |
453 | |
454 *size_bits = SECKEY_PublicKeyStrengthInBits(key.get()); | |
455 | |
456 switch (key->keyType) { | |
457 case rsaKey: | |
458 *type = kPublicKeyTypeRSA; | |
459 break; | |
460 case dsaKey: | |
461 *type = kPublicKeyTypeDSA; | |
462 break; | |
463 case dhKey: | |
464 *type = kPublicKeyTypeDH; | |
465 break; | |
466 case ecKey: | |
467 *type = kPublicKeyTypeECDSA; | |
468 break; | |
469 default: | |
470 *type = kPublicKeyTypeUnknown; | |
471 *size_bits = 0; | |
472 break; | |
473 } | |
474 } | 283 } |
475 | 284 |
476 } // namespace net | 285 } // namespace net |
OLD | NEW |