1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/ssl/client_cert_identity.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <utility>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
10*6777b538SAndroid Build Coastguard Worker #include "net/cert/x509_util.h"
11*6777b538SAndroid Build Coastguard Worker #include "net/ssl/ssl_private_key.h"
12*6777b538SAndroid Build Coastguard Worker
13*6777b538SAndroid Build Coastguard Worker namespace net {
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker namespace {
16*6777b538SAndroid Build Coastguard Worker
IdentityOwningPrivateKeyCallback(std::unique_ptr<ClientCertIdentity> identity,base::OnceCallback<void (scoped_refptr<SSLPrivateKey>)> private_key_callback,scoped_refptr<SSLPrivateKey> private_key)17*6777b538SAndroid Build Coastguard Worker void IdentityOwningPrivateKeyCallback(
18*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ClientCertIdentity> identity,
19*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)> private_key_callback,
20*6777b538SAndroid Build Coastguard Worker scoped_refptr<SSLPrivateKey> private_key) {
21*6777b538SAndroid Build Coastguard Worker std::move(private_key_callback).Run(std::move(private_key));
22*6777b538SAndroid Build Coastguard Worker }
23*6777b538SAndroid Build Coastguard Worker
24*6777b538SAndroid Build Coastguard Worker } // namespace
25*6777b538SAndroid Build Coastguard Worker
ClientCertIdentity(scoped_refptr<net::X509Certificate> cert)26*6777b538SAndroid Build Coastguard Worker ClientCertIdentity::ClientCertIdentity(scoped_refptr<net::X509Certificate> cert)
27*6777b538SAndroid Build Coastguard Worker : cert_(std::move(cert)) {}
28*6777b538SAndroid Build Coastguard Worker ClientCertIdentity::~ClientCertIdentity() = default;
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker // static
SelfOwningAcquirePrivateKey(std::unique_ptr<ClientCertIdentity> self,base::OnceCallback<void (scoped_refptr<SSLPrivateKey>)> private_key_callback)31*6777b538SAndroid Build Coastguard Worker void ClientCertIdentity::SelfOwningAcquirePrivateKey(
32*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ClientCertIdentity> self,
33*6777b538SAndroid Build Coastguard Worker base::OnceCallback<void(scoped_refptr<SSLPrivateKey>)>
34*6777b538SAndroid Build Coastguard Worker private_key_callback) {
35*6777b538SAndroid Build Coastguard Worker ClientCertIdentity* self_ptr = self.get();
36*6777b538SAndroid Build Coastguard Worker auto wrapped_private_key_callback =
37*6777b538SAndroid Build Coastguard Worker base::BindOnce(&IdentityOwningPrivateKeyCallback, std::move(self),
38*6777b538SAndroid Build Coastguard Worker std::move(private_key_callback));
39*6777b538SAndroid Build Coastguard Worker self_ptr->AcquirePrivateKey(std::move(wrapped_private_key_callback));
40*6777b538SAndroid Build Coastguard Worker }
41*6777b538SAndroid Build Coastguard Worker
SetIntermediates(std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates)42*6777b538SAndroid Build Coastguard Worker void ClientCertIdentity::SetIntermediates(
43*6777b538SAndroid Build Coastguard Worker std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates) {
44*6777b538SAndroid Build Coastguard Worker cert_ = cert_->CloneWithDifferentIntermediates(std::move(intermediates));
45*6777b538SAndroid Build Coastguard Worker DCHECK(cert_);
46*6777b538SAndroid Build Coastguard Worker }
47*6777b538SAndroid Build Coastguard Worker
ClientCertIdentitySorter()48*6777b538SAndroid Build Coastguard Worker ClientCertIdentitySorter::ClientCertIdentitySorter()
49*6777b538SAndroid Build Coastguard Worker : now_(base::Time::Now()) {}
50*6777b538SAndroid Build Coastguard Worker
operator ()(const std::unique_ptr<ClientCertIdentity> & a_identity,const std::unique_ptr<ClientCertIdentity> & b_identity) const51*6777b538SAndroid Build Coastguard Worker bool ClientCertIdentitySorter::operator()(
52*6777b538SAndroid Build Coastguard Worker const std::unique_ptr<ClientCertIdentity>& a_identity,
53*6777b538SAndroid Build Coastguard Worker const std::unique_ptr<ClientCertIdentity>& b_identity) const {
54*6777b538SAndroid Build Coastguard Worker X509Certificate* a = a_identity->certificate();
55*6777b538SAndroid Build Coastguard Worker X509Certificate* b = b_identity->certificate();
56*6777b538SAndroid Build Coastguard Worker DCHECK(a);
57*6777b538SAndroid Build Coastguard Worker DCHECK(b);
58*6777b538SAndroid Build Coastguard Worker
59*6777b538SAndroid Build Coastguard Worker // Certificates that are expired/not-yet-valid are sorted last.
60*6777b538SAndroid Build Coastguard Worker bool a_is_valid = now_ >= a->valid_start() && now_ <= a->valid_expiry();
61*6777b538SAndroid Build Coastguard Worker bool b_is_valid = now_ >= b->valid_start() && now_ <= b->valid_expiry();
62*6777b538SAndroid Build Coastguard Worker if (a_is_valid != b_is_valid)
63*6777b538SAndroid Build Coastguard Worker return a_is_valid && !b_is_valid;
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker // Certificates with longer expirations appear as higher priority (less
66*6777b538SAndroid Build Coastguard Worker // than) certificates with shorter expirations.
67*6777b538SAndroid Build Coastguard Worker if (a->valid_expiry() != b->valid_expiry())
68*6777b538SAndroid Build Coastguard Worker return a->valid_expiry() > b->valid_expiry();
69*6777b538SAndroid Build Coastguard Worker
70*6777b538SAndroid Build Coastguard Worker // If the expiration dates are equivalent, certificates that were issued
71*6777b538SAndroid Build Coastguard Worker // more recently should be prioritized over older certificates.
72*6777b538SAndroid Build Coastguard Worker if (a->valid_start() != b->valid_start())
73*6777b538SAndroid Build Coastguard Worker return a->valid_start() > b->valid_start();
74*6777b538SAndroid Build Coastguard Worker
75*6777b538SAndroid Build Coastguard Worker // Otherwise, prefer client certificates with shorter chains.
76*6777b538SAndroid Build Coastguard Worker const auto& a_intermediates = a->intermediate_buffers();
77*6777b538SAndroid Build Coastguard Worker const auto& b_intermediates = b->intermediate_buffers();
78*6777b538SAndroid Build Coastguard Worker return a_intermediates.size() < b_intermediates.size();
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker
81*6777b538SAndroid Build Coastguard Worker } // namespace net
82