xref: /aosp_15_r20/external/cronet/net/ssl/client_cert_identity.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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