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/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/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 // we 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 // 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
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
);
105 username
= temp_username
;
106 PORT_Free(temp_username
);
109 ca_name
= temp_ca_name
;
110 PORT_Free(temp_ca_name
);
112 result
= username
+ "'s " + ca_name
+ " ID";
116 result
= subject_
.GetDisplayName();
126 X509Certificate
* X509Certificate::CreateSelfSigned(
127 crypto::RSAPrivateKey
* key
,
128 const std::string
& subject
,
129 uint32 serial_number
,
130 base::TimeDelta valid_duration
) {
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(),
143 X509Certificate
* x509_cert
= X509Certificate::CreateFromHandle(
144 cert
, X509Certificate::OSCertHandles());
145 CERT_DestroyCertificate(cert
);
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
);
155 bool X509Certificate::VerifyNameMatch(const std::string
& hostname
) const {
156 return CERT_VerifyCertName(cert_handle_
, hostname
.c_str()) == SECSuccess
;
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
]);
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
,
175 return x509_util::IsCertificateIssuedBy(cert_chain
, issuers
);
179 bool X509Certificate::GetDEREncoded(X509Certificate::OSCertHandle cert_handle
,
180 std::string
* encoded
) {
181 if (!cert_handle
->derCert
.len
)
183 encoded
->assign(reinterpret_cast<char*>(cert_handle
->derCert
.data
),
184 cert_handle
->derCert
.len
);
189 bool X509Certificate::IsSameOSCert(X509Certificate::OSCertHandle a
,
190 X509Certificate::OSCertHandle b
) {
194 return a
->derCert
.len
== b
->derCert
.len
&&
195 memcmp(a
->derCert
.data
, b
->derCert
.data
, a
->derCert
.len
) == 0;
199 X509Certificate::OSCertHandle
X509Certificate::CreateOSCertHandleFromBytes(
200 const char* data
, int length
) {
201 return CreateOSCertHandleFromBytesWithNickname(data
, length
, NULL
);
205 X509Certificate::OSCertHandle
206 X509Certificate::CreateOSCertHandleFromBytesWithNickname(
209 const char* nickname
) {
213 crypto::EnsureNSSInit();
215 if (!NSS_IsInitialized())
219 der_cert
.data
= reinterpret_cast<unsigned char*>(const_cast<char*>(data
));
220 der_cert
.len
= length
;
221 der_cert
.type
= siDERCertBuffer
;
223 // Parse into a certificate structure.
224 return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der_cert
,
225 const_cast<char*>(nickname
),
230 X509Certificate::OSCertHandles
X509Certificate::CreateOSCertHandlesFromBytes(
234 return x509_util::CreateOSCertHandlesFromBytes(data
, length
, format
);
238 X509Certificate::OSCertHandle
X509Certificate::DupOSCertHandle(
239 OSCertHandle cert_handle
) {
240 return CERT_DupCertificate(cert_handle
);
244 void X509Certificate::FreeOSCertHandle(OSCertHandle cert_handle
) {
245 CERT_DestroyCertificate(cert_handle
);
249 SHA1HashValue
X509Certificate::CalculateFingerprint(
252 memset(sha1
.data
, 0, sizeof(sha1
.data
));
254 DCHECK(NULL
!= cert
->derCert
.data
);
255 DCHECK_NE(0U, cert
->derCert
.len
);
257 SECStatus rv
= HASH_HashBuf(HASH_AlgSHA1
, sha1
.data
,
258 cert
->derCert
.data
, cert
->derCert
.len
);
259 DCHECK_EQ(SECSuccess
, rv
);
265 SHA1HashValue
X509Certificate::CalculateCAFingerprint(
266 const OSCertHandles
& intermediates
) {
268 memset(sha1
.data
, 0, sizeof(sha1
.data
));
270 HASHContext
* sha1_ctx
= HASH_Create(HASH_AlgSHA1
);
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
);
278 unsigned int result_len
;
279 HASH_End(sha1_ctx
, sha1
.data
, &result_len
, HASH_ResultLenContext(sha1_ctx
));
280 HASH_Destroy(sha1_ctx
);
286 X509Certificate::OSCertHandle
287 X509Certificate::ReadOSCertHandleFromPickle(PickleIterator
* pickle_iter
) {
288 return x509_util::ReadOSCertHandleFromPickle(pickle_iter
);
292 bool X509Certificate::WriteOSCertHandleToPickle(OSCertHandle cert_handle
,
294 return pickle
->WriteData(
295 reinterpret_cast<const char*>(cert_handle
->derCert
.data
),
296 cert_handle
->derCert
.len
);
300 void X509Certificate::GetPublicKeyInfo(OSCertHandle cert_handle
,
302 PublicKeyType
* type
) {
303 x509_util::GetPublicKeyInfo(cert_handle
, size_bits
, type
);