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.
5 #include "net/cert/x509_certificate.h"
17 #include "base/logging.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/pickle.h"
20 #include "base/strings/stringprintf.h"
21 #include "base/time/time.h"
22 #include "crypto/nss_util.h"
23 #include "crypto/scoped_nss_types.h"
24 #include "net/cert/x509_util_nss.h"
28 void X509Certificate::Initialize() {
29 x509_util::ParsePrincipal(&cert_handle_->subject, &subject_);
30 x509_util::ParsePrincipal(&cert_handle_->issuer, &issuer_);
32 x509_util::ParseDate(&cert_handle_->validity.notBefore, &valid_start_);
33 x509_util::ParseDate(&cert_handle_->validity.notAfter, &valid_expiry_);
35 fingerprint_ = CalculateFingerprint(cert_handle_);
36 ca_fingerprint_ = CalculateCAFingerprint(intermediate_ca_certs_);
38 serial_number_ = x509_util::ParseSerialNumber(cert_handle_);
42 X509Certificate* X509Certificate::CreateFromBytesWithNickname(
45 const char* nickname) {
46 OSCertHandle cert_handle = CreateOSCertHandleFromBytesWithNickname(data,
52 X509Certificate* cert = CreateFromHandle(cert_handle, OSCertHandles());
53 FreeOSCertHandle(cert_handle);
56 cert->default_nickname_ = nickname;
61 std::string X509Certificate::GetDefaultNickname(CertType type) const {
62 if (!default_nickname_.empty())
63 return default_nickname_;
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 // return that nickname.
70 SECKEYPrivateKey* private_key = PK11_FindPrivateKeyFromCert(
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);
82 SECKEY_DestroyPrivateKey(private_key);
88 char* nickname = CERT_MakeCANickname(cert_handle_);
94 std::string subject_name = subject_.GetDisplayName();
95 if (subject_name.empty()) {
96 const char* email = CERT_GetFirstEmailAddress(cert_handle_);
100 // TODO(gspencer): Internationalize this. It's wrong to assume English
102 result = base::StringPrintf("%s's %s ID", subject_name.c_str(),
103 issuer_.GetDisplayName().c_str());
107 result = subject_.GetDisplayName();
116 void X509Certificate::GetSubjectAltName(
117 std::vector<std::string>* dns_names,
118 std::vector<std::string>* ip_addrs) const {
119 x509_util::GetSubjectAltName(cert_handle_, dns_names, ip_addrs);
122 bool X509Certificate::IsIssuedByEncoded(
123 const std::vector<std::string>& valid_issuers) {
124 // Get certificate chain as scoped list of CERTCertificate objects.
125 std::vector<CERTCertificate*> cert_chain;
126 cert_chain.push_back(cert_handle_);
127 for (size_t n = 0; n < intermediate_ca_certs_.size(); ++n) {
128 cert_chain.push_back(intermediate_ca_certs_[n]);
130 // Convert encoded issuers to scoped CERTName* list.
131 std::vector<CERTName*> issuers;
132 crypto::ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
133 if (!x509_util::GetIssuersFromEncodedList(valid_issuers,
138 return x509_util::IsCertificateIssuedBy(cert_chain, issuers);
142 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle,
143 std::string* encoded) {
144 if (!cert_handle || !cert_handle->derCert.len)
146 encoded->assign(reinterpret_cast<char*>(cert_handle->derCert.data),
147 cert_handle->derCert.len);
152 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a,
153 X509Certificate::OSCertHandle b) {
157 return a->derCert.len == b->derCert.len &&
158 memcmp(a->derCert.data, b->derCert.data, a->derCert.len) == 0;
162 X509Certificate::OSCertHandle X509Certificate::CreateOSCertHandleFromBytes(
163 const char* data, int length) {
164 return CreateOSCertHandleFromBytesWithNickname(data, length, NULL);
168 X509Certificate::OSCertHandle
169 X509Certificate::CreateOSCertHandleFromBytesWithNickname(
172 const char* nickname) {
176 crypto::EnsureNSSInit();
178 if (!NSS_IsInitialized())
182 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(data));
183 der_cert.len = length;
184 der_cert.type = siDERCertBuffer;
186 // Parse into a certificate structure.
187 return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert,
188 const_cast<char*>(nickname),
193 X509Certificate::OSCertHandles X509Certificate::CreateOSCertHandlesFromBytes(
197 return x509_util::CreateOSCertHandlesFromBytes(data, length, format);
201 X509Certificate::OSCertHandle X509Certificate::DupOSCertHandle(
202 OSCertHandle cert_handle) {
203 return CERT_DupCertificate(cert_handle);
207 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle) {
208 CERT_DestroyCertificate(cert_handle);
212 SHA1HashValue X509Certificate::CalculateFingerprint(
215 memset(sha1.data, 0, sizeof(sha1.data));
217 DCHECK(NULL != cert->derCert.data);
218 DCHECK_NE(0U, cert->derCert.len);
220 SECStatus rv = HASH_HashBuf(HASH_AlgSHA1, sha1.data,
221 cert->derCert.data, cert->derCert.len);
222 DCHECK_EQ(SECSuccess, rv);
228 SHA256HashValue X509Certificate::CalculateFingerprint256(OSCertHandle cert) {
229 SHA256HashValue sha256;
230 memset(sha256.data, 0, sizeof(sha256.data));
232 DCHECK(NULL != cert->derCert.data);
233 DCHECK_NE(0U, cert->derCert.len);
235 SECStatus rv = HASH_HashBuf(
236 HASH_AlgSHA256, sha256.data, cert->derCert.data, cert->derCert.len);
237 DCHECK_EQ(SECSuccess, rv);
243 SHA1HashValue X509Certificate::CalculateCAFingerprint(
244 const OSCertHandles& intermediates) {
246 memset(sha1.data, 0, sizeof(sha1.data));
248 HASHContext* sha1_ctx = HASH_Create(HASH_AlgSHA1);
251 HASH_Begin(sha1_ctx);
252 for (size_t i = 0; i < intermediates.size(); ++i) {
253 CERTCertificate* ca_cert = intermediates[i];
254 HASH_Update(sha1_ctx, ca_cert->derCert.data, ca_cert->derCert.len);
256 unsigned int result_len;
257 HASH_End(sha1_ctx, sha1.data, &result_len, HASH_ResultLenContext(sha1_ctx));
258 HASH_Destroy(sha1_ctx);
264 X509Certificate::OSCertHandle
265 X509Certificate::ReadOSCertHandleFromPickle(PickleIterator* pickle_iter) {
266 return x509_util::ReadOSCertHandleFromPickle(pickle_iter);
270 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle,
272 return pickle->WriteData(
273 reinterpret_cast<const char*>(cert_handle->derCert.data),
274 cert_handle->derCert.len);
278 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle,
280 PublicKeyType* type) {
281 x509_util::GetPublicKeyInfo(cert_handle, size_bits, type);
285 bool X509Certificate::IsSelfSigned(OSCertHandle cert_handle) {
286 crypto::ScopedSECKEYPublicKey public_key(CERT_ExtractPublicKey(cert_handle));
287 if (!public_key.get())
289 return SECSuccess == CERT_VerifySignedDataWithPublicKey(
290 &cert_handle->signatureWrap, public_key.get(), NULL);