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_util.h"
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/time/time.h"
10 #include "crypto/ec_private_key.h"
11 #include "crypto/rsa_private_key.h"
12 #include "net/cert/x509_certificate.h"
18 // RSA keys created by CreateKeyAndSelfSignedCert will be of this length.
19 static const uint16 kRSAKeyLength
= 1024;
21 // Certificates made by CreateKeyAndSelfSignedCert and
22 // CreateKeyAndDomainBoundCertEC will be signed using this digest algorithm.
23 static const DigestAlgorithm kSignatureDigestAlgorithm
= DIGEST_SHA256
;
25 ClientCertSorter::ClientCertSorter() : now_(base::Time::Now()) {}
27 bool ClientCertSorter::operator()(
28 const scoped_refptr
<X509Certificate
>& a
,
29 const scoped_refptr
<X509Certificate
>& b
) const {
30 // Certificates that are null are sorted last.
31 if (!a
.get() || !b
.get())
32 return a
.get() && !b
.get();
34 // Certificates that are expired/not-yet-valid are sorted last.
35 bool a_is_valid
= now_
>= a
->valid_start() && now_
<= a
->valid_expiry();
36 bool b_is_valid
= now_
>= b
->valid_start() && now_
<= b
->valid_expiry();
37 if (a_is_valid
!= b_is_valid
)
38 return a_is_valid
&& !b_is_valid
;
40 // Certificates with longer expirations appear as higher priority (less
41 // than) certificates with shorter expirations.
42 if (a
->valid_expiry() != b
->valid_expiry())
43 return a
->valid_expiry() > b
->valid_expiry();
45 // If the expiration dates are equivalent, certificates that were issued
46 // more recently should be prioritized over older certificates.
47 if (a
->valid_start() != b
->valid_start())
48 return a
->valid_start() > b
->valid_start();
50 // Otherwise, prefer client certificates with shorter chains.
51 const X509Certificate::OSCertHandles
& a_intermediates
=
52 a
->GetIntermediateCertificates();
53 const X509Certificate::OSCertHandles
& b_intermediates
=
54 b
->GetIntermediateCertificates();
55 return a_intermediates
.size() < b_intermediates
.size();
58 bool CreateKeyAndDomainBoundCertEC(const std::string
& domain
,
60 base::Time not_valid_before
,
61 base::Time not_valid_after
,
62 scoped_ptr
<crypto::ECPrivateKey
>* key
,
63 std::string
* der_cert
) {
64 scoped_ptr
<crypto::ECPrivateKey
> new_key(crypto::ECPrivateKey::Create());
68 bool success
= CreateDomainBoundCertEC(new_key
.get(),
69 kSignatureDigestAlgorithm
,
76 key
->reset(new_key
.release());
81 bool CreateKeyAndSelfSignedCert(const std::string
& subject
,
83 base::Time not_valid_before
,
84 base::Time not_valid_after
,
85 scoped_ptr
<crypto::RSAPrivateKey
>* key
,
86 std::string
* der_cert
) {
87 scoped_ptr
<crypto::RSAPrivateKey
> new_key(
88 crypto::RSAPrivateKey::Create(kRSAKeyLength
));
92 bool success
= CreateSelfSignedCert(new_key
.get(),
93 kSignatureDigestAlgorithm
,
100 key
->reset(new_key
.release());
105 } // namespace x509_util