1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SECURITY_MANAGER_SSL_TLSCLIENTAUTHCERTSELECTION_H_
#define SECURITY_MANAGER_SSL_TLSCLIENTAUTHCERTSELECTION_H_
#include "NSSSocketControl.h"
#include "nsIX509Cert.h"
#include "nsNSSIOLayer.h"
#include "nsThreadUtils.h"
#include "ssl.h"
class NSSSocketControl;
// NSS callback to select a client authentication certificate. See documentation
// at the top of TLSClientAuthCertSelection.cpp.
SECStatus SSLGetClientAuthDataHook(void* arg, PRFileDesc* socket,
CERTDistNames* caNames,
CERTCertificate** pRetCert,
SECKEYPrivateKey** pRetKey);
// Base class for continuing the operation of selecting a client authentication
// certificate. Should not be used directly.
class ClientAuthCertificateSelectedBase : public mozilla::Runnable {
public:
ClientAuthCertificateSelectedBase()
: Runnable("ClientAuthCertificateSelectedBase") {}
// Call to indicate that a client authentication certificate has been
// selected.
void SetSelectedClientAuthData(
nsTArray<uint8_t>&& selectedCertBytes,
nsTArray<nsTArray<uint8_t>>&& selectedCertChainBytes);
protected:
nsTArray<uint8_t> mSelectedCertBytes;
// The bytes of the certificates that form a chain from the selected
// certificate to a root. Necessary so NSS can include them in the TLS
// handshake (see note about mClientCertChain in NSSSocketControl).
nsTArray<nsTArray<uint8_t>> mSelectedCertChainBytes;
};
class ClientAuthCertificateSelected : public ClientAuthCertificateSelectedBase {
public:
explicit ClientAuthCertificateSelected(NSSSocketControl* socketInfo)
: mSocketInfo(socketInfo) {}
NS_IMETHOD Run() override;
private:
RefPtr<NSSSocketControl> mSocketInfo;
};
// This class is used to store the needed information for invoking the client
// cert selection UI.
class ClientAuthInfo final {
public:
explicit ClientAuthInfo(const nsACString& hostName,
const mozilla::OriginAttributes& originAttributes,
int32_t port, uint32_t providerFlags,
uint32_t providerTlsFlags);
~ClientAuthInfo() = default;
ClientAuthInfo(ClientAuthInfo&& aOther) noexcept;
const nsACString& HostName() const;
const mozilla::OriginAttributes& OriginAttributesRef() const;
int32_t Port() const;
uint32_t ProviderFlags() const;
uint32_t ProviderTlsFlags() const;
ClientAuthInfo(const ClientAuthInfo&) = delete;
void operator=(const ClientAuthInfo&) = delete;
private:
nsCString mHostName;
mozilla::OriginAttributes mOriginAttributes;
int32_t mPort;
uint32_t mProviderFlags;
uint32_t mProviderTlsFlags;
};
// Helper runnable to select a client authentication certificate. Gets created
// on the socket thread or an IPC thread, runs on the main thread, and then runs
// its continuation on the socket thread.
class SelectClientAuthCertificate : public mozilla::Runnable {
public:
SelectClientAuthCertificate(
ClientAuthInfo&& info, mozilla::UniqueCERTCertificate&& serverCert,
nsTArray<nsTArray<uint8_t>>&& caNames,
mozilla::UniqueCERTCertList&& potentialClientCertificates,
ClientAuthCertificateSelectedBase* continuation)
: Runnable("SelectClientAuthCertificate"),
mInfo(std::move(info)),
mServerCert(std::move(serverCert)),
mCANames(std::move(caNames)),
mPotentialClientCertificates(std::move(potentialClientCertificates)),
mContinuation(continuation) {}
NS_IMETHOD Run() override;
private:
mozilla::pkix::Result BuildChainForCertificate(
nsTArray<uint8_t>& certBytes,
nsTArray<nsTArray<uint8_t>>& certChainBytes);
void DoSelectClientAuthCertificate();
ClientAuthInfo mInfo;
mozilla::UniqueCERTCertificate mServerCert;
nsTArray<nsTArray<uint8_t>> mCANames;
mozilla::UniqueCERTCertList mPotentialClientCertificates;
RefPtr<ClientAuthCertificateSelectedBase> mContinuation;
nsTArray<nsTArray<uint8_t>> mEnterpriseCertificates;
nsTArray<uint8_t> mSelectedCertBytes;
};
#endif // SECURITY_MANAGER_SSL_TLSCLIENTAUTHCERTSELECTION_H_
|