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
X509Certificate::ReadOSCertHandleFromPickle(
265 base::PickleIterator
* pickle_iter
) {
266 return x509_util::ReadOSCertHandleFromPickle(pickle_iter
);
270 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle
,
271 base::Pickle
* pickle
) {
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
);