-
Notifications
You must be signed in to change notification settings - Fork 6
/
NSSHelper.h
193 lines (158 loc) · 9.59 KB
/
NSSHelper.h
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* -*- 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/. */
#pragma once
#include "prio.h"
#include "ssl.h"
#include "pk11pub.h"
#include "sslexp.h"
namespace mozquic {
class MozQuic;
// if you Read() from the helper, it pulls through the tls layer from the mozquic::stream0 buffer where
// peer data lke the client hello is stored.. if you Write() to the helper something
// like "", the tls layer adds the server hello on the way out into mozquic::stream0
class NSSHelper final
{
public:
static int Init(char *dir);
NSSHelper(MozQuic *quicSession, bool tolerateBadALPN, const char *originKey);
NSSHelper(MozQuic *quicSession, bool tolerateBadALPN, const char *originKey, bool clientindicator);
~NSSHelper();
uint32_t ReadTLSData();
uint32_t DriveHandshake();
bool IsHandshakeComplete() { return mHandshakeComplete; }
uint32_t HandshakeSecret(unsigned int ciphersuite, unsigned char *sendSecret, unsigned char *recvSecret);
uint32_t EncryptBlock(const unsigned char *aeadData, uint32_t aeadLen,
const unsigned char *plaintext, uint32_t plaintextLen,
uint64_t packetNumber,
unsigned char *out, uint32_t outAvail, uint32_t &written);
uint32_t DecryptBlock(const unsigned char *aeadData, uint32_t aeadLen,
const unsigned char *ciphertext, uint32_t ciphertextLen,
uint64_t packetNumber,
unsigned char *out, uint32_t outAvail, uint32_t &written);
uint32_t EncryptHandshake(const unsigned char *aeadData, uint32_t aeadLen,
const unsigned char *plaintext, uint32_t plaintextLen,
uint64_t packetNumber,
CID cid, unsigned char *out, uint32_t outAvail, uint32_t &written);
uint32_t DecryptHandshake(const unsigned char *aeadData, uint32_t aeadLen,
const unsigned char *ciphertext, uint32_t ciphertextLen,
uint64_t packetNumber,
CID cid, unsigned char *out, uint32_t outAvail, uint32_t &written);
uint32_t EncryptBlock0RTT(const unsigned char *aeadData, uint32_t aeadLen,
const unsigned char *plaintext, uint32_t plaintextLen,
uint64_t packetNumber,
unsigned char *out, uint32_t outAvail, uint32_t &written);
uint32_t DecryptBlock0RTT(const unsigned char *aeadData, uint32_t aeadLen,
const unsigned char *ciphertext, uint32_t ciphertextLen,
uint64_t packetNumber,
unsigned char *out, uint32_t outAvail, uint32_t &written);
CK_MECHANISM_TYPE ModeToMechanism(enum operationType mode);
PK11SymKey * ModeToPNKey(enum operationType mode);
void EncryptPNInPlace(enum operationType mode, unsigned char *pn,
const unsigned char *cipherTextToSample,
uint32_t cipherLen);
void DecryptPNInPlace(enum operationType mode, unsigned char *pn,
const unsigned char *cipherTextToSample, uint32_t cipherLen);
bool SetLocalTransportExtensionInfo(const unsigned char *data, uint16_t datalen); // local data to send
bool SetRemoteTransportExtensionInfo(const unsigned char *data, uint16_t datalen); // remote data recvd
void GetRemoteTransportExtensionInfo(unsigned char * &_output, uint16_t &actual) {
_output = mRemoteTransportExtensionInfo;
actual = mRemoteTransportExtensionLen;
}
static const uint32_t kTransportParametersID = 26;
bool DoHRR() {return mDoHRR;}
bool IsEarlyDataPossible();
bool IsEarlyDataAcceptedServer();
bool IsEarlyDataAcceptedClient();
private:
static void DecryptPNInPlace(unsigned char *pn,
CK_MECHANISM_TYPE mechToUse,
PK11SymKey *keyToUse,
const unsigned char *cipherTextToSample, uint32_t cipherLen);
void SharedInit();
static PRStatus NSPRGetPeerName(PRFileDesc *aFD, PRNetAddr*addr);
static PRStatus NSPRGetSocketOption(PRFileDesc *aFD, PRSocketOptionData *aOpt);
static PRStatus nssHelperConnect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime to);
static int nssHelperWrite(PRFileDesc *aFD, const void *aBuf, int32_t aAmount);
static int nssHelperSend(PRFileDesc *aFD, const void *aBuf, int32_t aAmount,
int , PRIntervalTime);
static int32_t nssHelperRead(PRFileDesc *fd, void *buf, int32_t amount);
static int32_t nssHelperRecv(PRFileDesc *fd, void *buf, int32_t amount, int flags,
PRIntervalTime timeout);
static SSLHelloRetryRequestAction HRRCallback(PRBool firstHello, const unsigned char *clientToken,
unsigned int clientTokenLen, unsigned char *retryToken,
unsigned int *retryTokenLen, unsigned int retryTokMax,
void *arg);
static void HandshakeCallback(PRFileDesc *fd, void *);
static SECStatus BadCertificate(void *client_data, PRFileDesc *fd);
static PRBool TransportExtensionWriter(PRFileDesc *fd, SSLHandshakeType m, PRUint8 *data,
unsigned int *len, unsigned int maxlen, void *arg);
static SECStatus TransportExtensionHandler(PRFileDesc *fd, SSLHandshakeType m, const PRUint8 *data,
unsigned int len, SSLAlertDescription *alert, void *arg);
uint32_t BlockOperation(enum operationType mode, const unsigned char *aeadData, uint32_t aeadLen,
const unsigned char *plaintext, uint32_t plaintextLen,
uint64_t packetNumber,
unsigned char *out, uint32_t outAvail, uint32_t &written);
uint32_t MakeKeyFromNSS(PRFileDesc *fd, bool earlyKey, const char *label,
unsigned int secretSize, unsigned int keySize, SSLHashType hashType,
CK_MECHANISM_TYPE importMechanism1, CK_MECHANISM_TYPE importMechanism2,
unsigned char *outIV, PK11SymKey **outKey, PK11SymKey **outPNKey);
public:
static uint32_t MakeKeyFromRaw(unsigned char *initialSecret,
unsigned int secretSize, unsigned int keySize, SSLHashType hashType,
CK_MECHANISM_TYPE importMechanism1, CK_MECHANISM_TYPE importMechanism2,
unsigned char *outIV, PK11SymKey **outKey, PK11SymKey **outPNKey);
static uint32_t staticDecryptHandshake(const unsigned char *aadData, uint32_t aadLen,
const unsigned char *data, uint32_t dataLen,
uint64_t packetNumber, CID connectionID,
unsigned char *out, uint32_t outAvail, uint32_t &written);
static void staticDecryptPNInPlace(unsigned char *pn,
CID connectionID,
const unsigned char *cipherTextToSample,
uint32_t cipherLen);
static uint64_t SockAddrHasher(const struct sockaddr *);
private:
static void GetKeyParamsFromCipherSuite(uint16_t cipherSuite,
unsigned int &secretSize,
unsigned int &keySize,
SSLHashType &hashType,
CK_MECHANISM_TYPE &packetMechanism,
CK_MECHANISM_TYPE &importMechanism1,
CK_MECHANISM_TYPE &importMechanism2);
void MakeHandshakeKeys(CID cid);
MozQuic *mMozQuic;
PRFileDesc *mFD;
bool mNSSReady;
bool mHandshakeComplete;
bool mHandshakeFailed; // complete but bad above nss
bool mIsClient;
bool mTolerateBadALPN;
bool mDoHRR;
unsigned char mExternalSendSecret[48];
unsigned char mExternalRecvSecret[48];
unsigned int mExternalCipherSuite;
unsigned char mLocalTransportExtensionInfo[2048];
uint16_t mLocalTransportExtensionLen;
unsigned char mRemoteTransportExtensionInfo[2048];
uint16_t mRemoteTransportExtensionLen;
CK_MECHANISM_TYPE mPacketProtectionMech;
PK11SymKey *mPacketProtectionSenderPNKey;
PK11SymKey *mPacketProtectionSenderKey0;
unsigned char mPacketProtectionSenderIV0[12];
PK11SymKey *mPacketProtectionReceiverPNKey;
PK11SymKey *mPacketProtectionReceiverKey0;
unsigned char mPacketProtectionReceiverIV0[12];
CK_MECHANISM_TYPE mPacketProtectionMech0RTT;
PK11SymKey *mPacketProtectionKey0RTT;
PK11SymKey *mPacketProtectionPNKey0RTT;
unsigned char mPacketProtectionIV0RTT[12];
CID mPacketProtectionHandshakeCID;
PK11SymKey *mPacketProtectionHandshakeSenderPNKey;
PK11SymKey *mPacketProtectionHandshakeSenderKey;
unsigned char mPacketProtectionHandshakeSenderIV[12];
PK11SymKey *mPacketProtectionHandshakeReceiverPNKey;
PK11SymKey *mPacketProtectionHandshakeReceiverKey;
unsigned char mPacketProtectionHandshakeReceiverIV[12];
};
} //namespace