| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
/** |
|
2
|
|
|
|
|
|
|
* @file sslDecode.c |
|
3
|
|
|
|
|
|
|
* @version 950bba4 (HEAD -> master) |
|
4
|
|
|
|
|
|
|
* |
|
5
|
|
|
|
|
|
|
* Secure Sockets Layer protocol message decoding portion of MatrixSSL. |
|
6
|
|
|
|
|
|
|
*/ |
|
7
|
|
|
|
|
|
|
/* |
|
8
|
|
|
|
|
|
|
* Copyright (c) 2013-2017 INSIDE Secure Corporation |
|
9
|
|
|
|
|
|
|
* Copyright (c) PeerSec Networks, 2002-2011 |
|
10
|
|
|
|
|
|
|
* All Rights Reserved |
|
11
|
|
|
|
|
|
|
* |
|
12
|
|
|
|
|
|
|
* The latest version of this code is available at http://www.matrixssl.org |
|
13
|
|
|
|
|
|
|
* |
|
14
|
|
|
|
|
|
|
* This software is open source; you can redistribute it and/or modify |
|
15
|
|
|
|
|
|
|
* it under the terms of the GNU General Public License as published by |
|
16
|
|
|
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or |
|
17
|
|
|
|
|
|
|
* (at your option) any later version. |
|
18
|
|
|
|
|
|
|
* |
|
19
|
|
|
|
|
|
|
* This General Public License does NOT permit incorporating this software |
|
20
|
|
|
|
|
|
|
* into proprietary programs. If you are unable to comply with the GPL, a |
|
21
|
|
|
|
|
|
|
* commercial license for this software may be purchased from INSIDE at |
|
22
|
|
|
|
|
|
|
* http://www.insidesecure.com/ |
|
23
|
|
|
|
|
|
|
* |
|
24
|
|
|
|
|
|
|
* This program is distributed in WITHOUT ANY WARRANTY; without even the |
|
25
|
|
|
|
|
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
26
|
|
|
|
|
|
|
* See the GNU General Public License for more details. |
|
27
|
|
|
|
|
|
|
* |
|
28
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License |
|
29
|
|
|
|
|
|
|
* along with this program; if not, write to the Free Software |
|
30
|
|
|
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
31
|
|
|
|
|
|
|
* http://www.gnu.org/copyleft/gpl.html |
|
32
|
|
|
|
|
|
|
*/ |
|
33
|
|
|
|
|
|
|
/******************************************************************************/ |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
#include "matrixsslImpl.h" |
|
36
|
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
/******************************************************************************/ |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# define LUCKY13 |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
#define SSL_MAX_IGNORED_MESSAGE_COUNT 1024 |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
static int32 parseSSLHandshake(ssl_t *ssl, char *inbuf, uint32 len); |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
#ifdef USE_CERT_CHAIN_PARSING |
|
46
|
|
|
|
|
|
|
static int32 parseSingleCert(ssl_t *ssl, unsigned char *c, unsigned char *end, |
|
47
|
|
|
|
|
|
|
int32 certLen); |
|
48
|
|
|
|
|
|
|
#endif /* USE_CERT_CHAIN_PARSING */ |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
#ifdef LUCKY13 |
|
51
|
|
|
|
|
|
|
static int32 addCompressCount(ssl_t *ssl, int32 padLen); |
|
52
|
|
|
|
|
|
|
#endif |
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
#ifdef USE_ZLIB_COMPRESSION |
|
55
|
|
|
|
|
|
|
/* Does not need to be a large value because we're only inflating the 16 |
|
56
|
|
|
|
|
|
|
byte FINISHED message. In fact, compression will grow 16 bytes but |
|
57
|
|
|
|
|
|
|
this is a good reminder that FUTURE support will need to account for |
|
58
|
|
|
|
|
|
|
likely data growth here */ |
|
59
|
|
|
|
|
|
|
# define MATRIX_INFLATE_FINISHED_OH 128 |
|
60
|
|
|
|
|
|
|
#endif |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
/******************************************************************************/ |
|
63
|
|
|
|
|
|
|
/* |
|
64
|
|
|
|
|
|
|
Parse incoming data per http://wp.netscape.com/eng/ssl3 |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
Input parameters to decode: |
|
67
|
|
|
|
|
|
|
. buf points to the start of data to decode |
|
68
|
|
|
|
|
|
|
. len points to the length in bytes of data to decode |
|
69
|
|
|
|
|
|
|
. size is the number of allocated bytes that follow buf |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
Meaningful parameters after the call to decode: |
|
74
|
|
|
|
|
|
|
MATRIXSSL_SUCCESS |
|
75
|
|
|
|
|
|
|
. buf will point to the first undecoded byte (could==inbuf or inbuf+inlen) |
|
76
|
|
|
|
|
|
|
. remaining will indicate how many more bytes of undecoded data remain |
|
77
|
|
|
|
|
|
|
* call again if more to decode or return if handshake is complete |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
SSL_PARTIAL |
|
80
|
|
|
|
|
|
|
. buf will not have moved (because partials start parse over) |
|
81
|
|
|
|
|
|
|
. reqLen will indicate how many bytes the entire full record is |
|
82
|
|
|
|
|
|
|
* get more data from peer and call again |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
SSL_FULL (implies decode completed fully but couldn't fit response) |
|
85
|
|
|
|
|
|
|
. buf will not have moved (it is reset to the front of final record) |
|
86
|
|
|
|
|
|
|
. len will be 0 to indicate no remaining unprocessed data |
|
87
|
|
|
|
|
|
|
. reqLen will inform how large buf should be grown before re-invoking |
|
88
|
|
|
|
|
|
|
* realloc the buf to the reqLen size and call again |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
SSL_SEND_RESPONSE |
|
91
|
|
|
|
|
|
|
. buf will point to the encoded handshake data to send |
|
92
|
|
|
|
|
|
|
. len will be length of data to send (from start offset) |
|
93
|
|
|
|
|
|
|
* pass the buf to the transport layer for sending to peer |
|
94
|
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
SSL_ALERT |
|
96
|
|
|
|
|
|
|
. buf will point to start of received alert (2 bytes alert level and desc) |
|
97
|
|
|
|
|
|
|
. len will be length of alert data (should be 2) |
|
98
|
|
|
|
|
|
|
. alertLevel will be 1 (warning) or 2 (fatal) |
|
99
|
|
|
|
|
|
|
. alertDesc will be SSL specified alert code |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
MATRIXSSL_ERROR (unrecoverable failure) |
|
102
|
|
|
|
|
|
|
. decodeErr is internal parse err code |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
SSL_PROCESS_DATA (ONLY CASE WITH DECRYPTED DATA AND POSSIBLE UNENCRYPTED) |
|
105
|
|
|
|
|
|
|
. unencrypted user data ready for processing is at prevBuf |
|
106
|
|
|
|
|
|
|
. buf points to start of any remaining unencrypted data |
|
107
|
|
|
|
|
|
|
. remaining is length of remaining encrypted data yet to decode |
|
108
|
|
|
|
|
|
|
. len is length of unencrypted data ready for user processing |
|
109
|
|
|
|
|
|
|
* pass unencypted data to application level |
|
110
|
|
|
|
|
|
|
* call decode again if more encrypted data remaining |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
*/ |
|
113
|
17143
|
|
|
|
|
|
int32 matrixSslDecode(ssl_t *ssl, unsigned char **buf, uint32 *len, |
|
114
|
|
|
|
|
|
|
uint32 size, uint32 *remaining, uint32 *requiredLen, |
|
115
|
|
|
|
|
|
|
int32 *error, unsigned char *alertLevel, |
|
116
|
|
|
|
|
|
|
unsigned char *alertDescription) |
|
117
|
|
|
|
|
|
|
{ |
|
118
|
|
|
|
|
|
|
unsigned char *c, *p, *end, *pend, *ctStart, *origbuf; |
|
119
|
|
|
|
|
|
|
unsigned char *mac; |
|
120
|
|
|
|
|
|
|
unsigned char macError; |
|
121
|
|
|
|
|
|
|
int32 rc; |
|
122
|
|
|
|
|
|
|
unsigned char padLen; |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# ifdef USE_CLIENT_SIDE_SSL |
|
125
|
|
|
|
|
|
|
sslSessOpts_t options; |
|
126
|
|
|
|
|
|
|
# endif |
|
127
|
|
|
|
|
|
|
psBuf_t tmpout; |
|
128
|
|
|
|
|
|
|
#ifdef USE_CERT_CHAIN_PARSING |
|
129
|
|
|
|
|
|
|
int32 certlen, i, nextCertLen; |
|
130
|
|
|
|
|
|
|
#endif /* USE_CERT_CHAIN_PARSING */ |
|
131
|
|
|
|
|
|
|
#ifdef USE_ZLIB_COMPRESSION |
|
132
|
|
|
|
|
|
|
int32 preInflateLen, postInflateLen, currLen; |
|
133
|
|
|
|
|
|
|
int zret; |
|
134
|
|
|
|
|
|
|
#endif |
|
135
|
|
|
|
|
|
|
/* |
|
136
|
|
|
|
|
|
|
If we've had a protocol error, don't allow further use of the session |
|
137
|
|
|
|
|
|
|
*/ |
|
138
|
17143
|
|
|
|
|
|
*error = PS_SUCCESS; |
|
139
|
17143
|
50
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_ERROR || ssl->flags & SSL_FLAGS_CLOSED) |
|
|
|
50
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
{ |
|
141
|
|
|
|
|
|
|
psTraceInfo("Can't use matrixSslDecode on closed/error-flagged sess\n"); |
|
142
|
0
|
|
|
|
|
|
*error = PS_PROTOCOL_FAIL; |
|
143
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
144
|
|
|
|
|
|
|
} |
|
145
|
|
|
|
|
|
|
|
|
146
|
17143
|
|
|
|
|
|
origbuf = *buf; /* Save the original buffer location */ |
|
147
|
|
|
|
|
|
|
|
|
148
|
17143
|
|
|
|
|
|
p = pend = mac = ctStart = NULL; |
|
149
|
17143
|
|
|
|
|
|
padLen = 0; |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING |
|
152
|
|
|
|
|
|
|
if (ssl->hwflags & SSL_HWFLAGS_PENDING_PKA_W || |
|
153
|
|
|
|
|
|
|
ssl->hwflags & SSL_HWFLAGS_PENDING_FLIGHT_W) |
|
154
|
|
|
|
|
|
|
{ |
|
155
|
|
|
|
|
|
|
goto encodeResponse; |
|
156
|
|
|
|
|
|
|
} |
|
157
|
|
|
|
|
|
|
# endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */ |
|
158
|
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
/* |
|
160
|
|
|
|
|
|
|
This flag is set if the previous call to this routine returned an SSL_FULL |
|
161
|
|
|
|
|
|
|
error from encodeResponse, indicating that there is data to be encoded, |
|
162
|
|
|
|
|
|
|
but the out buffer was not big enough to handle it. If we fall in this |
|
163
|
|
|
|
|
|
|
case, the user has increased the out buffer size and is re-calling this |
|
164
|
|
|
|
|
|
|
routine |
|
165
|
|
|
|
|
|
|
*/ |
|
166
|
17143
|
100
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_NEED_ENCODE) |
|
167
|
|
|
|
|
|
|
{ |
|
168
|
4
|
|
|
|
|
|
ssl->flags &= ~SSL_FLAGS_NEED_ENCODE; |
|
169
|
4
|
|
|
|
|
|
goto encodeResponse; |
|
170
|
|
|
|
|
|
|
} |
|
171
|
17139
|
|
|
|
|
|
*requiredLen = 0; |
|
172
|
17139
|
|
|
|
|
|
c = *buf; /* c is record parse pointer */ |
|
173
|
17139
|
|
|
|
|
|
end = *buf + *len; |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
/* |
|
176
|
|
|
|
|
|
|
Processing the SSL Record header. |
|
177
|
|
|
|
|
|
|
If the high bit of the first byte is set and this is the first |
|
178
|
|
|
|
|
|
|
message we've seen, we parse the request as an SSLv2 request |
|
179
|
|
|
|
|
|
|
@see http://wp.netscape.com/eng/security/SSL_2.html |
|
180
|
|
|
|
|
|
|
SSLv2 also supports a 3 byte header when padding is used, but this should |
|
181
|
|
|
|
|
|
|
not be required for the initial plaintext message, so we don't support it. |
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
@security SSLV2 ClientHello is deprecated and no longer supported. |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
v2 Header: |
|
186
|
|
|
|
|
|
|
2 bytes length (ignore high bit) |
|
187
|
|
|
|
|
|
|
v3 Header: |
|
188
|
|
|
|
|
|
|
1 byte type |
|
189
|
|
|
|
|
|
|
1 byte major version |
|
190
|
|
|
|
|
|
|
1 byte minor version |
|
191
|
|
|
|
|
|
|
2 bytes length |
|
192
|
|
|
|
|
|
|
*/ |
|
193
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
194
|
|
|
|
|
|
|
decodeMore: |
|
195
|
|
|
|
|
|
|
#endif |
|
196
|
17139
|
50
|
|
|
|
|
if (end - c == 0) |
|
197
|
|
|
|
|
|
|
{ |
|
198
|
|
|
|
|
|
|
/* |
|
199
|
|
|
|
|
|
|
This case could happen if change cipher spec was last |
|
200
|
|
|
|
|
|
|
message in the buffer or if there is a zero-length record |
|
201
|
|
|
|
|
|
|
at the end of a multi-record application data buffer. |
|
202
|
|
|
|
|
|
|
*/ |
|
203
|
0
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
204
|
|
|
|
|
|
|
} |
|
205
|
|
|
|
|
|
|
/* Even for SSLv2, we want at least 5 bytes in the record to continue */ |
|
206
|
17139
|
50
|
|
|
|
|
if (end - c < SSL3_HEADER_LEN) |
|
207
|
|
|
|
|
|
|
{ |
|
208
|
0
|
|
|
|
|
|
*requiredLen = SSL3_HEADER_LEN; |
|
209
|
0
|
|
|
|
|
|
return SSL_PARTIAL; |
|
210
|
|
|
|
|
|
|
} |
|
211
|
|
|
|
|
|
|
#ifdef USE_CERT_CHAIN_PARSING |
|
212
|
|
|
|
|
|
|
/* |
|
213
|
|
|
|
|
|
|
If we're in process of parsing a partial record, then skip the |
|
214
|
|
|
|
|
|
|
usual record header parse. Currently we're only supporting |
|
215
|
|
|
|
|
|
|
partial parsing for the certificate messages since they are the |
|
216
|
|
|
|
|
|
|
largest in size. |
|
217
|
|
|
|
|
|
|
*/ |
|
218
|
|
|
|
|
|
|
if (ssl->rec.partial != 0x0) |
|
219
|
|
|
|
|
|
|
{ |
|
220
|
|
|
|
|
|
|
psAssert(ssl->rec.type == SSL_RECORD_TYPE_HANDSHAKE); |
|
221
|
|
|
|
|
|
|
psAssert(ssl->hsState == SSL_HS_CERTIFICATE); |
|
222
|
|
|
|
|
|
|
/* |
|
223
|
|
|
|
|
|
|
Get this next record length based on the certificate size, |
|
224
|
|
|
|
|
|
|
which will always be the first three bytes of a partial here |
|
225
|
|
|
|
|
|
|
*/ |
|
226
|
|
|
|
|
|
|
ssl->rec.len = c[0] << 16; |
|
227
|
|
|
|
|
|
|
ssl->rec.len |= c[1] << 8; |
|
228
|
|
|
|
|
|
|
ssl->rec.len |= c[2]; |
|
229
|
|
|
|
|
|
|
ssl->rec.len += 3; |
|
230
|
|
|
|
|
|
|
goto SKIP_RECORD_PARSE; |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
#endif /* USE_CERT_CHAIN_PARSING */ |
|
233
|
|
|
|
|
|
|
|
|
234
|
17139
|
100
|
|
|
|
|
if (ssl->majVer != 0 || (*c & 0x80) == 0) |
|
|
|
50
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
{ |
|
236
|
17139
|
50
|
|
|
|
|
if (end - c < ssl->recordHeadLen) |
|
237
|
|
|
|
|
|
|
{ |
|
238
|
0
|
|
|
|
|
|
*requiredLen = ssl->recordHeadLen; |
|
239
|
0
|
|
|
|
|
|
return SSL_PARTIAL; |
|
240
|
|
|
|
|
|
|
} |
|
241
|
17139
|
|
|
|
|
|
ssl->rec.type = *c; c++; |
|
242
|
17139
|
|
|
|
|
|
ssl->rec.majVer = *c; c++; |
|
243
|
17139
|
|
|
|
|
|
ssl->rec.minVer = *c; c++; |
|
244
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
245
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
246
|
|
|
|
|
|
|
{ |
|
247
|
|
|
|
|
|
|
if (ssl->rec.majVer == DTLS_MAJ_VER && |
|
248
|
|
|
|
|
|
|
ssl->rec.minVer >= DTLS_1_2_MIN_VER) |
|
249
|
|
|
|
|
|
|
{ |
|
250
|
|
|
|
|
|
|
ssl->rec.epoch[0] = *c++; |
|
251
|
|
|
|
|
|
|
ssl->rec.epoch[1] = *c++; |
|
252
|
|
|
|
|
|
|
ssl->rec.rsn[0] = *c++; |
|
253
|
|
|
|
|
|
|
ssl->rec.rsn[1] = *c++; |
|
254
|
|
|
|
|
|
|
ssl->rec.rsn[2] = *c++; |
|
255
|
|
|
|
|
|
|
ssl->rec.rsn[3] = *c++; |
|
256
|
|
|
|
|
|
|
ssl->rec.rsn[4] = *c++; |
|
257
|
|
|
|
|
|
|
ssl->rec.rsn[5] = *c++; |
|
258
|
|
|
|
|
|
|
} |
|
259
|
|
|
|
|
|
|
else |
|
260
|
|
|
|
|
|
|
{ |
|
261
|
|
|
|
|
|
|
psTraceIntDtls("Expecting DTLS record version. Got %d\n", |
|
262
|
|
|
|
|
|
|
ssl->rec.majVer); |
|
263
|
|
|
|
|
|
|
*error = PS_PROTOCOL_FAIL; |
|
264
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
265
|
|
|
|
|
|
|
} |
|
266
|
|
|
|
|
|
|
} |
|
267
|
|
|
|
|
|
|
else /* Note: The else branch (not DTLS) is below, |
|
268
|
|
|
|
|
|
|
in code outside USE_DTLS */ |
|
269
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
270
|
|
|
|
|
|
|
#ifndef USE_SSL_PROTOCOL_VERSIONS_OTHER_THAN_3 |
|
271
|
|
|
|
|
|
|
{ |
|
272
|
|
|
|
|
|
|
/* RFC 5246 Suggests to accept all RSA minor versions, |
|
273
|
|
|
|
|
|
|
but only major version 0x03 (SSLv3, TLS 1.0, |
|
274
|
|
|
|
|
|
|
TLS 1.1, TLS 1.2, TLS 1.3 etc) */ |
|
275
|
17139
|
50
|
|
|
|
|
if (ssl->rec.majVer != 0x03) |
|
276
|
|
|
|
|
|
|
{ |
|
277
|
|
|
|
|
|
|
/* Consider invalid major version protocol |
|
278
|
|
|
|
|
|
|
version error. */ |
|
279
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_PROTOCOL_VERSION; |
|
280
|
|
|
|
|
|
|
psTraceInfo( |
|
281
|
|
|
|
|
|
|
"Won't support client's SSL major version\n"); |
|
282
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
283
|
|
|
|
|
|
|
} |
|
284
|
|
|
|
|
|
|
} |
|
285
|
|
|
|
|
|
|
#else |
|
286
|
|
|
|
|
|
|
{ } /* No check for rec.MajVer. */ |
|
287
|
|
|
|
|
|
|
#endif /* USE_SSL_PROTOCOL_VERSIONS_OTHER_THAN_3 */ |
|
288
|
|
|
|
|
|
|
|
|
289
|
17139
|
|
|
|
|
|
ssl->rec.len = *c << 8; c++; |
|
290
|
17139
|
|
|
|
|
|
ssl->rec.len += *c; c++; |
|
291
|
|
|
|
|
|
|
} |
|
292
|
|
|
|
|
|
|
else |
|
293
|
|
|
|
|
|
|
{ |
|
294
|
|
|
|
|
|
|
/* OpenSSL 0.9.8 will send a SSLv2 CLIENT_HELLO. Use the -no_ssl2 |
|
295
|
|
|
|
|
|
|
option when running a 0.9.8 client to prevent this */ |
|
296
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
297
|
|
|
|
|
|
|
psTraceInfo("SSLv2 records not supported\n"); |
|
298
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
299
|
|
|
|
|
|
|
} |
|
300
|
|
|
|
|
|
|
/* |
|
301
|
|
|
|
|
|
|
Validate the various record headers. The type must be valid, |
|
302
|
|
|
|
|
|
|
the major and minor versions must match the negotiated versions (if we're |
|
303
|
|
|
|
|
|
|
past ClientHello) and the length must be < 16K and > 0 |
|
304
|
|
|
|
|
|
|
*/ |
|
305
|
17139
|
50
|
|
|
|
|
switch (ssl->rec.type) |
|
306
|
|
|
|
|
|
|
{ |
|
307
|
|
|
|
|
|
|
case SSL_RECORD_TYPE_CHANGE_CIPHER_SPEC: |
|
308
|
|
|
|
|
|
|
case SSL_RECORD_TYPE_ALERT: |
|
309
|
|
|
|
|
|
|
case SSL_RECORD_TYPE_HANDSHAKE: |
|
310
|
|
|
|
|
|
|
case SSL_RECORD_TYPE_APPLICATION_DATA: |
|
311
|
17139
|
|
|
|
|
|
break; |
|
312
|
|
|
|
|
|
|
/* Any other case is unrecognized */ |
|
313
|
|
|
|
|
|
|
default: |
|
314
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
315
|
|
|
|
|
|
|
psTraceIntInfo("Record header type not valid: %d\n", ssl->rec.type); |
|
316
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
317
|
|
|
|
|
|
|
} |
|
318
|
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
/* |
|
320
|
|
|
|
|
|
|
Verify the record version numbers unless this is the first record we're |
|
321
|
|
|
|
|
|
|
reading. |
|
322
|
|
|
|
|
|
|
*/ |
|
323
|
17139
|
100
|
|
|
|
|
if (ssl->hsState != SSL_HS_SERVER_HELLO && |
|
|
|
100
|
|
|
|
|
|
|
324
|
15989
|
|
|
|
|
|
ssl->hsState != SSL_HS_CLIENT_HELLO) |
|
325
|
|
|
|
|
|
|
{ |
|
326
|
14847
|
50
|
|
|
|
|
if (ssl->rec.majVer != ssl->majVer || ssl->rec.minVer != ssl->minVer) |
|
|
|
50
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
{ |
|
328
|
|
|
|
|
|
|
#ifdef SSL_REHANDSHAKES_ENABLED |
|
329
|
|
|
|
|
|
|
/* If in DONE state and this version doesn't match the previously |
|
330
|
|
|
|
|
|
|
negotiated one that can be OK because a CLIENT_HELLO for a |
|
331
|
|
|
|
|
|
|
rehandshake might be acting like a first time send and using |
|
332
|
|
|
|
|
|
|
a lower version to get to the parsing phase. Unsupported |
|
333
|
|
|
|
|
|
|
versions will be weeded out at CLIENT_HELLO parse time */ |
|
334
|
0
|
0
|
|
|
|
|
if (ssl->hsState != SSL_HS_DONE || |
|
|
|
0
|
|
|
|
|
|
|
335
|
0
|
|
|
|
|
|
ssl->rec.type != SSL_RECORD_TYPE_HANDSHAKE) |
|
336
|
|
|
|
|
|
|
{ |
|
337
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
338
|
|
|
|
|
|
|
psTraceInfo("Record header version not valid\n"); |
|
339
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
340
|
|
|
|
|
|
|
} |
|
341
|
|
|
|
|
|
|
#else |
|
342
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
343
|
|
|
|
|
|
|
psTraceInfo("Record header version not valid\n"); |
|
344
|
|
|
|
|
|
|
goto encodeResponse; |
|
345
|
|
|
|
|
|
|
#endif |
|
346
|
|
|
|
|
|
|
} |
|
347
|
|
|
|
|
|
|
} |
|
348
|
|
|
|
|
|
|
/* |
|
349
|
|
|
|
|
|
|
Verify max and min record lengths |
|
350
|
|
|
|
|
|
|
*/ |
|
351
|
17139
|
50
|
|
|
|
|
if (ssl->rec.len > SSL_MAX_RECORD_LEN || ssl->rec.len == 0) |
|
|
|
50
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
{ |
|
353
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
354
|
|
|
|
|
|
|
psTraceIntInfo("Record header length not valid: %d\n", ssl->rec.len); |
|
355
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
356
|
|
|
|
|
|
|
} |
|
357
|
|
|
|
|
|
|
/* |
|
358
|
|
|
|
|
|
|
This implementation requires the entire SSL record to be in the 'in' buffer |
|
359
|
|
|
|
|
|
|
before we parse it. This is because we need to MAC the entire record before |
|
360
|
|
|
|
|
|
|
allowing it to be used by the caller. |
|
361
|
|
|
|
|
|
|
*/ |
|
362
|
|
|
|
|
|
|
#ifdef USE_CERT_CHAIN_PARSING |
|
363
|
|
|
|
|
|
|
SKIP_RECORD_PARSE: |
|
364
|
|
|
|
|
|
|
if ((end - c < ssl->rec.len) || ssl->rec.partial) |
|
365
|
|
|
|
|
|
|
{ |
|
366
|
|
|
|
|
|
|
/* |
|
367
|
|
|
|
|
|
|
This feature will only work if the CERTIFICATE message is sent in a |
|
368
|
|
|
|
|
|
|
different record from the SERVER_HELLO message. |
|
369
|
|
|
|
|
|
|
*/ |
|
370
|
|
|
|
|
|
|
if (ssl->hsState != SSL_HS_CERTIFICATE) |
|
371
|
|
|
|
|
|
|
{ |
|
372
|
|
|
|
|
|
|
ssl->rec.partial = 0x0; |
|
373
|
|
|
|
|
|
|
*requiredLen = ssl->rec.len + ssl->recordHeadLen; |
|
374
|
|
|
|
|
|
|
return SSL_PARTIAL; |
|
375
|
|
|
|
|
|
|
} |
|
376
|
|
|
|
|
|
|
/* |
|
377
|
|
|
|
|
|
|
Not supporting cert stream parsing for re-handshake. This is |
|
378
|
|
|
|
|
|
|
important because the block cipher assumes a single pass is a record |
|
379
|
|
|
|
|
|
|
and will use explicit IV each pass |
|
380
|
|
|
|
|
|
|
*/ |
|
381
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_READ_SECURE) |
|
382
|
|
|
|
|
|
|
{ |
|
383
|
|
|
|
|
|
|
ssl->rec.partial = 0x0; |
|
384
|
|
|
|
|
|
|
*requiredLen = ssl->rec.len + ssl->recordHeadLen; |
|
385
|
|
|
|
|
|
|
return SSL_PARTIAL; |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
/* |
|
388
|
|
|
|
|
|
|
Manipulate the rec.len for partial handling |
|
389
|
|
|
|
|
|
|
*/ |
|
390
|
|
|
|
|
|
|
i = 0; |
|
391
|
|
|
|
|
|
|
if (ssl->rec.partial == 0x0) |
|
392
|
|
|
|
|
|
|
{ |
|
393
|
|
|
|
|
|
|
/* |
|
394
|
|
|
|
|
|
|
Initialization for partial parse counters |
|
395
|
|
|
|
|
|
|
*/ |
|
396
|
|
|
|
|
|
|
ssl->rec.hsBytesHashed = 0; |
|
397
|
|
|
|
|
|
|
ssl->rec.hsBytesParsed = 0; |
|
398
|
|
|
|
|
|
|
ssl->rec.partial = 0x1; |
|
399
|
|
|
|
|
|
|
ssl->rec.trueLen = ssl->rec.len + ssl->recordHeadLen; |
|
400
|
|
|
|
|
|
|
ssl->rec.len = 0; |
|
401
|
|
|
|
|
|
|
/* |
|
402
|
|
|
|
|
|
|
Best to identify and isolate full certificate boundaries |
|
403
|
|
|
|
|
|
|
ASAP to keep parsing logic as high level as possible. |
|
404
|
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
Current state of record buffer: pointer at start of HS record |
|
406
|
|
|
|
|
|
|
which begins with 4 bytes of hsType(1) and hsLen(3). After |
|
407
|
|
|
|
|
|
|
the header are 3 bytes of certchainlen and 3 bytes of first |
|
408
|
|
|
|
|
|
|
cert len. Make sure we have at least one full cert here before |
|
409
|
|
|
|
|
|
|
allowing the partial parse. |
|
410
|
|
|
|
|
|
|
*/ |
|
411
|
|
|
|
|
|
|
if (end - c < (ssl->hshakeHeadLen + 6)) /* 3*2 cert chain len */ |
|
412
|
|
|
|
|
|
|
{ |
|
413
|
|
|
|
|
|
|
ssl->rec.partial = 0x0; /* Unusable. Reset */ |
|
414
|
|
|
|
|
|
|
*requiredLen = ssl->hshakeHeadLen + 6; |
|
415
|
|
|
|
|
|
|
return SSL_PARTIAL; |
|
416
|
|
|
|
|
|
|
} |
|
417
|
|
|
|
|
|
|
ssl->rec.len += (ssl->hshakeHeadLen + 3); |
|
418
|
|
|
|
|
|
|
i = ssl->hshakeHeadLen; |
|
419
|
|
|
|
|
|
|
certlen = c[i] << 16; i++; |
|
420
|
|
|
|
|
|
|
certlen |= c[i] << 8; i++; |
|
421
|
|
|
|
|
|
|
certlen |= c[i]; i++; |
|
422
|
|
|
|
|
|
|
/* |
|
423
|
|
|
|
|
|
|
This feature only works if the CERTIFICATE message is the only |
|
424
|
|
|
|
|
|
|
message in the record. Test this by seeing that trueLen doesn't |
|
425
|
|
|
|
|
|
|
claim there is more to follow |
|
426
|
|
|
|
|
|
|
*/ |
|
427
|
|
|
|
|
|
|
if (ssl->rec.trueLen != (certlen + 3 + ssl->hshakeHeadLen + |
|
428
|
|
|
|
|
|
|
ssl->recordHeadLen)) |
|
429
|
|
|
|
|
|
|
{ |
|
430
|
|
|
|
|
|
|
ssl->rec.partial = 0x0; /* Unusable. Reset */ |
|
431
|
|
|
|
|
|
|
*requiredLen = ssl->rec.trueLen; |
|
432
|
|
|
|
|
|
|
return SSL_PARTIAL; |
|
433
|
|
|
|
|
|
|
} |
|
434
|
|
|
|
|
|
|
/* First cert length */ |
|
435
|
|
|
|
|
|
|
ssl->rec.len += 3; |
|
436
|
|
|
|
|
|
|
certlen = c[i] << 16; i++; |
|
437
|
|
|
|
|
|
|
certlen |= c[i] << 8; i++; |
|
438
|
|
|
|
|
|
|
certlen |= c[i]; |
|
439
|
|
|
|
|
|
|
ssl->rec.len += certlen; |
|
440
|
|
|
|
|
|
|
} |
|
441
|
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
/* One complete cert? */ |
|
443
|
|
|
|
|
|
|
if (end - c < ssl->rec.len) |
|
444
|
|
|
|
|
|
|
{ |
|
445
|
|
|
|
|
|
|
/* |
|
446
|
|
|
|
|
|
|
If there isn't a full cert in the first partial, we reset and |
|
447
|
|
|
|
|
|
|
handle as the standard SSL_PARTIAL case. |
|
448
|
|
|
|
|
|
|
*/ |
|
449
|
|
|
|
|
|
|
if (ssl->rec.hsBytesParsed == 0) |
|
450
|
|
|
|
|
|
|
{ |
|
451
|
|
|
|
|
|
|
ssl->rec.partial = 0x0; /* Unusable. Reset */ |
|
452
|
|
|
|
|
|
|
*requiredLen = ssl->rec.len + ssl->recordHeadLen; |
|
453
|
|
|
|
|
|
|
} |
|
454
|
|
|
|
|
|
|
else |
|
455
|
|
|
|
|
|
|
{ |
|
456
|
|
|
|
|
|
|
/* Record header has already been parsed */ |
|
457
|
|
|
|
|
|
|
*requiredLen = ssl->rec.len; |
|
458
|
|
|
|
|
|
|
} |
|
459
|
|
|
|
|
|
|
return SSL_PARTIAL; /* Standard partial case */ |
|
460
|
|
|
|
|
|
|
} |
|
461
|
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
/* More than one complete cert? */ |
|
463
|
|
|
|
|
|
|
while (end - c > ssl->rec.len) |
|
464
|
|
|
|
|
|
|
{ |
|
465
|
|
|
|
|
|
|
if (ssl->rec.len + ssl->rec.hsBytesParsed == ssl->rec.trueLen) |
|
466
|
|
|
|
|
|
|
{ |
|
467
|
|
|
|
|
|
|
/* |
|
468
|
|
|
|
|
|
|
Don't try to read another cert if the total of already parsed |
|
469
|
|
|
|
|
|
|
record and the length of the current record match the 'trueLen'. |
|
470
|
|
|
|
|
|
|
If they are equal, we know we are on the final cert and don't |
|
471
|
|
|
|
|
|
|
need to look for more |
|
472
|
|
|
|
|
|
|
*/ |
|
473
|
|
|
|
|
|
|
break; |
|
474
|
|
|
|
|
|
|
} |
|
475
|
|
|
|
|
|
|
psAssert(ssl->rec.len + ssl->rec.hsBytesParsed <= ssl->rec.trueLen); |
|
476
|
|
|
|
|
|
|
nextCertLen = c[ssl->rec.len] << 16; |
|
477
|
|
|
|
|
|
|
nextCertLen |= c[ssl->rec.len + 1] << 8; |
|
478
|
|
|
|
|
|
|
nextCertLen |= c[ssl->rec.len + 2]; |
|
479
|
|
|
|
|
|
|
if (end - c > (ssl->rec.len + nextCertLen + 3)) |
|
480
|
|
|
|
|
|
|
{ |
|
481
|
|
|
|
|
|
|
ssl->rec.len += (nextCertLen + 3); |
|
482
|
|
|
|
|
|
|
} |
|
483
|
|
|
|
|
|
|
else |
|
484
|
|
|
|
|
|
|
{ |
|
485
|
|
|
|
|
|
|
break; |
|
486
|
|
|
|
|
|
|
} |
|
487
|
|
|
|
|
|
|
} |
|
488
|
|
|
|
|
|
|
} |
|
489
|
|
|
|
|
|
|
#else |
|
490
|
17139
|
100
|
|
|
|
|
if (end - c < ssl->rec.len) |
|
491
|
|
|
|
|
|
|
{ |
|
492
|
|
|
|
|
|
|
# ifdef USE_DTLS |
|
493
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
494
|
|
|
|
|
|
|
{ |
|
495
|
|
|
|
|
|
|
psTraceInfo("DTLS error: Received PARTIAL record from peer.\n"); |
|
496
|
|
|
|
|
|
|
psTraceInfo("This indicates a PMTU mismatch\n"); |
|
497
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
498
|
|
|
|
|
|
|
goto encodeResponse; |
|
499
|
|
|
|
|
|
|
} |
|
500
|
|
|
|
|
|
|
# endif /* USE_DTLS */ |
|
501
|
2068
|
|
|
|
|
|
*requiredLen = ssl->rec.len + ssl->recordHeadLen; |
|
502
|
2068
|
|
|
|
|
|
return SSL_PARTIAL; |
|
503
|
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
} |
|
505
|
|
|
|
|
|
|
#endif |
|
506
|
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
508
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
509
|
|
|
|
|
|
|
{ |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
/* Epoch and RSN validation. Silently ignore most mismatches (SUCCESS) */ |
|
512
|
|
|
|
|
|
|
rc = dtlsCompareEpoch(ssl->rec.epoch, ssl->expectedEpoch); |
|
513
|
|
|
|
|
|
|
/* These cases have become pretty complex due to a code change in which |
|
514
|
|
|
|
|
|
|
the epoch is always incremented when CCS is sent. We used to |
|
515
|
|
|
|
|
|
|
reset the FINISHED epoch back to +1 of the current epoch when |
|
516
|
|
|
|
|
|
|
resending the FINISHED flight but a customer had a problem with this |
|
517
|
|
|
|
|
|
|
because they thought every single message must be unique for epoch |
|
518
|
|
|
|
|
|
|
and sequence number. They were probably correct but now it's a |
|
519
|
|
|
|
|
|
|
real mess trying to keep the expectedEpoch up-to-date when we can't |
|
520
|
|
|
|
|
|
|
possibly know how many epoch increments the peer has made before we |
|
521
|
|
|
|
|
|
|
receive a FINISHED message or an APPLICATION DATA record */ |
|
522
|
|
|
|
|
|
|
if (rc == 1 && ssl->rec.type == SSL_RECORD_TYPE_HANDSHAKE && |
|
523
|
|
|
|
|
|
|
ssl->hsState == SSL_HS_FINISHED) |
|
524
|
|
|
|
|
|
|
{ |
|
525
|
|
|
|
|
|
|
/* Special handlers for these CCS/Finished cases because epoch |
|
526
|
|
|
|
|
|
|
could be larger for a good reason */ |
|
527
|
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
/* This is the case where we are getting a finished without having |
|
529
|
|
|
|
|
|
|
seen a CCS. Preumably they will be trying again since this is |
|
530
|
|
|
|
|
|
|
an indication that they are aware they are the senders */ |
|
531
|
|
|
|
|
|
|
if (ssl->parsedCCS == 0) |
|
532
|
|
|
|
|
|
|
{ |
|
533
|
|
|
|
|
|
|
c += ssl->rec.len; |
|
534
|
|
|
|
|
|
|
*buf = c; |
|
535
|
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
536
|
|
|
|
|
|
|
} |
|
537
|
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
/* This is the case where we didn't receive a combo CCS/FINISHED |
|
539
|
|
|
|
|
|
|
flight from the peer and they have resent with a larger epoch |
|
540
|
|
|
|
|
|
|
for the resent FINISHED message (so as not to send a epoch/seqNo |
|
541
|
|
|
|
|
|
|
duplicate on this resend). Make the expected epoch the new one |
|
542
|
|
|
|
|
|
|
to reset the test for any future rehandshakes */ |
|
543
|
|
|
|
|
|
|
ssl->expectedEpoch[0] = ssl->rec.epoch[0]; |
|
544
|
|
|
|
|
|
|
ssl->expectedEpoch[1] = ssl->rec.epoch[1]; |
|
545
|
|
|
|
|
|
|
} |
|
546
|
|
|
|
|
|
|
else if (rc != 0) |
|
547
|
|
|
|
|
|
|
{ |
|
548
|
|
|
|
|
|
|
psTraceIntDtls("Epoch mismatch %d ", ssl->rec.epoch[1]); |
|
549
|
|
|
|
|
|
|
psTraceIntDtls("on a record type of %d\n", ssl->rec.type); |
|
550
|
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
/* Another corner case where the peer has sent repeat FINISHED |
|
552
|
|
|
|
|
|
|
messages when we are in the state where we are finished. |
|
553
|
|
|
|
|
|
|
Need to keep the expectedEpoch up-to-date then because when |
|
554
|
|
|
|
|
|
|
the peer finally gets around to sending application data it |
|
555
|
|
|
|
|
|
|
will be sending it on the last epoch it sent for the final |
|
556
|
|
|
|
|
|
|
FINISHED. */ |
|
557
|
|
|
|
|
|
|
if (rc == 1 && ssl->rec.type == SSL_RECORD_TYPE_HANDSHAKE && |
|
558
|
|
|
|
|
|
|
ssl->hsState == SSL_HS_DONE) |
|
559
|
|
|
|
|
|
|
{ |
|
560
|
|
|
|
|
|
|
ssl->expectedEpoch[0] = ssl->rec.epoch[0]; |
|
561
|
|
|
|
|
|
|
ssl->expectedEpoch[1] = ssl->rec.epoch[1]; |
|
562
|
|
|
|
|
|
|
} |
|
563
|
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
/* Yet another corner case where we are receiving application data |
|
565
|
|
|
|
|
|
|
that has an epoch larger than we were expecting. This could |
|
566
|
|
|
|
|
|
|
happen if the peer has been sending "duplicate" FINISHED |
|
567
|
|
|
|
|
|
|
messages in which we have already parsed an earlier one and we |
|
568
|
|
|
|
|
|
|
are in the done state. If we didn't receive those duplicate |
|
569
|
|
|
|
|
|
|
FINISHED messages and are now getting an APPLICATION record, |
|
570
|
|
|
|
|
|
|
let's just try to decrypt it and get this communication going */ |
|
571
|
|
|
|
|
|
|
if (rc == 1 && ssl->rec.type == SSL_RECORD_TYPE_APPLICATION_DATA && |
|
572
|
|
|
|
|
|
|
ssl->hsState == SSL_HS_DONE) |
|
573
|
|
|
|
|
|
|
{ |
|
574
|
|
|
|
|
|
|
ssl->expectedEpoch[0] = ssl->rec.epoch[0]; |
|
575
|
|
|
|
|
|
|
ssl->expectedEpoch[1] = ssl->rec.epoch[1]; |
|
576
|
|
|
|
|
|
|
goto ADVANCE_TO_APP_DATA; |
|
577
|
|
|
|
|
|
|
} |
|
578
|
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
/* Now just skip the record as a duplicate */ |
|
580
|
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
c += ssl->rec.len; |
|
582
|
|
|
|
|
|
|
*buf = c; |
|
583
|
|
|
|
|
|
|
/* If this is a ChangeCipherSpec message from the peer |
|
584
|
|
|
|
|
|
|
and we have never received encypted application data this is |
|
585
|
|
|
|
|
|
|
probably the 'endgame' problem in which the peer never received |
|
586
|
|
|
|
|
|
|
our final handshake flight. Trigger a resend in this specific |
|
587
|
|
|
|
|
|
|
case */ |
|
588
|
|
|
|
|
|
|
if ((ssl->rec.type == SSL_RECORD_TYPE_CHANGE_CIPHER_SPEC) && |
|
589
|
|
|
|
|
|
|
(ssl->appDataExch == 0)) |
|
590
|
|
|
|
|
|
|
{ |
|
591
|
|
|
|
|
|
|
/* Need to make sure we mark the rest of this buffer as read. |
|
592
|
|
|
|
|
|
|
The CCS message can be passed in here with the FINISHED tacked |
|
593
|
|
|
|
|
|
|
on. OpenSSL sends them separately but most wouldn't */ |
|
594
|
|
|
|
|
|
|
if (end != c) |
|
595
|
|
|
|
|
|
|
{ |
|
596
|
|
|
|
|
|
|
psAssert(*c == SSL_RECORD_TYPE_HANDSHAKE); /* Finished */ |
|
597
|
|
|
|
|
|
|
c += 11; /* Skip type, version, epoch to get to length */ |
|
598
|
|
|
|
|
|
|
/* borrow rc since we will be leaving here anyway */ |
|
599
|
|
|
|
|
|
|
rc = *c << 8; c++; |
|
600
|
|
|
|
|
|
|
rc += *c; c++; |
|
601
|
|
|
|
|
|
|
c += rc; /* Skip FINISHED message we've already accepted */ |
|
602
|
|
|
|
|
|
|
*buf = c; |
|
603
|
|
|
|
|
|
|
} |
|
604
|
|
|
|
|
|
|
return DTLS_RETRANSMIT; |
|
605
|
|
|
|
|
|
|
} |
|
606
|
|
|
|
|
|
|
if (end - c > 0) |
|
607
|
|
|
|
|
|
|
{ |
|
608
|
|
|
|
|
|
|
goto decodeMore; |
|
609
|
|
|
|
|
|
|
} |
|
610
|
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
/* Next, check if this is a record on a session that the server |
|
612
|
|
|
|
|
|
|
has already closed. Server timed out this client completely and then |
|
613
|
|
|
|
|
|
|
the client decides to send a new encoded client hello or app data |
|
614
|
|
|
|
|
|
|
on an epoch that it thinks is fine. If we are getting an epoch |
|
615
|
|
|
|
|
|
|
greater than ours and we don't even have a state for this client, |
|
616
|
|
|
|
|
|
|
an error should be returned so the ssl session can be deleted */ |
|
617
|
|
|
|
|
|
|
if (rc == 1 && ssl->flags & SSL_FLAGS_SERVER && |
|
618
|
|
|
|
|
|
|
ssl->hsState == SSL_HS_CLIENT_HELLO) |
|
619
|
|
|
|
|
|
|
{ |
|
620
|
|
|
|
|
|
|
*buf = origbuf; |
|
621
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
622
|
|
|
|
|
|
|
psTraceDtls("Client sending record on closed session\n"); |
|
623
|
|
|
|
|
|
|
goto encodeResponse; |
|
624
|
|
|
|
|
|
|
} |
|
625
|
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
/* If getting epoch that is less than expected, we'll resend */ |
|
627
|
|
|
|
|
|
|
if (rc == -1) |
|
628
|
|
|
|
|
|
|
{ |
|
629
|
|
|
|
|
|
|
return DTLS_RETRANSMIT; |
|
630
|
|
|
|
|
|
|
} |
|
631
|
|
|
|
|
|
|
/* Got FINISHED message without ever getting a change cipher spec */ |
|
632
|
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
633
|
|
|
|
|
|
|
} |
|
634
|
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
if (dtlsChkReplayWindow(ssl, ssl->rec.rsn) != 1) |
|
636
|
|
|
|
|
|
|
{ |
|
637
|
|
|
|
|
|
|
psTraceIntDtls("Seen this record before %d\n", ssl->rec.rsn[5]); |
|
638
|
|
|
|
|
|
|
c += ssl->rec.len; |
|
639
|
|
|
|
|
|
|
*buf = c; |
|
640
|
|
|
|
|
|
|
if (end - c > 0) |
|
641
|
|
|
|
|
|
|
{ |
|
642
|
|
|
|
|
|
|
goto decodeMore; |
|
643
|
|
|
|
|
|
|
} |
|
644
|
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
645
|
|
|
|
|
|
|
} |
|
646
|
|
|
|
|
|
|
} |
|
647
|
|
|
|
|
|
|
ADVANCE_TO_APP_DATA: |
|
648
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
649
|
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
#ifdef USE_MATRIXSSL_STATS |
|
651
|
|
|
|
|
|
|
if (ssl->rec.type == SSL_RECORD_TYPE_APPLICATION_DATA) |
|
652
|
|
|
|
|
|
|
{ |
|
653
|
|
|
|
|
|
|
matrixsslUpdateStat(ssl, APP_DATA_RECV_STAT, ssl->rec.len + |
|
654
|
|
|
|
|
|
|
ssl->recordHeadLen); |
|
655
|
|
|
|
|
|
|
} |
|
656
|
|
|
|
|
|
|
#endif |
|
657
|
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
/* |
|
659
|
|
|
|
|
|
|
Decrypt the entire record contents. The record length should be |
|
660
|
|
|
|
|
|
|
a multiple of block size, or decrypt will return an error |
|
661
|
|
|
|
|
|
|
If we're still handshaking and sending plaintext, the decryption |
|
662
|
|
|
|
|
|
|
callback will point to a null provider that passes the data unchanged |
|
663
|
|
|
|
|
|
|
*/ |
|
664
|
|
|
|
|
|
|
|
|
665
|
15071
|
|
|
|
|
|
ctStart = origbuf; /* Clear-text start. Decrypt to the front */ |
|
666
|
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
/* Sanity check ct len. Step 1 of Lucky 13 MEE-TLS-CBC decryption. |
|
668
|
|
|
|
|
|
|
max{b, t + 1} is always "t + 1" because largest possible blocksize |
|
669
|
|
|
|
|
|
|
is 16 and smallest possible tag len is 16. Multiple of block size test |
|
670
|
|
|
|
|
|
|
is done in decrypt. We return the identical error as if the mac failed, |
|
671
|
|
|
|
|
|
|
since this is a sanity check for pad and mac verification. */ |
|
672
|
15071
|
100
|
|
|
|
|
if ((ssl->flags & SSL_FLAGS_READ_SECURE) && (ssl->deBlockSize > 1) && |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
673
|
3
|
|
|
|
|
|
!(ssl->flags & SSL_FLAGS_AEAD_R)) |
|
674
|
|
|
|
|
|
|
{ |
|
675
|
|
|
|
|
|
|
#ifdef USE_TLS_1_1 |
|
676
|
3
|
50
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_TLS_1_1) |
|
677
|
|
|
|
|
|
|
{ |
|
678
|
3
|
50
|
|
|
|
|
if (ssl->rec.len < (ssl->deMacSize + 1 + ssl->deBlockSize)) |
|
679
|
|
|
|
|
|
|
{ |
|
680
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_BAD_RECORD_MAC; |
|
681
|
|
|
|
|
|
|
psTraceInfo("Ciphertext length failed sanity\n"); |
|
682
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
683
|
|
|
|
|
|
|
} |
|
684
|
|
|
|
|
|
|
} |
|
685
|
|
|
|
|
|
|
else |
|
686
|
|
|
|
|
|
|
{ |
|
687
|
0
|
0
|
|
|
|
|
if (ssl->rec.len < (ssl->deMacSize + 1)) |
|
688
|
|
|
|
|
|
|
{ |
|
689
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_BAD_RECORD_MAC; |
|
690
|
|
|
|
|
|
|
psTraceInfo("Ciphertext length failed sanity\n"); |
|
691
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
692
|
|
|
|
|
|
|
} |
|
693
|
|
|
|
|
|
|
} |
|
694
|
|
|
|
|
|
|
#else |
|
695
|
|
|
|
|
|
|
if (ssl->rec.len < (ssl->deMacSize + 1)) |
|
696
|
|
|
|
|
|
|
{ |
|
697
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_BAD_RECORD_MAC; |
|
698
|
|
|
|
|
|
|
psTraceInfo("Ciphertext length failed sanity\n"); |
|
699
|
|
|
|
|
|
|
goto encodeResponse; |
|
700
|
|
|
|
|
|
|
} |
|
701
|
|
|
|
|
|
|
#endif /* USE_TLS_1_1 */ |
|
702
|
|
|
|
|
|
|
} |
|
703
|
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
/* CT to PT */ |
|
705
|
15071
|
50
|
|
|
|
|
if (ssl->decrypt(ssl, c, ctStart, ssl->rec.len) < 0) |
|
706
|
|
|
|
|
|
|
{ |
|
707
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECRYPT_ERROR; |
|
708
|
|
|
|
|
|
|
psTraceInfo("Couldn't decrypt record data 2\n"); |
|
709
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
710
|
|
|
|
|
|
|
} |
|
711
|
|
|
|
|
|
|
|
|
712
|
15071
|
|
|
|
|
|
c += ssl->rec.len; |
|
713
|
|
|
|
|
|
|
|
|
714
|
15071
|
100
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_AEAD_R) |
|
715
|
|
|
|
|
|
|
{ |
|
716
|
|
|
|
|
|
|
/* AEAD needs a bit of manual length manipulation for buffer mgmnt */ |
|
717
|
6287
|
50
|
|
|
|
|
ssl->rec.len -= AEAD_TAG_LEN(ssl); |
|
718
|
6287
|
50
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_NONCE_R) |
|
719
|
|
|
|
|
|
|
{ |
|
720
|
6287
|
|
|
|
|
|
ssl->rec.len -= TLS_EXPLICIT_NONCE_LEN; |
|
721
|
|
|
|
|
|
|
} |
|
722
|
|
|
|
|
|
|
} |
|
723
|
|
|
|
|
|
|
/* |
|
724
|
|
|
|
|
|
|
If we're reading a secure message, we need to validate the MAC and |
|
725
|
|
|
|
|
|
|
padding (if using a block cipher). Insecure messages do not have |
|
726
|
|
|
|
|
|
|
a trailing MAC or any padding. |
|
727
|
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
SECURITY - There are several vulnerabilities in block cipher padding |
|
729
|
|
|
|
|
|
|
that we handle in the below code. For more information see: |
|
730
|
|
|
|
|
|
|
http://www.openssl.org/~bodo/tls-cbc.txt |
|
731
|
|
|
|
|
|
|
*/ |
|
732
|
15071
|
100
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_READ_SECURE && !(ssl->flags & SSL_FLAGS_AEAD_R)) |
|
|
|
100
|
|
|
|
|
|
|
733
|
|
|
|
|
|
|
{ |
|
734
|
|
|
|
|
|
|
/* |
|
735
|
|
|
|
|
|
|
Start tracking MAC errors, rather then immediately catching them to |
|
736
|
|
|
|
|
|
|
stop timing and alert description attacks that differentiate between |
|
737
|
|
|
|
|
|
|
a padding error and a MAC error. |
|
738
|
|
|
|
|
|
|
*/ |
|
739
|
3
|
|
|
|
|
|
macError = 0; |
|
740
|
|
|
|
|
|
|
/* |
|
741
|
|
|
|
|
|
|
Decode padding only if blocksize is > 0 (we're using a block cipher), |
|
742
|
|
|
|
|
|
|
otherwise no padding will be present, and the mac is the last |
|
743
|
|
|
|
|
|
|
macSize bytes of the record. |
|
744
|
|
|
|
|
|
|
*/ |
|
745
|
3
|
50
|
|
|
|
|
if (ssl->deBlockSize <= 1) |
|
746
|
|
|
|
|
|
|
{ |
|
747
|
0
|
|
|
|
|
|
mac = ctStart + ssl->rec.len - ssl->deMacSize; |
|
748
|
|
|
|
|
|
|
} |
|
749
|
|
|
|
|
|
|
else |
|
750
|
|
|
|
|
|
|
{ |
|
751
|
|
|
|
|
|
|
/* |
|
752
|
|
|
|
|
|
|
The goal from here through completion of ssl->verifyMac call is a |
|
753
|
|
|
|
|
|
|
constant processing time for a given record length. Going to |
|
754
|
|
|
|
|
|
|
follow the suggestions of the Lucky 13 research paper section |
|
755
|
|
|
|
|
|
|
"Careful implementation of MEE-TLS-CBC decryption". |
|
756
|
|
|
|
|
|
|
http://www.isg.rhul.ac.uk/tls/TLStiming.pdf |
|
757
|
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
Consistent timing is still a "goal" here. This implementation |
|
759
|
|
|
|
|
|
|
accounts for the largest timing discrepencies but is not a |
|
760
|
|
|
|
|
|
|
strict "clock cycles" equalizer. The complexity of the attack |
|
761
|
|
|
|
|
|
|
circumstances and plaintext recovery possibilities using these |
|
762
|
|
|
|
|
|
|
techniques is almost entirely in the academic realm. Improvements |
|
763
|
|
|
|
|
|
|
to this code will be an ongoing process as research uncovers |
|
764
|
|
|
|
|
|
|
more practical plaintext recovery threats. |
|
765
|
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
Verify the pad data for block ciphers |
|
767
|
|
|
|
|
|
|
c points within the cipher text, p points within the plaintext |
|
768
|
|
|
|
|
|
|
The last byte of the record is the pad length |
|
769
|
|
|
|
|
|
|
*/ |
|
770
|
3
|
|
|
|
|
|
p = ctStart + ssl->rec.len; |
|
771
|
3
|
|
|
|
|
|
padLen = *(p - 1); |
|
772
|
|
|
|
|
|
|
/* |
|
773
|
|
|
|
|
|
|
SSL3.0 requires the pad length to be less than blockSize |
|
774
|
|
|
|
|
|
|
TLS can have a pad length up to 255 for obfuscating the data len |
|
775
|
|
|
|
|
|
|
*/ |
|
776
|
3
|
50
|
|
|
|
|
if (ssl->majVer == SSL3_MAJ_VER && ssl->minVer == SSL3_MIN_VER && |
|
|
|
50
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
777
|
0
|
|
|
|
|
|
padLen >= ssl->deBlockSize) |
|
778
|
|
|
|
|
|
|
{ |
|
779
|
0
|
|
|
|
|
|
macError = 1; |
|
780
|
|
|
|
|
|
|
} |
|
781
|
|
|
|
|
|
|
/* |
|
782
|
|
|
|
|
|
|
The minimum record length is the size of the mac, plus pad bytes |
|
783
|
|
|
|
|
|
|
plus one length byte, plus explicit IV if TLS 1.1 or above |
|
784
|
|
|
|
|
|
|
*/ |
|
785
|
3
|
50
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_TLS_1_1) |
|
786
|
|
|
|
|
|
|
{ |
|
787
|
3
|
50
|
|
|
|
|
if (ssl->rec.len < ssl->deMacSize + padLen + 1 + ssl->deBlockSize) |
|
788
|
|
|
|
|
|
|
{ |
|
789
|
3
|
|
|
|
|
|
macError = 2; |
|
790
|
|
|
|
|
|
|
} |
|
791
|
|
|
|
|
|
|
} |
|
792
|
|
|
|
|
|
|
else |
|
793
|
|
|
|
|
|
|
{ |
|
794
|
0
|
0
|
|
|
|
|
if (ssl->rec.len < ssl->deMacSize + padLen + 1) |
|
795
|
|
|
|
|
|
|
{ |
|
796
|
0
|
|
|
|
|
|
macError = 3; |
|
797
|
|
|
|
|
|
|
} |
|
798
|
|
|
|
|
|
|
} |
|
799
|
3
|
50
|
|
|
|
|
if (macError) |
|
800
|
|
|
|
|
|
|
{ |
|
801
|
|
|
|
|
|
|
/* Step 3 of Lucky 13 MEE-TLS-CBC decryption: Run a loop as |
|
802
|
|
|
|
|
|
|
if there were 256 bytes of padding, with a dummy check |
|
803
|
|
|
|
|
|
|
in each iteration*/ |
|
804
|
0
|
0
|
|
|
|
|
for (rc = 255; rc >= 0; rc--) |
|
805
|
|
|
|
|
|
|
{ |
|
806
|
|
|
|
|
|
|
/* make the test a moving target so it doesn't get |
|
807
|
|
|
|
|
|
|
optimized out at compile. The loop is written |
|
808
|
|
|
|
|
|
|
this way so the macError assignment will be done |
|
809
|
|
|
|
|
|
|
only once */ |
|
810
|
0
|
0
|
|
|
|
|
if ((unsigned char) rc == padLen) |
|
811
|
|
|
|
|
|
|
{ |
|
812
|
0
|
|
|
|
|
|
macError = 1; /* No incr to avoid any wraps */ |
|
813
|
|
|
|
|
|
|
} |
|
814
|
|
|
|
|
|
|
} |
|
815
|
|
|
|
|
|
|
} |
|
816
|
|
|
|
|
|
|
#ifdef USE_TLS |
|
817
|
|
|
|
|
|
|
/* |
|
818
|
|
|
|
|
|
|
TLS specifies that all pad bytes must have the same value |
|
819
|
|
|
|
|
|
|
as the final pad length byte. Some SSL3 implementations also |
|
820
|
|
|
|
|
|
|
do this by convention, but some just fill with random bytes. |
|
821
|
|
|
|
|
|
|
(We're just overloading the 'mac' ptr here, this has nothing to |
|
822
|
|
|
|
|
|
|
do with real MAC.) |
|
823
|
|
|
|
|
|
|
*/ |
|
824
|
3
|
50
|
|
|
|
|
if (!macError && ssl->majVer == TLS_MAJ_VER && |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
825
|
3
|
|
|
|
|
|
ssl->minVer >= TLS_MIN_VER) |
|
826
|
|
|
|
|
|
|
{ |
|
827
|
37
|
100
|
|
|
|
|
for (mac = p - padLen - 1; mac < p; mac++) |
|
828
|
|
|
|
|
|
|
{ |
|
829
|
34
|
50
|
|
|
|
|
if (*mac != padLen) |
|
830
|
|
|
|
|
|
|
{ |
|
831
|
0
|
|
|
|
|
|
macError = 1; |
|
832
|
|
|
|
|
|
|
} |
|
833
|
|
|
|
|
|
|
} |
|
834
|
|
|
|
|
|
|
/* Lucky 13 step 4. If this fails, then run a loop as if there |
|
835
|
|
|
|
|
|
|
were 256 - padlen - 1 bytes of padding, with a dummy |
|
836
|
|
|
|
|
|
|
check in each iteration */ |
|
837
|
3
|
50
|
|
|
|
|
if (macError) |
|
838
|
|
|
|
|
|
|
{ |
|
839
|
0
|
0
|
|
|
|
|
for (rc = 256 - padLen - 1; rc > 0; rc--) |
|
840
|
|
|
|
|
|
|
{ |
|
841
|
|
|
|
|
|
|
/* make the test a moving target so it doesn't get |
|
842
|
|
|
|
|
|
|
optimized out at compile. Again, make it so |
|
843
|
|
|
|
|
|
|
the loop condition doesn't get hit more than |
|
844
|
|
|
|
|
|
|
once. */ |
|
845
|
0
|
0
|
|
|
|
|
if ((unsigned char) rc == padLen) |
|
846
|
|
|
|
|
|
|
{ |
|
847
|
0
|
|
|
|
|
|
macError = 2; /* change value for smart compilers */ |
|
848
|
|
|
|
|
|
|
} |
|
849
|
|
|
|
|
|
|
} |
|
850
|
|
|
|
|
|
|
} |
|
851
|
|
|
|
|
|
|
} |
|
852
|
|
|
|
|
|
|
#endif /* USE_TLS */ |
|
853
|
|
|
|
|
|
|
/* |
|
854
|
|
|
|
|
|
|
The mac starts macSize bytes before the padding and length byte. |
|
855
|
|
|
|
|
|
|
If we have a macError, just fake the mac as the last macSize bytes |
|
856
|
|
|
|
|
|
|
of the record, so we are sure to have enough bytes to verify |
|
857
|
|
|
|
|
|
|
against, we'll fail anyway, so the actual contents don't matter. |
|
858
|
|
|
|
|
|
|
*/ |
|
859
|
3
|
50
|
|
|
|
|
if (!macError) |
|
860
|
|
|
|
|
|
|
{ |
|
861
|
|
|
|
|
|
|
/* No padding errors */ |
|
862
|
3
|
|
|
|
|
|
mac = p - padLen - 1 - ssl->deMacSize; |
|
863
|
|
|
|
|
|
|
/* Lucky 13 step 5: Otherwise (the padding is now correctly |
|
864
|
|
|
|
|
|
|
formatted) run a loop as if there were 256 - padlen - 1 |
|
865
|
|
|
|
|
|
|
bytes of padding, doing a dummy check in each iteration */ |
|
866
|
737
|
100
|
|
|
|
|
for (rc = (256 - padLen) - 1; rc > 0; rc--) |
|
867
|
|
|
|
|
|
|
{ |
|
868
|
|
|
|
|
|
|
/* make this test look like the others */ |
|
869
|
734
|
100
|
|
|
|
|
if ((unsigned char) rc == padLen) |
|
870
|
|
|
|
|
|
|
{ |
|
871
|
|
|
|
|
|
|
/* coverity[assigned_value] */ |
|
872
|
3
|
|
|
|
|
|
macError = 1; /* not really an error. reset below */ |
|
873
|
|
|
|
|
|
|
} |
|
874
|
|
|
|
|
|
|
} |
|
875
|
|
|
|
|
|
|
(void) macError; /* Suppress static analysis warnings */ |
|
876
|
3
|
|
|
|
|
|
macError = 0; |
|
877
|
|
|
|
|
|
|
} |
|
878
|
|
|
|
|
|
|
else |
|
879
|
|
|
|
|
|
|
{ |
|
880
|
|
|
|
|
|
|
/* Lucky 13 step 3 and 4 condition: Then let P' denote the first |
|
881
|
|
|
|
|
|
|
plen - t bytes of P, compute a MAC on SQN||HDR||P' and do a |
|
882
|
|
|
|
|
|
|
constant-time comparison of the computed MAC with the |
|
883
|
|
|
|
|
|
|
last t bytes of P. Return fatal error. */ |
|
884
|
0
|
|
|
|
|
|
mac = origbuf + ssl->rec.len - ssl->deMacSize; |
|
885
|
|
|
|
|
|
|
} |
|
886
|
|
|
|
|
|
|
} |
|
887
|
|
|
|
|
|
|
/* |
|
888
|
|
|
|
|
|
|
Verify the MAC of the message by calculating our own MAC of the message |
|
889
|
|
|
|
|
|
|
and comparing it to the one in the message. We do this step regardless |
|
890
|
|
|
|
|
|
|
of whether or not we've already set macError to stop timing attacks. |
|
891
|
|
|
|
|
|
|
Clear the mac in the callers buffer if we're successful |
|
892
|
|
|
|
|
|
|
*/ |
|
893
|
|
|
|
|
|
|
#ifdef USE_TLS_1_1 |
|
894
|
3
|
50
|
|
|
|
|
if ((ssl->flags & SSL_FLAGS_TLS_1_1) && (ssl->deBlockSize > 1)) |
|
|
|
50
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
{ |
|
896
|
3
|
|
|
|
|
|
ctStart += ssl->deBlockSize; /* skip explicit IV */ |
|
897
|
|
|
|
|
|
|
} |
|
898
|
|
|
|
|
|
|
#endif |
|
899
|
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
#ifdef LUCKY13 |
|
901
|
|
|
|
|
|
|
/* |
|
902
|
|
|
|
|
|
|
Lucky 13 Step 5. If using a block cipher, blind the mac operation. |
|
903
|
|
|
|
|
|
|
Doing this extra MAC compression here rather |
|
904
|
|
|
|
|
|
|
than inside the real verify to keep this code patch at the |
|
905
|
|
|
|
|
|
|
protocol level. |
|
906
|
|
|
|
|
|
|
The Sha Update calls are with an exact state size for the |
|
907
|
|
|
|
|
|
|
hash, so the compress function will be called 1:1 with the Update. |
|
908
|
|
|
|
|
|
|
*/ |
|
909
|
3
|
50
|
|
|
|
|
if (ssl->deBlockSize > 1) |
|
910
|
|
|
|
|
|
|
{ |
|
911
|
|
|
|
|
|
|
/* Run this helper regardless of error status thus far */ |
|
912
|
3
|
|
|
|
|
|
rc = addCompressCount(ssl, padLen); |
|
913
|
3
|
50
|
|
|
|
|
if (macError == 0) |
|
914
|
|
|
|
|
|
|
{ |
|
915
|
|
|
|
|
|
|
psDigestContext_t md; |
|
916
|
|
|
|
|
|
|
unsigned char tmp[128]; |
|
917
|
3
|
|
|
|
|
|
switch (ssl->deMacSize) |
|
918
|
|
|
|
|
|
|
{ |
|
919
|
|
|
|
|
|
|
# ifdef USE_SHA256 |
|
920
|
|
|
|
|
|
|
case SHA256_HASH_SIZE: |
|
921
|
0
|
|
|
|
|
|
psSha256PreInit(&md.sha256); |
|
922
|
0
|
|
|
|
|
|
psSha256Init(&md.sha256); |
|
923
|
0
|
0
|
|
|
|
|
while (rc > 0) |
|
924
|
|
|
|
|
|
|
{ |
|
925
|
0
|
|
|
|
|
|
psSha256Update(&md.sha256, tmp, 64); |
|
926
|
0
|
|
|
|
|
|
rc--; |
|
927
|
|
|
|
|
|
|
} |
|
928
|
0
|
|
|
|
|
|
psSha256Final(&md.sha256, tmp); |
|
929
|
0
|
|
|
|
|
|
break; |
|
930
|
|
|
|
|
|
|
# endif |
|
931
|
|
|
|
|
|
|
# ifdef USE_SHA384 |
|
932
|
|
|
|
|
|
|
case SHA384_HASH_SIZE: |
|
933
|
0
|
|
|
|
|
|
psSha384PreInit(&md.sha384); |
|
934
|
0
|
|
|
|
|
|
psSha384Init(&md.sha384); |
|
935
|
0
|
0
|
|
|
|
|
while (rc > 0) |
|
936
|
|
|
|
|
|
|
{ |
|
937
|
0
|
|
|
|
|
|
psSha384Update(&md.sha384, tmp, 128); |
|
938
|
0
|
|
|
|
|
|
rc--; |
|
939
|
|
|
|
|
|
|
} |
|
940
|
0
|
|
|
|
|
|
psSha384Final(&md.sha384, tmp); |
|
941
|
0
|
|
|
|
|
|
break; |
|
942
|
|
|
|
|
|
|
# endif |
|
943
|
|
|
|
|
|
|
# ifdef USE_SHA1 |
|
944
|
|
|
|
|
|
|
case SHA1_HASH_SIZE: |
|
945
|
3
|
|
|
|
|
|
psSha1PreInit(&md.sha1); |
|
946
|
3
|
|
|
|
|
|
psSha1Init(&md.sha1); |
|
947
|
3
|
50
|
|
|
|
|
while (rc > 0) |
|
948
|
|
|
|
|
|
|
{ |
|
949
|
0
|
|
|
|
|
|
psSha1Update(&md.sha1, tmp, 64); |
|
950
|
0
|
|
|
|
|
|
rc--; |
|
951
|
|
|
|
|
|
|
} |
|
952
|
3
|
|
|
|
|
|
psSha1Final(&md.sha1, tmp); |
|
953
|
3
|
|
|
|
|
|
break; |
|
954
|
|
|
|
|
|
|
# endif |
|
955
|
|
|
|
|
|
|
default: |
|
956
|
0
|
|
|
|
|
|
psAssert(0); |
|
957
|
3
|
|
|
|
|
|
break; |
|
958
|
|
|
|
|
|
|
} |
|
959
|
|
|
|
|
|
|
} |
|
960
|
|
|
|
|
|
|
} |
|
961
|
|
|
|
|
|
|
#endif /* LUCKY13 */ |
|
962
|
|
|
|
|
|
|
|
|
963
|
3
|
50
|
|
|
|
|
if (ssl->verifyMac(ssl, ssl->rec.type, ctStart, |
|
964
|
3
|
50
|
|
|
|
|
(uint32) (mac - ctStart), mac) < 0 || macError) |
|
965
|
|
|
|
|
|
|
{ |
|
966
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_BAD_RECORD_MAC; |
|
967
|
|
|
|
|
|
|
psTraceInfo("Couldn't verify MAC or pad of record data\n"); |
|
968
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
969
|
|
|
|
|
|
|
} |
|
970
|
|
|
|
|
|
|
|
|
971
|
3
|
|
|
|
|
|
memset(mac, 0x0, ssl->deMacSize); |
|
972
|
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
/* Record data starts at ctStart and ends at mac */ |
|
974
|
3
|
|
|
|
|
|
p = ctStart; |
|
975
|
3
|
|
|
|
|
|
pend = mac; |
|
976
|
|
|
|
|
|
|
} |
|
977
|
|
|
|
|
|
|
else |
|
978
|
|
|
|
|
|
|
{ |
|
979
|
|
|
|
|
|
|
/* |
|
980
|
|
|
|
|
|
|
The record data is the entire record as there is no MAC or padding |
|
981
|
|
|
|
|
|
|
*/ |
|
982
|
15068
|
|
|
|
|
|
p = ctStart; |
|
983
|
15068
|
|
|
|
|
|
pend = mac = ctStart + ssl->rec.len; |
|
984
|
|
|
|
|
|
|
} |
|
985
|
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
#ifdef USE_ZLIB_COMPRESSION |
|
987
|
|
|
|
|
|
|
/* Currently only supporting compression of FINISHED message. |
|
988
|
|
|
|
|
|
|
Compressed application data is handled outside MatrixSSL. |
|
989
|
|
|
|
|
|
|
Re-handshakes are not allowed with compression and we've |
|
990
|
|
|
|
|
|
|
incremented ssl->compression if we've already been through here |
|
991
|
|
|
|
|
|
|
so we'll know */ |
|
992
|
|
|
|
|
|
|
if (ssl->compression == 2 && ssl->flags & SSL_FLAGS_READ_SECURE && |
|
993
|
|
|
|
|
|
|
ssl->rec.type == SSL_RECORD_TYPE_HANDSHAKE) |
|
994
|
|
|
|
|
|
|
{ |
|
995
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
996
|
|
|
|
|
|
|
psTraceInfo("Re-handshakes not supported on compressed sessions\n"); |
|
997
|
|
|
|
|
|
|
goto encodeResponse; |
|
998
|
|
|
|
|
|
|
} |
|
999
|
|
|
|
|
|
|
if (ssl->compression && ssl->flags & SSL_FLAGS_READ_SECURE && |
|
1000
|
|
|
|
|
|
|
ssl->rec.type == SSL_RECORD_TYPE_HANDSHAKE) |
|
1001
|
|
|
|
|
|
|
{ |
|
1002
|
|
|
|
|
|
|
/* TODO - handle the cases below where the buffer has to grow */ |
|
1003
|
|
|
|
|
|
|
currLen = ssl->inflate.total_out; |
|
1004
|
|
|
|
|
|
|
preInflateLen = (int32) (pend - p); |
|
1005
|
|
|
|
|
|
|
ssl->zlibBuffer = psMalloc(ssl->bufferPool, preInflateLen + |
|
1006
|
|
|
|
|
|
|
MATRIX_INFLATE_FINISHED_OH); |
|
1007
|
|
|
|
|
|
|
if (ssl->zlibBuffer == NULL) |
|
1008
|
|
|
|
|
|
|
{ |
|
1009
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1010
|
|
|
|
|
|
|
psTraceInfo("Couldn't allocate compressed scratch pad\n"); |
|
1011
|
|
|
|
|
|
|
goto encodeResponse; |
|
1012
|
|
|
|
|
|
|
} |
|
1013
|
|
|
|
|
|
|
memset(ssl->zlibBuffer, 0, preInflateLen + MATRIX_INFLATE_FINISHED_OH); |
|
1014
|
|
|
|
|
|
|
if (preInflateLen > 0) /* zero length record possible */ |
|
1015
|
|
|
|
|
|
|
{ /* psTraceBytes("pre inflate", ctStart, preInflateLen); */ |
|
1016
|
|
|
|
|
|
|
ssl->inflate.next_in = ctStart; |
|
1017
|
|
|
|
|
|
|
ssl->inflate.avail_in = preInflateLen; |
|
1018
|
|
|
|
|
|
|
ssl->inflate.next_out = ssl->zlibBuffer; |
|
1019
|
|
|
|
|
|
|
ssl->inflate.avail_out = SSL_MAX_PLAINTEXT_LEN; |
|
1020
|
|
|
|
|
|
|
if ((zret = inflate(&ssl->inflate, Z_SYNC_FLUSH)) != Z_OK) |
|
1021
|
|
|
|
|
|
|
{ |
|
1022
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1023
|
|
|
|
|
|
|
psFree(ssl->zlibBuffer, ssl->bufferPool); ssl->zlibBuffer = NULL; |
|
1024
|
|
|
|
|
|
|
inflateEnd(&ssl->inflate); |
|
1025
|
|
|
|
|
|
|
psTraceIntInfo("ZLIB inflate failed %d\n", zret); |
|
1026
|
|
|
|
|
|
|
goto encodeResponse; |
|
1027
|
|
|
|
|
|
|
} |
|
1028
|
|
|
|
|
|
|
if (ssl->inflate.avail_in != 0) |
|
1029
|
|
|
|
|
|
|
{ |
|
1030
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1031
|
|
|
|
|
|
|
psFree(ssl->zlibBuffer, ssl->bufferPool); ssl->zlibBuffer = NULL; |
|
1032
|
|
|
|
|
|
|
inflateEnd(&ssl->inflate); |
|
1033
|
|
|
|
|
|
|
psTraceInfo("ZLIB inflate didn't work in one pass\n"); |
|
1034
|
|
|
|
|
|
|
goto encodeResponse; |
|
1035
|
|
|
|
|
|
|
} |
|
1036
|
|
|
|
|
|
|
postInflateLen = ssl->inflate.total_out - currLen; |
|
1037
|
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
/* psTraceBytes("post inflate", ssl->zlibBuffer, |
|
1039
|
|
|
|
|
|
|
postInflateLen); */ |
|
1040
|
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
if (postInflateLen <= preInflateLen) |
|
1042
|
|
|
|
|
|
|
{ |
|
1043
|
|
|
|
|
|
|
/* Easy case where compressed data was actually larger. |
|
1044
|
|
|
|
|
|
|
Don't need to update c or inlen because the next |
|
1045
|
|
|
|
|
|
|
good data is already correctly being pointed to */ |
|
1046
|
|
|
|
|
|
|
memcpy(p, ssl->zlibBuffer, postInflateLen); |
|
1047
|
|
|
|
|
|
|
mac = p + postInflateLen; |
|
1048
|
|
|
|
|
|
|
pend = mac; |
|
1049
|
|
|
|
|
|
|
} |
|
1050
|
|
|
|
|
|
|
else |
|
1051
|
|
|
|
|
|
|
{ |
|
1052
|
|
|
|
|
|
|
/* Data expanded. Fit it in the buffer and update all |
|
1053
|
|
|
|
|
|
|
the associated lengths and pointers |
|
1054
|
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
Add back in the MAC and pad to preInflate so we're |
|
1056
|
|
|
|
|
|
|
looking at the useful boundaries of the buffers */ |
|
1057
|
|
|
|
|
|
|
preInflateLen += (int32) (c - mac); |
|
1058
|
|
|
|
|
|
|
/* reusing currLen var. Now the difference in lengths */ |
|
1059
|
|
|
|
|
|
|
currLen = postInflateLen - preInflateLen; |
|
1060
|
|
|
|
|
|
|
if ((int32) (c - ssl->inbuf) == ssl->inlen) |
|
1061
|
|
|
|
|
|
|
{ |
|
1062
|
|
|
|
|
|
|
/* Good, this was the only data in the buffer. Just |
|
1063
|
|
|
|
|
|
|
check there is room to append */ |
|
1064
|
|
|
|
|
|
|
if ((ssl->insize - ssl->inlen) >= postInflateLen) |
|
1065
|
|
|
|
|
|
|
{ |
|
1066
|
|
|
|
|
|
|
memcpy(p, ssl->zlibBuffer, postInflateLen); |
|
1067
|
|
|
|
|
|
|
c += currLen; |
|
1068
|
|
|
|
|
|
|
mac = p + postInflateLen; |
|
1069
|
|
|
|
|
|
|
pend = mac; |
|
1070
|
|
|
|
|
|
|
} |
|
1071
|
|
|
|
|
|
|
else |
|
1072
|
|
|
|
|
|
|
{ |
|
1073
|
|
|
|
|
|
|
/* Only one here but not enough room to store it */ |
|
1074
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1075
|
|
|
|
|
|
|
psFree(ssl->zlibBuffer, ssl->bufferPool); |
|
1076
|
|
|
|
|
|
|
ssl->zlibBuffer = NULL; |
|
1077
|
|
|
|
|
|
|
inflateEnd(&ssl->inflate); |
|
1078
|
|
|
|
|
|
|
psTraceInfo("ZLIB buffer management needed\n"); |
|
1079
|
|
|
|
|
|
|
goto encodeResponse; |
|
1080
|
|
|
|
|
|
|
} |
|
1081
|
|
|
|
|
|
|
} |
|
1082
|
|
|
|
|
|
|
else |
|
1083
|
|
|
|
|
|
|
{ |
|
1084
|
|
|
|
|
|
|
/* Push any existing data further back in the buffer to |
|
1085
|
|
|
|
|
|
|
make room for this uncompressed length. c pointing |
|
1086
|
|
|
|
|
|
|
to start of next record that needs to be pushed |
|
1087
|
|
|
|
|
|
|
back. currLen is how far to push back. |
|
1088
|
|
|
|
|
|
|
p pointing to where zlibBuffer should copy |
|
1089
|
|
|
|
|
|
|
to. postInflateLen is amount to copy there. */ |
|
1090
|
|
|
|
|
|
|
if (currLen < (ssl->insize - ssl->inlen)) |
|
1091
|
|
|
|
|
|
|
{ |
|
1092
|
|
|
|
|
|
|
/* Good, fits in current buffer. Move all valid |
|
1093
|
|
|
|
|
|
|
data back currLen */ |
|
1094
|
|
|
|
|
|
|
memmove(c + currLen, c, |
|
1095
|
|
|
|
|
|
|
ssl->inlen - (int32) (c - ssl->inbuf)); |
|
1096
|
|
|
|
|
|
|
c += currLen; |
|
1097
|
|
|
|
|
|
|
memcpy(p, ssl->zlibBuffer, postInflateLen); |
|
1098
|
|
|
|
|
|
|
mac = p + postInflateLen; |
|
1099
|
|
|
|
|
|
|
pend = mac; |
|
1100
|
|
|
|
|
|
|
} |
|
1101
|
|
|
|
|
|
|
else |
|
1102
|
|
|
|
|
|
|
{ |
|
1103
|
|
|
|
|
|
|
/* Need to realloc more space AND push the records |
|
1104
|
|
|
|
|
|
|
back */ |
|
1105
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1106
|
|
|
|
|
|
|
psFree(ssl->zlibBuffer, ssl->bufferPool); |
|
1107
|
|
|
|
|
|
|
ssl->zlibBuffer = NULL; |
|
1108
|
|
|
|
|
|
|
inflateEnd(&ssl->inflate); |
|
1109
|
|
|
|
|
|
|
psTraceInfo("ZLIB buffer management needed\n"); |
|
1110
|
|
|
|
|
|
|
goto encodeResponse; |
|
1111
|
|
|
|
|
|
|
} |
|
1112
|
|
|
|
|
|
|
} |
|
1113
|
|
|
|
|
|
|
/* Finally increase inlen and *len to account for it now */ |
|
1114
|
|
|
|
|
|
|
ssl->inlen += currLen; |
|
1115
|
|
|
|
|
|
|
*len += currLen; |
|
1116
|
|
|
|
|
|
|
ssl->rec.len += currLen; |
|
1117
|
|
|
|
|
|
|
} |
|
1118
|
|
|
|
|
|
|
} |
|
1119
|
|
|
|
|
|
|
psFree(ssl->zlibBuffer, ssl->bufferPool); ssl->zlibBuffer = NULL; |
|
1120
|
|
|
|
|
|
|
/* Will not need the context any longer since FINISHED is the only |
|
1121
|
|
|
|
|
|
|
supported message */ |
|
1122
|
|
|
|
|
|
|
inflateEnd(&ssl->inflate); |
|
1123
|
|
|
|
|
|
|
ssl->compression = 2; |
|
1124
|
|
|
|
|
|
|
} |
|
1125
|
|
|
|
|
|
|
#endif /* USE_ZLIB_COMPRESSION */ |
|
1126
|
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
/* Check now for maximum plaintext length of 16kb. */ |
|
1128
|
15071
|
50
|
|
|
|
|
if (ssl->maxPtFrag == 0xFF) /* Still negotiating size */ |
|
1129
|
|
|
|
|
|
|
{ |
|
1130
|
0
|
0
|
|
|
|
|
if ((int32) (pend - p) > SSL_MAX_PLAINTEXT_LEN) |
|
1131
|
|
|
|
|
|
|
{ |
|
1132
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_RECORD_OVERFLOW; |
|
1133
|
|
|
|
|
|
|
psTraceInfo("Record overflow\n"); |
|
1134
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1135
|
|
|
|
|
|
|
} |
|
1136
|
|
|
|
|
|
|
} |
|
1137
|
|
|
|
|
|
|
else |
|
1138
|
|
|
|
|
|
|
{ |
|
1139
|
15071
|
50
|
|
|
|
|
if ((int32) (pend - p) > ssl->maxPtFrag) |
|
1140
|
|
|
|
|
|
|
{ |
|
1141
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_RECORD_OVERFLOW; |
|
1142
|
|
|
|
|
|
|
psTraceInfo("Record overflow\n"); |
|
1143
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1144
|
|
|
|
|
|
|
} |
|
1145
|
|
|
|
|
|
|
} |
|
1146
|
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
/* |
|
1148
|
|
|
|
|
|
|
Take action based on the actual record type we're dealing with |
|
1149
|
|
|
|
|
|
|
'p' points to the start of the data, and 'pend' points to the end |
|
1150
|
|
|
|
|
|
|
*/ |
|
1151
|
15071
|
|
|
|
|
|
switch (ssl->rec.type) |
|
1152
|
|
|
|
|
|
|
{ |
|
1153
|
|
|
|
|
|
|
case SSL_RECORD_TYPE_CHANGE_CIPHER_SPEC: |
|
1154
|
|
|
|
|
|
|
psTraceStrHs(">>> %s parsing CHANGE_CIPHER_SPEC message\n", |
|
1155
|
|
|
|
|
|
|
(ssl->flags & SSL_FLAGS_SERVER) ? "Server" : "Client"); |
|
1156
|
|
|
|
|
|
|
/* |
|
1157
|
|
|
|
|
|
|
Body is single byte with value 1 to indicate that the next message |
|
1158
|
|
|
|
|
|
|
will be encrypted using the negotiated cipher suite |
|
1159
|
|
|
|
|
|
|
*/ |
|
1160
|
2119
|
50
|
|
|
|
|
if (pend - p < 1) |
|
1161
|
|
|
|
|
|
|
{ |
|
1162
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
1163
|
|
|
|
|
|
|
psTraceInfo("Invalid length for CipherSpec\n"); |
|
1164
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1165
|
|
|
|
|
|
|
} |
|
1166
|
2119
|
50
|
|
|
|
|
if (*p == 1) |
|
1167
|
|
|
|
|
|
|
{ |
|
1168
|
2119
|
|
|
|
|
|
p++; |
|
1169
|
|
|
|
|
|
|
} |
|
1170
|
|
|
|
|
|
|
else |
|
1171
|
|
|
|
|
|
|
{ |
|
1172
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
1173
|
|
|
|
|
|
|
psTraceInfo("Invalid value for CipherSpec\n"); |
|
1174
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1175
|
|
|
|
|
|
|
} |
|
1176
|
|
|
|
|
|
|
|
|
1177
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
1178
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
1179
|
|
|
|
|
|
|
{ |
|
1180
|
|
|
|
|
|
|
if (ssl->hsState != SSL_HS_FINISHED) |
|
1181
|
|
|
|
|
|
|
{ |
|
1182
|
|
|
|
|
|
|
/* Possible to get the changeCipherSpec message out of order */ |
|
1183
|
|
|
|
|
|
|
psTraceIntInfo("Got out of order CCS: state %d\n", ssl->hsState); |
|
1184
|
|
|
|
|
|
|
*buf = c; |
|
1185
|
|
|
|
|
|
|
goto decodeMore; |
|
1186
|
|
|
|
|
|
|
} |
|
1187
|
|
|
|
|
|
|
/* The epoch corner cases surrounding the CHANGE_CIPHER_SPEC |
|
1188
|
|
|
|
|
|
|
message are complex. Let's just finally create a clear signal |
|
1189
|
|
|
|
|
|
|
that the CCS was parsed. The general problem is that our |
|
1190
|
|
|
|
|
|
|
state machine is FINISHED when expecting either the CCS or |
|
1191
|
|
|
|
|
|
|
the FINISHED message (probably goes back to CCS having some |
|
1192
|
|
|
|
|
|
|
special record type in the specs). This will just be set |
|
1193
|
|
|
|
|
|
|
between CCS parse and FINISHED parse */ |
|
1194
|
|
|
|
|
|
|
ssl->parsedCCS = 1; |
|
1195
|
|
|
|
|
|
|
} |
|
1196
|
|
|
|
|
|
|
/* |
|
1197
|
|
|
|
|
|
|
Expect epoch to increment after successful CCS parse |
|
1198
|
|
|
|
|
|
|
*/ |
|
1199
|
|
|
|
|
|
|
incrTwoByte(ssl, ssl->expectedEpoch, 0); |
|
1200
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
1201
|
|
|
|
|
|
|
|
|
1202
|
2119
|
|
|
|
|
|
*remaining = *len - (c - origbuf); |
|
1203
|
2119
|
|
|
|
|
|
*buf = c; |
|
1204
|
|
|
|
|
|
|
/* |
|
1205
|
|
|
|
|
|
|
If we're expecting finished, then this is the right place to get |
|
1206
|
|
|
|
|
|
|
this record. It is really part of the handshake but it has its |
|
1207
|
|
|
|
|
|
|
own record type. |
|
1208
|
|
|
|
|
|
|
Activate the read cipher callbacks, so we will decrypt incoming |
|
1209
|
|
|
|
|
|
|
data from now on. |
|
1210
|
|
|
|
|
|
|
*/ |
|
1211
|
2119
|
50
|
|
|
|
|
if (ssl->hsState == SSL_HS_FINISHED) |
|
1212
|
|
|
|
|
|
|
{ |
|
1213
|
2119
|
50
|
|
|
|
|
if (sslActivateReadCipher(ssl) < 0) |
|
1214
|
|
|
|
|
|
|
{ |
|
1215
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1216
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1217
|
|
|
|
|
|
|
} |
|
1218
|
|
|
|
|
|
|
} |
|
1219
|
|
|
|
|
|
|
else |
|
1220
|
|
|
|
|
|
|
{ |
|
1221
|
|
|
|
|
|
|
#ifdef USE_STATELESS_SESSION_TICKETS |
|
1222
|
|
|
|
|
|
|
/* RFC 5077 allows the server to not acknowlege whether or not it |
|
1223
|
|
|
|
|
|
|
accepted our session ticket in the SERVER_HELLO extension so |
|
1224
|
|
|
|
|
|
|
there was no place prior to recieving this CCS to find out. |
|
1225
|
|
|
|
|
|
|
Different cipher suites types will be in different states */ |
|
1226
|
0
|
0
|
|
|
|
|
if (ssl->hsState == SSL_HS_CERTIFICATE && ssl->sid && |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1227
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState == SESS_TICKET_STATE_IN_LIMBO) |
|
1228
|
|
|
|
|
|
|
{ |
|
1229
|
|
|
|
|
|
|
/* Do all the things that should have been done earlier */ |
|
1230
|
0
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_RESUMED; |
|
1231
|
|
|
|
|
|
|
# ifdef USE_MATRIXSSL_STATS |
|
1232
|
|
|
|
|
|
|
matrixsslUpdateStat(ssl, RESUMPTIONS_STAT, 1); |
|
1233
|
|
|
|
|
|
|
# endif |
|
1234
|
0
|
0
|
|
|
|
|
if (sslCreateKeys(ssl) < 0) |
|
1235
|
|
|
|
|
|
|
{ |
|
1236
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1237
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1238
|
|
|
|
|
|
|
} |
|
1239
|
0
|
|
|
|
|
|
ssl->hsState = SSL_HS_FINISHED; |
|
1240
|
0
|
0
|
|
|
|
|
if (sslActivateReadCipher(ssl) < 0) |
|
1241
|
|
|
|
|
|
|
{ |
|
1242
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1243
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1244
|
|
|
|
|
|
|
} |
|
1245
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = SESS_TICKET_STATE_INIT; |
|
1246
|
|
|
|
|
|
|
# ifdef USE_ANON_DH_CIPHER_SUITE |
|
1247
|
|
|
|
|
|
|
/* Anon DH could be in SERVER_KEY_EXCHANGE state */ |
|
1248
|
|
|
|
|
|
|
} |
|
1249
|
0
|
0
|
|
|
|
|
else if ((ssl->flags & SSL_FLAGS_ANON_CIPHER) && |
|
|
|
0
|
|
|
|
|
|
|
1250
|
0
|
0
|
|
|
|
|
(ssl->hsState == SSL_HS_SERVER_KEY_EXCHANGE) && ssl->sid && |
|
|
|
0
|
|
|
|
|
|
|
1251
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState == SESS_TICKET_STATE_IN_LIMBO) |
|
1252
|
|
|
|
|
|
|
{ |
|
1253
|
|
|
|
|
|
|
/* Do all the things that should have been done earlier */ |
|
1254
|
0
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_RESUMED; |
|
1255
|
|
|
|
|
|
|
# ifdef USE_MATRIXSSL_STATS |
|
1256
|
|
|
|
|
|
|
matrixsslUpdateStat(ssl, RESUMPTIONS_STAT, 1); |
|
1257
|
|
|
|
|
|
|
# endif |
|
1258
|
0
|
0
|
|
|
|
|
if (sslCreateKeys(ssl) < 0) |
|
1259
|
|
|
|
|
|
|
{ |
|
1260
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1261
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1262
|
|
|
|
|
|
|
} |
|
1263
|
0
|
|
|
|
|
|
ssl->hsState = SSL_HS_FINISHED; |
|
1264
|
0
|
0
|
|
|
|
|
if (sslActivateReadCipher(ssl) < 0) |
|
1265
|
|
|
|
|
|
|
{ |
|
1266
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1267
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1268
|
|
|
|
|
|
|
} |
|
1269
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = SESS_TICKET_STATE_INIT; |
|
1270
|
|
|
|
|
|
|
# endif /* USE_ANON_DH_CIPHER_SUITE */ |
|
1271
|
|
|
|
|
|
|
# ifdef USE_PSK_CIPHER_SUITE |
|
1272
|
|
|
|
|
|
|
/* PSK could be in SERVER_KEY_EXCHANGE state */ |
|
1273
|
|
|
|
|
|
|
} |
|
1274
|
0
|
0
|
|
|
|
|
else if ((ssl->flags & SSL_FLAGS_PSK_CIPHER) && |
|
|
|
0
|
|
|
|
|
|
|
1275
|
0
|
0
|
|
|
|
|
(ssl->hsState == SSL_HS_SERVER_KEY_EXCHANGE) && ssl->sid && |
|
|
|
0
|
|
|
|
|
|
|
1276
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState == SESS_TICKET_STATE_IN_LIMBO) |
|
1277
|
|
|
|
|
|
|
{ |
|
1278
|
|
|
|
|
|
|
/* Do all the things that should have been done earlier */ |
|
1279
|
0
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_RESUMED; |
|
1280
|
|
|
|
|
|
|
# ifdef USE_MATRIXSSL_STATS |
|
1281
|
|
|
|
|
|
|
matrixsslUpdateStat(ssl, RESUMPTIONS_STAT, 1); |
|
1282
|
|
|
|
|
|
|
# endif |
|
1283
|
0
|
0
|
|
|
|
|
if (sslCreateKeys(ssl) < 0) |
|
1284
|
|
|
|
|
|
|
{ |
|
1285
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1286
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1287
|
|
|
|
|
|
|
} |
|
1288
|
0
|
|
|
|
|
|
ssl->hsState = SSL_HS_FINISHED; |
|
1289
|
0
|
0
|
|
|
|
|
if (sslActivateReadCipher(ssl) < 0) |
|
1290
|
|
|
|
|
|
|
{ |
|
1291
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1292
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1293
|
|
|
|
|
|
|
} |
|
1294
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = SESS_TICKET_STATE_INIT; |
|
1295
|
|
|
|
|
|
|
# endif /* USE_PSK_CIPHER_SUITE */ |
|
1296
|
|
|
|
|
|
|
} |
|
1297
|
|
|
|
|
|
|
else |
|
1298
|
|
|
|
|
|
|
{ |
|
1299
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
1300
|
|
|
|
|
|
|
psTraceIntInfo("Invalid CipherSpec order: %d\n", ssl->hsState); |
|
1301
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1302
|
|
|
|
|
|
|
} |
|
1303
|
|
|
|
|
|
|
#else |
|
1304
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
1305
|
|
|
|
|
|
|
psTraceIntInfo("Invalid CipherSpec order: %d\n", ssl->hsState); |
|
1306
|
|
|
|
|
|
|
goto encodeResponse; |
|
1307
|
|
|
|
|
|
|
#endif |
|
1308
|
|
|
|
|
|
|
} |
|
1309
|
2119
|
|
|
|
|
|
ssl->decState = SSL_HS_CCC; |
|
1310
|
2119
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
1311
|
|
|
|
|
|
|
|
|
1312
|
|
|
|
|
|
|
case SSL_RECORD_TYPE_ALERT: |
|
1313
|
|
|
|
|
|
|
/* |
|
1314
|
|
|
|
|
|
|
Decoded an alert |
|
1315
|
|
|
|
|
|
|
1 byte alert level (warning or fatal) |
|
1316
|
|
|
|
|
|
|
1 byte alert description corresponding to SSL_ALERT_* |
|
1317
|
|
|
|
|
|
|
*/ |
|
1318
|
91
|
50
|
|
|
|
|
if (pend - p < 2) |
|
1319
|
|
|
|
|
|
|
{ |
|
1320
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
1321
|
|
|
|
|
|
|
psTraceInfo("Error in length of alert record\n"); |
|
1322
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1323
|
|
|
|
|
|
|
} |
|
1324
|
91
|
|
|
|
|
|
*alertLevel = *p; p++; |
|
1325
|
91
|
|
|
|
|
|
*alertDescription = *p; p++; |
|
1326
|
91
|
|
|
|
|
|
*len = 2; |
|
1327
|
|
|
|
|
|
|
#ifdef USE_SSL_HANDSHAKE_MSG_TRACE |
|
1328
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_SERVER) |
|
1329
|
|
|
|
|
|
|
{ |
|
1330
|
|
|
|
|
|
|
psTraceHs(">>> Server"); |
|
1331
|
|
|
|
|
|
|
} |
|
1332
|
|
|
|
|
|
|
else |
|
1333
|
|
|
|
|
|
|
{ |
|
1334
|
|
|
|
|
|
|
psTraceHs(">>> Client"); |
|
1335
|
|
|
|
|
|
|
} |
|
1336
|
|
|
|
|
|
|
if (*alertDescription == SSL_ALERT_CLOSE_NOTIFY) |
|
1337
|
|
|
|
|
|
|
{ |
|
1338
|
|
|
|
|
|
|
psTraceHs(" parsing ALERT (CLOSE_NOTIFY) message\n"); |
|
1339
|
|
|
|
|
|
|
} |
|
1340
|
|
|
|
|
|
|
else |
|
1341
|
|
|
|
|
|
|
{ |
|
1342
|
|
|
|
|
|
|
psTraceHs(" parsing ALERT message\n"); |
|
1343
|
|
|
|
|
|
|
} |
|
1344
|
|
|
|
|
|
|
#endif |
|
1345
|
|
|
|
|
|
|
psTraceIntInfo("Received alert %d\n", (int32) (*alertDescription)); |
|
1346
|
|
|
|
|
|
|
/* |
|
1347
|
|
|
|
|
|
|
If the alert is fatal, or is a close message (usually a warning), |
|
1348
|
|
|
|
|
|
|
flag the session with ERROR so it cannot be used anymore. |
|
1349
|
|
|
|
|
|
|
Caller can decide whether or not to close on other warnings. |
|
1350
|
|
|
|
|
|
|
*/ |
|
1351
|
91
|
100
|
|
|
|
|
if (*alertLevel == SSL_ALERT_LEVEL_FATAL) |
|
1352
|
|
|
|
|
|
|
{ |
|
1353
|
90
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_ERROR; |
|
1354
|
|
|
|
|
|
|
} |
|
1355
|
91
|
100
|
|
|
|
|
if (*alertDescription == SSL_ALERT_CLOSE_NOTIFY) |
|
1356
|
|
|
|
|
|
|
{ |
|
1357
|
1
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_CLOSED; |
|
1358
|
|
|
|
|
|
|
} |
|
1359
|
91
|
|
|
|
|
|
*buf = c; |
|
1360
|
91
|
|
|
|
|
|
ssl->decState = SSL_HS_ALERT; |
|
1361
|
91
|
|
|
|
|
|
return SSL_ALERT; |
|
1362
|
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
case SSL_RECORD_TYPE_HANDSHAKE: |
|
1364
|
|
|
|
|
|
|
/* |
|
1365
|
|
|
|
|
|
|
We've got one or more handshake messages in the record data. |
|
1366
|
|
|
|
|
|
|
The handshake parsing function will take care of all messages |
|
1367
|
|
|
|
|
|
|
and return an error if there is any problem. |
|
1368
|
|
|
|
|
|
|
If there is a response to be sent (either a return handshake |
|
1369
|
|
|
|
|
|
|
or an error alert, send it). If the message was parsed, but no |
|
1370
|
|
|
|
|
|
|
response is needed, loop up and try to parse another message |
|
1371
|
|
|
|
|
|
|
*/ |
|
1372
|
|
|
|
|
|
|
#ifdef USE_CERT_CHAIN_PARSING |
|
1373
|
|
|
|
|
|
|
if (ssl->rec.partial) |
|
1374
|
|
|
|
|
|
|
{ |
|
1375
|
|
|
|
|
|
|
if (ssl->rec.hsBytesParsed == 0) |
|
1376
|
|
|
|
|
|
|
{ |
|
1377
|
|
|
|
|
|
|
/* |
|
1378
|
|
|
|
|
|
|
Account for the SSL record header for first pass |
|
1379
|
|
|
|
|
|
|
*/ |
|
1380
|
|
|
|
|
|
|
ssl->rec.hsBytesParsed = ssl->recordHeadLen; |
|
1381
|
|
|
|
|
|
|
} |
|
1382
|
|
|
|
|
|
|
} |
|
1383
|
|
|
|
|
|
|
#endif |
|
1384
|
8738
|
|
|
|
|
|
rc = parseSSLHandshake(ssl, (char *) p, (uint32) (pend - p)); |
|
1385
|
|
|
|
|
|
|
/* If the entire fragment is present, the parse has occured */ |
|
1386
|
8738
|
50
|
|
|
|
|
if (ssl->fragMessage != NULL) |
|
1387
|
|
|
|
|
|
|
{ |
|
1388
|
0
|
0
|
|
|
|
|
if (ssl->fragIndex == ssl->fragTotal) |
|
1389
|
|
|
|
|
|
|
{ |
|
1390
|
0
|
|
|
|
|
|
psFree(ssl->fragMessage, ssl->hsPool); |
|
1391
|
0
|
|
|
|
|
|
ssl->fragMessage = NULL; |
|
1392
|
0
|
|
|
|
|
|
ssl->fragIndex = ssl->fragTotal = 0; |
|
1393
|
|
|
|
|
|
|
} |
|
1394
|
|
|
|
|
|
|
} |
|
1395
|
8738
|
|
|
|
|
|
switch (rc) |
|
1396
|
|
|
|
|
|
|
{ |
|
1397
|
|
|
|
|
|
|
case MATRIXSSL_SUCCESS: |
|
1398
|
5382
|
|
|
|
|
|
*remaining = *len - (c - origbuf); |
|
1399
|
5382
|
|
|
|
|
|
*buf = c; |
|
1400
|
5382
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
1401
|
|
|
|
|
|
|
|
|
1402
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
1403
|
|
|
|
|
|
|
case DTLS_RETRANSMIT: |
|
1404
|
|
|
|
|
|
|
/* The idea here is to only return retransmit if |
|
1405
|
|
|
|
|
|
|
we are seeing the final message in the inbuf as repeat. Otherwise |
|
1406
|
|
|
|
|
|
|
the next msg right in this flight might be able to move our state |
|
1407
|
|
|
|
|
|
|
forward without a resend. */ |
|
1408
|
|
|
|
|
|
|
*remaining = *len - (c - origbuf); |
|
1409
|
|
|
|
|
|
|
*buf = c; |
|
1410
|
|
|
|
|
|
|
if (*remaining == 0) |
|
1411
|
|
|
|
|
|
|
{ |
|
1412
|
|
|
|
|
|
|
return DTLS_RETRANSMIT; |
|
1413
|
|
|
|
|
|
|
} |
|
1414
|
|
|
|
|
|
|
else |
|
1415
|
|
|
|
|
|
|
{ |
|
1416
|
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
1417
|
|
|
|
|
|
|
} |
|
1418
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
1419
|
|
|
|
|
|
|
|
|
1420
|
|
|
|
|
|
|
case SSL_PROCESS_DATA: |
|
1421
|
|
|
|
|
|
|
/* |
|
1422
|
|
|
|
|
|
|
We're here when we've processed an SSL header that requires |
|
1423
|
|
|
|
|
|
|
a response. In all cases (except FALSE START), we would not |
|
1424
|
|
|
|
|
|
|
expect to have any data remaining in the incoming buffer, since |
|
1425
|
|
|
|
|
|
|
the peer would be waiting for our response. |
|
1426
|
|
|
|
|
|
|
*/ |
|
1427
|
|
|
|
|
|
|
#ifdef ENABLE_FALSE_START |
|
1428
|
3266
|
50
|
|
|
|
|
if (c < origbuf + *len) |
|
1429
|
|
|
|
|
|
|
{ |
|
1430
|
|
|
|
|
|
|
/* |
|
1431
|
|
|
|
|
|
|
If there's still incoming data in the buffer, it could be |
|
1432
|
|
|
|
|
|
|
FALSE START app data immediately after the FINISHED message, |
|
1433
|
|
|
|
|
|
|
and before we've had a chance to encode and send our |
|
1434
|
|
|
|
|
|
|
CHANGE_CIPHER_SPEC and FINISHED message. We hack around |
|
1435
|
|
|
|
|
|
|
some values to support this case. |
|
1436
|
|
|
|
|
|
|
http://tools.ietf.org/html/draft-bmoeller-tls-falsestart-00 |
|
1437
|
|
|
|
|
|
|
*/ |
|
1438
|
0
|
0
|
|
|
|
|
if (*c == SSL_RECORD_TYPE_APPLICATION_DATA && |
|
|
|
0
|
|
|
|
|
|
|
1439
|
0
|
0
|
|
|
|
|
ssl->hsState == SSL_HS_DONE && |
|
1440
|
0
|
|
|
|
|
|
(ssl->flags & SSL_FLAGS_SERVER)) |
|
1441
|
|
|
|
|
|
|
{ |
|
1442
|
|
|
|
|
|
|
psTraceHs(">>> Server buffering FALSE START APPLICATION_DATA\n"); |
|
1443
|
0
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_FALSE_START; |
|
1444
|
0
|
|
|
|
|
|
*remaining = *len - (c - origbuf); |
|
1445
|
0
|
|
|
|
|
|
*buf = c; |
|
1446
|
|
|
|
|
|
|
} |
|
1447
|
|
|
|
|
|
|
else |
|
1448
|
|
|
|
|
|
|
{ |
|
1449
|
|
|
|
|
|
|
/* |
|
1450
|
|
|
|
|
|
|
Implies successful parse of supposed last message in |
|
1451
|
|
|
|
|
|
|
flight so check for the corner cases and reset the |
|
1452
|
|
|
|
|
|
|
buffer to start to write response |
|
1453
|
|
|
|
|
|
|
*/ |
|
1454
|
|
|
|
|
|
|
#endif |
|
1455
|
0
|
0
|
|
|
|
|
if (*c == SSL_RECORD_TYPE_APPLICATION_DATA && |
|
|
|
0
|
|
|
|
|
|
|
1456
|
0
|
0
|
|
|
|
|
ssl->hsState == SSL_HS_DONE && |
|
1457
|
0
|
|
|
|
|
|
(ssl->flags & SSL_FLAGS_SERVER)) |
|
1458
|
|
|
|
|
|
|
{ |
|
1459
|
|
|
|
|
|
|
/* If this asserts, try defining ENABLE_FALSE_START */ |
|
1460
|
0
|
0
|
|
|
|
|
psAssert(origbuf + *len == c); |
|
1461
|
0
|
|
|
|
|
|
*buf = origbuf; |
|
1462
|
|
|
|
|
|
|
} |
|
1463
|
0
|
0
|
|
|
|
|
else if (*c == SSL_RECORD_TYPE_APPLICATION_DATA && |
|
|
|
0
|
|
|
|
|
|
|
1464
|
0
|
0
|
|
|
|
|
ssl->hsState == SSL_HS_HELLO_REQUEST && |
|
1465
|
0
|
|
|
|
|
|
(c < (origbuf + *len))) |
|
1466
|
|
|
|
|
|
|
{ |
|
1467
|
|
|
|
|
|
|
/* message tacked on to end of HELLO_REQUEST. Very |
|
1468
|
|
|
|
|
|
|
complicated scenario for the state machine and |
|
1469
|
|
|
|
|
|
|
API so we're going to ignore the HELLO_REQUEST |
|
1470
|
|
|
|
|
|
|
(fine by the specification) and give precedence to |
|
1471
|
|
|
|
|
|
|
the app data. This backup flag data was set aside |
|
1472
|
|
|
|
|
|
|
in sslResetContext when the HELLO_REQUEST was |
|
1473
|
|
|
|
|
|
|
received */ |
|
1474
|
0
|
|
|
|
|
|
*buf = c; |
|
1475
|
|
|
|
|
|
|
#ifdef USE_CLIENT_SIDE_SSL |
|
1476
|
0
|
|
|
|
|
|
ssl->sec.anon = ssl->anonBk; |
|
1477
|
0
|
|
|
|
|
|
ssl->flags = ssl->flagsBk; |
|
1478
|
0
|
|
|
|
|
|
ssl->bFlags = ssl->bFlagsBk; |
|
1479
|
|
|
|
|
|
|
#endif |
|
1480
|
0
|
|
|
|
|
|
ssl->hsState = SSL_HS_DONE; |
|
1481
|
0
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
1482
|
|
|
|
|
|
|
} |
|
1483
|
|
|
|
|
|
|
else |
|
1484
|
|
|
|
|
|
|
{ |
|
1485
|
|
|
|
|
|
|
/* If this asserts, please report the values of the |
|
1486
|
|
|
|
|
|
|
* c byte and ssl->hsState to support */ |
|
1487
|
0
|
0
|
|
|
|
|
psAssert(origbuf + *len == c); |
|
1488
|
0
|
|
|
|
|
|
*buf = origbuf; |
|
1489
|
|
|
|
|
|
|
} |
|
1490
|
|
|
|
|
|
|
#ifdef ENABLE_FALSE_START |
|
1491
|
|
|
|
|
|
|
} |
|
1492
|
|
|
|
|
|
|
} |
|
1493
|
|
|
|
|
|
|
else |
|
1494
|
|
|
|
|
|
|
{ |
|
1495
|
3266
|
|
|
|
|
|
*buf = origbuf; |
|
1496
|
|
|
|
|
|
|
} |
|
1497
|
|
|
|
|
|
|
#endif |
|
1498
|
3266
|
|
|
|
|
|
goto encodeResponse; |
|
1499
|
|
|
|
|
|
|
|
|
1500
|
|
|
|
|
|
|
case MATRIXSSL_ERROR: |
|
1501
|
|
|
|
|
|
|
case SSL_MEM_ERROR: |
|
1502
|
90
|
50
|
|
|
|
|
if (ssl->err == SSL_ALERT_NONE) |
|
1503
|
|
|
|
|
|
|
{ |
|
1504
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1505
|
|
|
|
|
|
|
} |
|
1506
|
90
|
|
|
|
|
|
goto encodeResponse; |
|
1507
|
|
|
|
|
|
|
default: |
|
1508
|
|
|
|
|
|
|
psTraceIntInfo("Unknown return %d from parseSSLHandshake!\n", rc); |
|
1509
|
0
|
0
|
|
|
|
|
if (ssl->err == SSL_ALERT_NONE) |
|
1510
|
|
|
|
|
|
|
{ |
|
1511
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
1512
|
|
|
|
|
|
|
} |
|
1513
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1514
|
|
|
|
|
|
|
} |
|
1515
|
|
|
|
|
|
|
break; |
|
1516
|
|
|
|
|
|
|
|
|
1517
|
|
|
|
|
|
|
case SSL_RECORD_TYPE_APPLICATION_DATA: |
|
1518
|
|
|
|
|
|
|
/* |
|
1519
|
|
|
|
|
|
|
Data is in the out buffer, let user handle it |
|
1520
|
|
|
|
|
|
|
Don't allow application data until handshake is complete, and we are |
|
1521
|
|
|
|
|
|
|
secure. It is ok to let application data through on the client |
|
1522
|
|
|
|
|
|
|
if we are in the SERVER_HELLO state because this could mean that |
|
1523
|
|
|
|
|
|
|
the client has sent a CLIENT_HELLO message for a rehandshake |
|
1524
|
|
|
|
|
|
|
and is awaiting reply. |
|
1525
|
|
|
|
|
|
|
*/ |
|
1526
|
4123
|
50
|
|
|
|
|
if ((ssl->hsState != SSL_HS_DONE && ssl->hsState != SSL_HS_SERVER_HELLO) |
|
|
|
0
|
|
|
|
|
|
|
1527
|
4123
|
50
|
|
|
|
|
|| !(ssl->flags & SSL_FLAGS_READ_SECURE)) |
|
1528
|
|
|
|
|
|
|
{ |
|
1529
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
1530
|
|
|
|
|
|
|
psTraceIntInfo("Incomplete handshake: %d\n", ssl->hsState); |
|
1531
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1532
|
|
|
|
|
|
|
} |
|
1533
|
|
|
|
|
|
|
/* |
|
1534
|
|
|
|
|
|
|
Insitu for application data is more tricky than it is for SSL handshake |
|
1535
|
|
|
|
|
|
|
messages. This is because there is never going to be any 'out' data |
|
1536
|
|
|
|
|
|
|
for handshake messages until the final record of a flight is parsed. |
|
1537
|
|
|
|
|
|
|
Whereas application data necessarily has an 'out' for every 'in' |
|
1538
|
|
|
|
|
|
|
record because it is the decrypted data of the 'in'. So, the managed |
|
1539
|
|
|
|
|
|
|
cases result anytime there is more than 1 app record in the 'in' buffer |
|
1540
|
|
|
|
|
|
|
where the insitu must hold BOTH a decrypted buffer and the next |
|
1541
|
|
|
|
|
|
|
encrypted record. |
|
1542
|
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
Create so that: |
|
1544
|
|
|
|
|
|
|
. buf points to start of any remaining unencrypted data |
|
1545
|
|
|
|
|
|
|
. start is length of remaining encrypted data yet to decode |
|
1546
|
|
|
|
|
|
|
. len is length of unencrypted data ready for user processing |
|
1547
|
|
|
|
|
|
|
|
|
1548
|
|
|
|
|
|
|
*/ |
|
1549
|
4123
|
|
|
|
|
|
*buf = c; |
|
1550
|
4123
|
|
|
|
|
|
*remaining = *len - (c - origbuf); |
|
1551
|
4123
|
|
|
|
|
|
*len = mac - origbuf; |
|
1552
|
|
|
|
|
|
|
/* |
|
1553
|
|
|
|
|
|
|
SECURITY - If the mac is at the current out->end, then there is no data |
|
1554
|
|
|
|
|
|
|
in the record. These records are valid, but are usually not sent by |
|
1555
|
|
|
|
|
|
|
the application layer protocol. Rather, they are initiated within the |
|
1556
|
|
|
|
|
|
|
remote SSL protocol implementation to avoid some types of attacks when |
|
1557
|
|
|
|
|
|
|
using block ciphers. For more information see: |
|
1558
|
|
|
|
|
|
|
http://www.openssl.org/~bodo/tls-cbc.txt |
|
1559
|
|
|
|
|
|
|
|
|
1560
|
|
|
|
|
|
|
SECURITY - Returning blank messages has the potential |
|
1561
|
|
|
|
|
|
|
for denial of service, because we are not changing the state of the |
|
1562
|
|
|
|
|
|
|
system in any way when processing these messages, (although the upper |
|
1563
|
|
|
|
|
|
|
level protocol may). To counteract this, we maintain a counter |
|
1564
|
|
|
|
|
|
|
that we share with other types of ignored messages. If too many in a |
|
1565
|
|
|
|
|
|
|
row occur, an alert will be sent and the connection closed. |
|
1566
|
|
|
|
|
|
|
We implement this as a leaky bucket, so if a non-blank message comes |
|
1567
|
|
|
|
|
|
|
in, the ignored message count is decremented, ensuring that we only |
|
1568
|
|
|
|
|
|
|
error on a large number of consecutive blanks. |
|
1569
|
|
|
|
|
|
|
*/ |
|
1570
|
4123
|
50
|
|
|
|
|
if (ctStart == mac) |
|
1571
|
|
|
|
|
|
|
{ |
|
1572
|
0
|
0
|
|
|
|
|
if (ssl->ignoredMessageCount++ >= SSL_MAX_IGNORED_MESSAGE_COUNT) |
|
1573
|
|
|
|
|
|
|
{ |
|
1574
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
1575
|
|
|
|
|
|
|
psTraceIntInfo("Exceeded limit on ignored messages: %d\n", |
|
1576
|
|
|
|
|
|
|
SSL_MAX_IGNORED_MESSAGE_COUNT); |
|
1577
|
0
|
|
|
|
|
|
goto encodeResponse; |
|
1578
|
|
|
|
|
|
|
} |
|
1579
|
|
|
|
|
|
|
} |
|
1580
|
4123
|
50
|
|
|
|
|
else if (ssl->ignoredMessageCount > 0) |
|
1581
|
|
|
|
|
|
|
{ |
|
1582
|
0
|
|
|
|
|
|
ssl->ignoredMessageCount--; |
|
1583
|
|
|
|
|
|
|
} |
|
1584
|
|
|
|
|
|
|
#ifdef USE_MATRIXSSL_STATS |
|
1585
|
|
|
|
|
|
|
matrixsslUpdateStat(ssl, STAT_PT_DATA_RECV, *len); |
|
1586
|
|
|
|
|
|
|
#endif |
|
1587
|
4123
|
|
|
|
|
|
ssl->decState = SSL_HS_DONE; |
|
1588
|
4123
|
|
|
|
|
|
return SSL_PROCESS_DATA; |
|
1589
|
|
|
|
|
|
|
|
|
1590
|
|
|
|
|
|
|
default: |
|
1591
|
|
|
|
|
|
|
/* Falls to error below */ |
|
1592
|
0
|
|
|
|
|
|
break; |
|
1593
|
|
|
|
|
|
|
} |
|
1594
|
|
|
|
|
|
|
/* |
|
1595
|
|
|
|
|
|
|
Should not get here under normal operation |
|
1596
|
|
|
|
|
|
|
*/ |
|
1597
|
|
|
|
|
|
|
psTraceIntInfo("Invalid record type in matrixSslDecode: %d\n", |
|
1598
|
|
|
|
|
|
|
ssl->rec.type); |
|
1599
|
0
|
|
|
|
|
|
*error = PS_PROTOCOL_FAIL; |
|
1600
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
1601
|
|
|
|
|
|
|
|
|
1602
|
|
|
|
|
|
|
encodeResponse: |
|
1603
|
|
|
|
|
|
|
/* |
|
1604
|
|
|
|
|
|
|
We decoded a record that needs a response, either a handshake response |
|
1605
|
|
|
|
|
|
|
or an alert if we've detected an error. |
|
1606
|
|
|
|
|
|
|
*/ |
|
1607
|
|
|
|
|
|
|
# ifdef ENABLE_FALSE_START |
|
1608
|
3360
|
50
|
|
|
|
|
if ((ssl->flags & SSL_FLAGS_FALSE_START) && *buf != origbuf) |
|
|
|
0
|
|
|
|
|
|
|
1609
|
|
|
|
|
|
|
{ |
|
1610
|
|
|
|
|
|
|
/* |
|
1611
|
|
|
|
|
|
|
Encode the output into ssl->outbuf in this case, rather than back |
|
1612
|
|
|
|
|
|
|
into origbuf, since there is still valid data in origbuf that |
|
1613
|
|
|
|
|
|
|
needs to be decoded later. |
|
1614
|
|
|
|
|
|
|
Other places in this function we do not reference the ssl inbuf |
|
1615
|
|
|
|
|
|
|
or outbuf directly, but this was the cleanest way for this hack. |
|
1616
|
|
|
|
|
|
|
Caller must test to see if *buf has been modified if |
|
1617
|
|
|
|
|
|
|
ssl->flags & SSL_FLAGS_FALSE_START |
|
1618
|
|
|
|
|
|
|
*/ |
|
1619
|
0
|
|
|
|
|
|
tmpout.buf = tmpout.start = tmpout.end = ssl->outbuf + ssl->outlen; |
|
1620
|
0
|
|
|
|
|
|
tmpout.size = ssl->outsize - ssl->outlen; |
|
1621
|
0
|
|
|
|
|
|
memset(origbuf, 0x0, (*buf - origbuf)); /* SECURITY (see below) */ |
|
1622
|
|
|
|
|
|
|
} |
|
1623
|
|
|
|
|
|
|
else |
|
1624
|
|
|
|
|
|
|
{ |
|
1625
|
|
|
|
|
|
|
# endif |
|
1626
|
3360
|
50
|
|
|
|
|
psAssert(origbuf == *buf); |
|
1627
|
3360
|
|
|
|
|
|
tmpout.buf = tmpout.end = tmpout.start = origbuf; |
|
1628
|
3360
|
|
|
|
|
|
tmpout.size = size; |
|
1629
|
|
|
|
|
|
|
|
|
1630
|
|
|
|
|
|
|
# if defined(USE_HARDWARE_CRYPTO_RECORD) || defined(USE_HARDWARE_CRYPTO_PKA) || defined(USE_EXT_CERTIFICATE_VERIFY_SIGNING) |
|
1631
|
|
|
|
|
|
|
if (!(ssl->hwflags & SSL_HWFLAGS_PENDING_PKA_W) && |
|
1632
|
|
|
|
|
|
|
!(ssl->hwflags & SSL_HWFLAGS_PENDING_FLIGHT_W)) |
|
1633
|
|
|
|
|
|
|
{ |
|
1634
|
|
|
|
|
|
|
/* If we are coming back through on a pending, this data is GOLD */ |
|
1635
|
|
|
|
|
|
|
memset(tmpout.buf, 0x0, tmpout.size); |
|
1636
|
|
|
|
|
|
|
} |
|
1637
|
|
|
|
|
|
|
# else |
|
1638
|
|
|
|
|
|
|
/* |
|
1639
|
|
|
|
|
|
|
SECURITY - Clear the decoded incoming record from outbuf before encoding |
|
1640
|
|
|
|
|
|
|
the response into outbuf. |
|
1641
|
|
|
|
|
|
|
*/ |
|
1642
|
3360
|
|
|
|
|
|
memset(tmpout.buf, 0x0, tmpout.size); |
|
1643
|
|
|
|
|
|
|
# endif |
|
1644
|
|
|
|
|
|
|
|
|
1645
|
|
|
|
|
|
|
# ifdef ENABLE_FALSE_START |
|
1646
|
|
|
|
|
|
|
} |
|
1647
|
|
|
|
|
|
|
# endif |
|
1648
|
|
|
|
|
|
|
|
|
1649
|
|
|
|
|
|
|
# ifdef USE_CLIENT_SIDE_SSL |
|
1650
|
3360
|
50
|
|
|
|
|
if (ssl->hsState == SSL_HS_HELLO_REQUEST) |
|
1651
|
|
|
|
|
|
|
{ |
|
1652
|
0
|
|
|
|
|
|
memset(&options, 0x0, sizeof(sslSessOpts_t)); |
|
1653
|
|
|
|
|
|
|
/* |
|
1654
|
|
|
|
|
|
|
Don't clear the session info. If receiving a HELLO_REQUEST from a |
|
1655
|
|
|
|
|
|
|
MatrixSSL enabled server the determination on whether to reuse the |
|
1656
|
|
|
|
|
|
|
session is made on that side, so always send the current session |
|
1657
|
|
|
|
|
|
|
*/ |
|
1658
|
0
|
|
|
|
|
|
rc = matrixSslEncodeClientHello(ssl, &tmpout, 0, 0, requiredLen, NULL, |
|
1659
|
|
|
|
|
|
|
&options); |
|
1660
|
|
|
|
|
|
|
} |
|
1661
|
|
|
|
|
|
|
else |
|
1662
|
|
|
|
|
|
|
{ |
|
1663
|
|
|
|
|
|
|
# endif /* USE_CLIENT_SIDE_SSL */ |
|
1664
|
3360
|
|
|
|
|
|
rc = sslEncodeResponse(ssl, &tmpout, requiredLen); |
|
1665
|
|
|
|
|
|
|
# ifdef USE_CLIENT_SIDE_SSL |
|
1666
|
|
|
|
|
|
|
} |
|
1667
|
|
|
|
|
|
|
# endif /* USE_CLIENT_SIDE_SSL */ |
|
1668
|
3360
|
|
|
|
|
|
*alertDescription = SSL_ALERT_NONE; |
|
1669
|
3360
|
100
|
|
|
|
|
if (rc == MATRIXSSL_SUCCESS) |
|
1670
|
|
|
|
|
|
|
{ |
|
1671
|
3356
|
100
|
|
|
|
|
if (ssl->err != SSL_ALERT_NONE) |
|
1672
|
|
|
|
|
|
|
{ |
|
1673
|
|
|
|
|
|
|
/* We know this is always a fatal alert due to an error in |
|
1674
|
|
|
|
|
|
|
message parsing or creation so flag this session as error */ |
|
1675
|
90
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_ERROR; |
|
1676
|
|
|
|
|
|
|
/* |
|
1677
|
|
|
|
|
|
|
If tmpbuf has data, it is an alert that needs to be sent so let |
|
1678
|
|
|
|
|
|
|
it fall through. Not sure how we would ever not have data in tmpout |
|
1679
|
|
|
|
|
|
|
*/ |
|
1680
|
90
|
50
|
|
|
|
|
if (tmpout.buf == tmpout.end) |
|
1681
|
|
|
|
|
|
|
{ |
|
1682
|
|
|
|
|
|
|
psTraceInfo("Unexpected data\n"); |
|
1683
|
0
|
|
|
|
|
|
*error = PS_PROTOCOL_FAIL; |
|
1684
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
1685
|
|
|
|
|
|
|
} |
|
1686
|
90
|
|
|
|
|
|
*alertDescription = (unsigned char) ssl->err; |
|
1687
|
90
|
|
|
|
|
|
*alertLevel = SSL_ALERT_LEVEL_FATAL; |
|
1688
|
|
|
|
|
|
|
} |
|
1689
|
|
|
|
|
|
|
# ifdef ENABLE_FALSE_START |
|
1690
|
3356
|
50
|
|
|
|
|
if ((ssl->flags & SSL_FLAGS_FALSE_START) && *buf != origbuf) |
|
|
|
0
|
|
|
|
|
|
|
1691
|
|
|
|
|
|
|
{ |
|
1692
|
|
|
|
|
|
|
/* Update outlen with the data we added */ |
|
1693
|
0
|
|
|
|
|
|
ssl->outlen += tmpout.end - tmpout.buf; |
|
1694
|
|
|
|
|
|
|
} |
|
1695
|
|
|
|
|
|
|
else |
|
1696
|
|
|
|
|
|
|
{ |
|
1697
|
|
|
|
|
|
|
# endif |
|
1698
|
3356
|
|
|
|
|
|
*remaining = 0; |
|
1699
|
3356
|
|
|
|
|
|
*len = tmpout.end - tmpout.buf; |
|
1700
|
|
|
|
|
|
|
# ifdef ENABLE_FALSE_START |
|
1701
|
|
|
|
|
|
|
} |
|
1702
|
|
|
|
|
|
|
# endif |
|
1703
|
3356
|
|
|
|
|
|
return SSL_SEND_RESPONSE; |
|
1704
|
|
|
|
|
|
|
} |
|
1705
|
4
|
50
|
|
|
|
|
if (rc == SSL_FULL) |
|
1706
|
|
|
|
|
|
|
{ |
|
1707
|
|
|
|
|
|
|
# ifdef ENABLE_FALSE_START |
|
1708
|
|
|
|
|
|
|
/* We don't support growing outbuf in the false start case */ |
|
1709
|
4
|
50
|
|
|
|
|
if (*buf != origbuf) |
|
1710
|
|
|
|
|
|
|
{ |
|
1711
|
0
|
0
|
|
|
|
|
psAssert(rc != SSL_FULL); |
|
1712
|
0
|
|
|
|
|
|
*error = rc; |
|
1713
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
1714
|
|
|
|
|
|
|
} |
|
1715
|
|
|
|
|
|
|
# endif |
|
1716
|
4
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_NEED_ENCODE; |
|
1717
|
4
|
|
|
|
|
|
*len = 0; /* No data left to decode */ |
|
1718
|
|
|
|
|
|
|
/* requiredLen is set by sslEncode Response or ClientHello above */ |
|
1719
|
4
|
|
|
|
|
|
return SSL_FULL; |
|
1720
|
|
|
|
|
|
|
} |
|
1721
|
0
|
0
|
|
|
|
|
psAssert(rc < 0); |
|
1722
|
0
|
|
|
|
|
|
*error = rc; |
|
1723
|
17143
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
1724
|
|
|
|
|
|
|
} |
|
1725
|
|
|
|
|
|
|
|
|
1726
|
|
|
|
|
|
|
#ifdef LUCKY13 |
|
1727
|
|
|
|
|
|
|
/* Return the number of additional MAC compressions that are needed to blind |
|
1728
|
|
|
|
|
|
|
the padding/hmac logic for thwarting Lucky 13 style attacks |
|
1729
|
|
|
|
|
|
|
*/ |
|
1730
|
3
|
|
|
|
|
|
static int32 addCompressCount(ssl_t *ssl, int32 padLen) |
|
1731
|
|
|
|
|
|
|
{ |
|
1732
|
|
|
|
|
|
|
int32 l1, l2, c1, c2, len; |
|
1733
|
|
|
|
|
|
|
|
|
1734
|
3
|
|
|
|
|
|
c1 = c2 = 0; |
|
1735
|
3
|
|
|
|
|
|
len = ssl->rec.len; |
|
1736
|
|
|
|
|
|
|
|
|
1737
|
|
|
|
|
|
|
# ifdef USE_TLS_1_1 |
|
1738
|
3
|
50
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_TLS_1_1) |
|
1739
|
|
|
|
|
|
|
{ |
|
1740
|
3
|
|
|
|
|
|
len -= ssl->deBlockSize; /* skip explicit IV */ |
|
1741
|
|
|
|
|
|
|
} |
|
1742
|
|
|
|
|
|
|
# endif |
|
1743
|
3
|
|
|
|
|
|
l1 = 13 + len - ssl->deMacSize; |
|
1744
|
3
|
|
|
|
|
|
l2 = 13 + len - padLen - 1 - ssl->deMacSize; |
|
1745
|
|
|
|
|
|
|
|
|
1746
|
3
|
50
|
|
|
|
|
if (ssl->deMacSize == SHA1_HASH_SIZE || ssl->deMacSize == SHA256_HASH_SIZE) |
|
|
|
0
|
|
|
|
|
|
|
1747
|
|
|
|
|
|
|
{ |
|
1748
|
3
|
50
|
|
|
|
|
while (l1 > 64) |
|
1749
|
|
|
|
|
|
|
{ |
|
1750
|
0
|
|
|
|
|
|
c1++; l1 -= 64; |
|
1751
|
|
|
|
|
|
|
} |
|
1752
|
3
|
50
|
|
|
|
|
if (l1 > 56) |
|
1753
|
|
|
|
|
|
|
{ |
|
1754
|
0
|
|
|
|
|
|
c1++; |
|
1755
|
|
|
|
|
|
|
} |
|
1756
|
3
|
50
|
|
|
|
|
while (l2 > 64) |
|
1757
|
|
|
|
|
|
|
{ |
|
1758
|
0
|
|
|
|
|
|
c2++; l2 -= 64; |
|
1759
|
|
|
|
|
|
|
} |
|
1760
|
3
|
50
|
|
|
|
|
if (l2 > 56) |
|
1761
|
|
|
|
|
|
|
{ |
|
1762
|
0
|
|
|
|
|
|
c2++; |
|
1763
|
|
|
|
|
|
|
} |
|
1764
|
|
|
|
|
|
|
# ifdef USE_SHA384 |
|
1765
|
|
|
|
|
|
|
} |
|
1766
|
0
|
0
|
|
|
|
|
else if (ssl->deMacSize == SHA384_HASH_SIZE) |
|
1767
|
|
|
|
|
|
|
{ |
|
1768
|
0
|
0
|
|
|
|
|
while (l1 > 128) |
|
1769
|
|
|
|
|
|
|
{ |
|
1770
|
0
|
|
|
|
|
|
c1++; l1 -= 128; |
|
1771
|
|
|
|
|
|
|
} |
|
1772
|
0
|
0
|
|
|
|
|
if (l1 > 112) |
|
1773
|
|
|
|
|
|
|
{ |
|
1774
|
0
|
|
|
|
|
|
c1++; |
|
1775
|
|
|
|
|
|
|
} |
|
1776
|
0
|
0
|
|
|
|
|
while (l2 > 128) |
|
1777
|
|
|
|
|
|
|
{ |
|
1778
|
0
|
|
|
|
|
|
c2++; l2 -= 128; |
|
1779
|
|
|
|
|
|
|
} |
|
1780
|
0
|
0
|
|
|
|
|
if (l2 > 112) |
|
1781
|
|
|
|
|
|
|
{ |
|
1782
|
0
|
|
|
|
|
|
c2++; |
|
1783
|
|
|
|
|
|
|
} |
|
1784
|
|
|
|
|
|
|
|
|
1785
|
|
|
|
|
|
|
# endif |
|
1786
|
|
|
|
|
|
|
} |
|
1787
|
|
|
|
|
|
|
|
|
1788
|
3
|
|
|
|
|
|
return c1 - c2; |
|
1789
|
|
|
|
|
|
|
} |
|
1790
|
|
|
|
|
|
|
#endif /* LUCKY13 */ |
|
1791
|
|
|
|
|
|
|
|
|
1792
|
|
|
|
|
|
|
/******************************************************************************/ |
|
1793
|
|
|
|
|
|
|
/* |
|
1794
|
|
|
|
|
|
|
The workhorse for parsing handshake messages. Also enforces the state |
|
1795
|
|
|
|
|
|
|
machine for proper ordering of handshake messages. |
|
1796
|
|
|
|
|
|
|
Parameters: |
|
1797
|
|
|
|
|
|
|
ssl - ssl context |
|
1798
|
|
|
|
|
|
|
inbuf - buffer to read handshake message from |
|
1799
|
|
|
|
|
|
|
len - data length for the current ssl record. The ssl record |
|
1800
|
|
|
|
|
|
|
can contain multiple handshake messages, so we may need to parse |
|
1801
|
|
|
|
|
|
|
them all here. |
|
1802
|
|
|
|
|
|
|
Return: |
|
1803
|
|
|
|
|
|
|
MATRIXSSL_SUCCESS |
|
1804
|
|
|
|
|
|
|
SSL_PROCESS_DATA |
|
1805
|
|
|
|
|
|
|
MATRIXSSL_ERROR - see ssl->err for details |
|
1806
|
|
|
|
|
|
|
MEM_FAIL |
|
1807
|
|
|
|
|
|
|
-MATRIXSSL_ERROR and MEM_FAIL will be caught and an alert sent. If you |
|
1808
|
|
|
|
|
|
|
want to specifiy the alert the set ss->err. Otherwise it will |
|
1809
|
|
|
|
|
|
|
be an INTERNAL_ERROR |
|
1810
|
|
|
|
|
|
|
*/ |
|
1811
|
8738
|
|
|
|
|
|
static int32 parseSSLHandshake(ssl_t *ssl, char *inbuf, uint32 len) |
|
1812
|
|
|
|
|
|
|
{ |
|
1813
|
|
|
|
|
|
|
unsigned char *c, *end; |
|
1814
|
|
|
|
|
|
|
unsigned char hsType; |
|
1815
|
|
|
|
|
|
|
int32 rc; |
|
1816
|
|
|
|
|
|
|
uint32 hsLen; |
|
1817
|
|
|
|
|
|
|
unsigned char hsMsgHash[SHA512_HASH_SIZE]; |
|
1818
|
|
|
|
|
|
|
|
|
1819
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
1820
|
|
|
|
|
|
|
uint32 fragLen; |
|
1821
|
|
|
|
|
|
|
int32 msn, fragOffset, j; |
|
1822
|
|
|
|
|
|
|
# ifdef USE_CLIENT_SIDE_SSL |
|
1823
|
|
|
|
|
|
|
int32 hvreqMinVer, hvreqMajVer; |
|
1824
|
|
|
|
|
|
|
# endif |
|
1825
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
1826
|
|
|
|
|
|
|
|
|
1827
|
|
|
|
|
|
|
|
|
1828
|
8738
|
|
|
|
|
|
rc = MATRIXSSL_SUCCESS; |
|
1829
|
8738
|
|
|
|
|
|
c = (unsigned char *) inbuf; |
|
1830
|
8738
|
|
|
|
|
|
end = (unsigned char *) (inbuf + len); |
|
1831
|
|
|
|
|
|
|
|
|
1832
|
|
|
|
|
|
|
/* Immediately check if we are working with a fragmented message. */ |
|
1833
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
1834
|
|
|
|
|
|
|
msn = 0; |
|
1835
|
|
|
|
|
|
|
/* This is the non-DTLS fragmentation handler */ |
|
1836
|
|
|
|
|
|
|
if (!(ssl->flags & SSL_FLAGS_DTLS)) |
|
1837
|
|
|
|
|
|
|
{ |
|
1838
|
|
|
|
|
|
|
#endif |
|
1839
|
8738
|
50
|
|
|
|
|
if (ssl->fragMessage != NULL) |
|
1840
|
|
|
|
|
|
|
{ |
|
1841
|
|
|
|
|
|
|
/* Just borrowing hsLen variable. Is the rest here or do we still |
|
1842
|
|
|
|
|
|
|
need more? */ |
|
1843
|
0
|
|
|
|
|
|
hsLen = min((uint32) (end - c), ssl->fragTotal - ssl->fragIndex); |
|
1844
|
0
|
|
|
|
|
|
memcpy(ssl->fragMessage + ssl->fragIndex, c, hsLen); |
|
1845
|
0
|
|
|
|
|
|
ssl->fragIndex += hsLen; |
|
1846
|
0
|
|
|
|
|
|
c += hsLen; |
|
1847
|
|
|
|
|
|
|
|
|
1848
|
0
|
0
|
|
|
|
|
if (ssl->fragIndex == ssl->fragTotal) |
|
1849
|
|
|
|
|
|
|
{ |
|
1850
|
0
|
|
|
|
|
|
c = ssl->fragMessage + ssl->hshakeHeadLen; |
|
1851
|
0
|
|
|
|
|
|
end = ssl->fragMessage + ssl->fragTotal; |
|
1852
|
0
|
|
|
|
|
|
hsLen = ssl->fragTotal - ssl->hshakeHeadLen; |
|
1853
|
0
|
|
|
|
|
|
goto SKIP_HSHEADER_PARSE; |
|
1854
|
|
|
|
|
|
|
} |
|
1855
|
|
|
|
|
|
|
else |
|
1856
|
|
|
|
|
|
|
{ |
|
1857
|
0
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
1858
|
|
|
|
|
|
|
} |
|
1859
|
|
|
|
|
|
|
} |
|
1860
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
1861
|
|
|
|
|
|
|
} |
|
1862
|
|
|
|
|
|
|
#endif |
|
1863
|
|
|
|
|
|
|
|
|
1864
|
|
|
|
|
|
|
#ifdef USE_CERT_CHAIN_PARSING |
|
1865
|
|
|
|
|
|
|
if (ssl->rec.partial && (ssl->rec.hsBytesParsed > ssl->recordHeadLen)) |
|
1866
|
|
|
|
|
|
|
{ |
|
1867
|
|
|
|
|
|
|
goto SKIP_HSHEADER_PARSE; |
|
1868
|
|
|
|
|
|
|
} |
|
1869
|
|
|
|
|
|
|
#endif /* USE_CERT_CHAIN_PARSING */ |
|
1870
|
|
|
|
|
|
|
|
|
1871
|
|
|
|
|
|
|
parseHandshake: |
|
1872
|
8738
|
50
|
|
|
|
|
if (end - c < 1) |
|
1873
|
|
|
|
|
|
|
{ |
|
1874
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
1875
|
|
|
|
|
|
|
psTraceInfo("Invalid length of handshake message 1\n"); |
|
1876
|
|
|
|
|
|
|
psTraceIntInfo("%d\n", (int32) (end - c)); |
|
1877
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
1878
|
|
|
|
|
|
|
} |
|
1879
|
8738
|
|
|
|
|
|
hsType = *c; c++; |
|
1880
|
|
|
|
|
|
|
|
|
1881
|
|
|
|
|
|
|
#ifndef SSL_REHANDSHAKES_ENABLED |
|
1882
|
|
|
|
|
|
|
/* |
|
1883
|
|
|
|
|
|
|
If all rehandshaking is disabled, just catch that here and alert. |
|
1884
|
|
|
|
|
|
|
*/ |
|
1885
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_SERVER) |
|
1886
|
|
|
|
|
|
|
{ |
|
1887
|
|
|
|
|
|
|
if (hsType == SSL_HS_CLIENT_HELLO && ssl->hsState == SSL_HS_DONE) |
|
1888
|
|
|
|
|
|
|
{ |
|
1889
|
|
|
|
|
|
|
psTraceInfo("Closing conn with client. Rehandshake is disabled\n"); |
|
1890
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_NO_RENEGOTIATION; |
|
1891
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
1892
|
|
|
|
|
|
|
} |
|
1893
|
|
|
|
|
|
|
} |
|
1894
|
|
|
|
|
|
|
else |
|
1895
|
|
|
|
|
|
|
{ |
|
1896
|
|
|
|
|
|
|
if (hsType == SSL_HS_HELLO_REQUEST && ssl->hsState == SSL_HS_DONE) |
|
1897
|
|
|
|
|
|
|
{ |
|
1898
|
|
|
|
|
|
|
psTraceInfo("Closing conn with server. Rehandshake is disabled\n"); |
|
1899
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_NO_RENEGOTIATION; |
|
1900
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
1901
|
|
|
|
|
|
|
} |
|
1902
|
|
|
|
|
|
|
} |
|
1903
|
|
|
|
|
|
|
#endif /* SSL_REHANDSHAKES_ENABLED */ |
|
1904
|
|
|
|
|
|
|
|
|
1905
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
1906
|
|
|
|
|
|
|
/* |
|
1907
|
|
|
|
|
|
|
The MSN helpes keep the state machine sane prior to passing through to |
|
1908
|
|
|
|
|
|
|
the hsType exceptions because if they are received out-of-order it could |
|
1909
|
|
|
|
|
|
|
choose the wrong handshake type (client auth, rehandshake, or standard) |
|
1910
|
|
|
|
|
|
|
|
|
1911
|
|
|
|
|
|
|
It is mostly important to deal with future messages here because those |
|
1912
|
|
|
|
|
|
|
are the ones that may bypass us to the wrong handshake type. Duplicates |
|
1913
|
|
|
|
|
|
|
are handled below. |
|
1914
|
|
|
|
|
|
|
*/ |
|
1915
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
1916
|
|
|
|
|
|
|
{ |
|
1917
|
|
|
|
|
|
|
if (end - c < 5) |
|
1918
|
|
|
|
|
|
|
{ |
|
1919
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
1920
|
|
|
|
|
|
|
psTraceInfo("Invalid length of handshake message\n"); |
|
1921
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
1922
|
|
|
|
|
|
|
} |
|
1923
|
|
|
|
|
|
|
msn = c[3] << 8; |
|
1924
|
|
|
|
|
|
|
msn += c[4]; |
|
1925
|
|
|
|
|
|
|
if (msn > (ssl->lastMsn + 1)) |
|
1926
|
|
|
|
|
|
|
{ |
|
1927
|
|
|
|
|
|
|
psTraceIntDtls("Ignoring future handshake msg %d\n", hsType); |
|
1928
|
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
1929
|
|
|
|
|
|
|
} |
|
1930
|
|
|
|
|
|
|
else if (msn != 0 && ssl->lastMsn >= msn) |
|
1931
|
|
|
|
|
|
|
{ |
|
1932
|
|
|
|
|
|
|
psTraceIntDtls("Ignoring already seen handshake msg %d\n", hsType); |
|
1933
|
|
|
|
|
|
|
return DTLS_RETRANSMIT; |
|
1934
|
|
|
|
|
|
|
} |
|
1935
|
|
|
|
|
|
|
} |
|
1936
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
1937
|
|
|
|
|
|
|
|
|
1938
|
|
|
|
|
|
|
/* |
|
1939
|
|
|
|
|
|
|
hsType is the received handshake type and ssl->hsState is the expected |
|
1940
|
|
|
|
|
|
|
handshake type. If it doesn't match, there are some possible cases |
|
1941
|
|
|
|
|
|
|
that are not errors. These are checked here. |
|
1942
|
|
|
|
|
|
|
*/ |
|
1943
|
8738
|
100
|
|
|
|
|
if (hsType != ssl->hsState && |
|
|
|
50
|
|
|
|
|
|
|
1944
|
7
|
50
|
|
|
|
|
(hsType != SSL_HS_CLIENT_HELLO || ssl->hsState != SSL_HS_DONE)) |
|
1945
|
|
|
|
|
|
|
{ |
|
1946
|
|
|
|
|
|
|
|
|
1947
|
|
|
|
|
|
|
/* |
|
1948
|
|
|
|
|
|
|
A mismatch is possible in the client authentication case. |
|
1949
|
|
|
|
|
|
|
The optional CERTIFICATE_REQUEST may be appearing instead of |
|
1950
|
|
|
|
|
|
|
SERVER_HELLO_DONE. |
|
1951
|
|
|
|
|
|
|
*/ |
|
1952
|
0
|
0
|
|
|
|
|
if ((hsType == SSL_HS_CERTIFICATE_REQUEST) && |
|
|
|
0
|
|
|
|
|
|
|
1953
|
0
|
|
|
|
|
|
(ssl->hsState == SSL_HS_SERVER_HELLO_DONE)) |
|
1954
|
|
|
|
|
|
|
{ |
|
1955
|
|
|
|
|
|
|
/* |
|
1956
|
|
|
|
|
|
|
This is where the client is first aware of requested client |
|
1957
|
|
|
|
|
|
|
authentication so we set the flag here. |
|
1958
|
|
|
|
|
|
|
|
|
1959
|
|
|
|
|
|
|
*/ |
|
1960
|
0
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_CLIENT_AUTH; |
|
1961
|
0
|
|
|
|
|
|
ssl->hsState = SSL_HS_CERTIFICATE_REQUEST; |
|
1962
|
0
|
|
|
|
|
|
goto hsStateDetermined; |
|
1963
|
|
|
|
|
|
|
} |
|
1964
|
|
|
|
|
|
|
/* |
|
1965
|
|
|
|
|
|
|
Another possible mismatch allowed is for a HELLO_REQEST message. |
|
1966
|
|
|
|
|
|
|
Indicates a rehandshake initiated from the server. |
|
1967
|
|
|
|
|
|
|
*/ |
|
1968
|
0
|
0
|
|
|
|
|
if ((hsType == SSL_HS_HELLO_REQUEST) && |
|
|
|
0
|
|
|
|
|
|
|
1969
|
0
|
0
|
|
|
|
|
(ssl->hsState == SSL_HS_DONE) && |
|
1970
|
0
|
|
|
|
|
|
!(ssl->flags & SSL_FLAGS_SERVER)) |
|
1971
|
|
|
|
|
|
|
{ |
|
1972
|
0
|
|
|
|
|
|
sslResetContext(ssl); |
|
1973
|
0
|
|
|
|
|
|
ssl->hsState = hsType; |
|
1974
|
0
|
|
|
|
|
|
goto hsStateDetermined; |
|
1975
|
|
|
|
|
|
|
} |
|
1976
|
|
|
|
|
|
|
|
|
1977
|
|
|
|
|
|
|
/* Another possible mismatch is HELLO_REQUEST right after we sent |
|
1978
|
|
|
|
|
|
|
a re-handshake CLIENT_HELLO. Will ignore the request and |
|
1979
|
|
|
|
|
|
|
assume this was a timing issue and that the server will reply |
|
1980
|
|
|
|
|
|
|
to our CLIENT_HELLO when it is received */ |
|
1981
|
0
|
0
|
|
|
|
|
if ((hsType == SSL_HS_HELLO_REQUEST) && |
|
|
|
0
|
|
|
|
|
|
|
1982
|
0
|
0
|
|
|
|
|
(ssl->hsState == SSL_HS_SERVER_HELLO) && |
|
1983
|
0
|
0
|
|
|
|
|
(ssl->flags & SSL_FLAGS_READ_SECURE) && |
|
1984
|
0
|
0
|
|
|
|
|
(ssl->flags & SSL_FLAGS_WRITE_SECURE) && |
|
1985
|
0
|
|
|
|
|
|
!(ssl->flags & SSL_FLAGS_SERVER)) |
|
1986
|
|
|
|
|
|
|
{ |
|
1987
|
|
|
|
|
|
|
/* There is no body to the message. Confirm this and exit happily |
|
1988
|
|
|
|
|
|
|
without changing state */ |
|
1989
|
0
|
0
|
|
|
|
|
if (end - c < 3) |
|
1990
|
|
|
|
|
|
|
{ |
|
1991
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
1992
|
|
|
|
|
|
|
psTraceInfo("Invalid length of handshake message 2\n"); |
|
1993
|
|
|
|
|
|
|
psTraceIntInfo("%d\n", (int32) (end - c)); |
|
1994
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
1995
|
|
|
|
|
|
|
} |
|
1996
|
0
|
|
|
|
|
|
hsLen = *c << 16; c++; |
|
1997
|
0
|
|
|
|
|
|
hsLen += *c << 8; c++; |
|
1998
|
0
|
|
|
|
|
|
hsLen += *c; c++; |
|
1999
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
2000
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
2001
|
|
|
|
|
|
|
{ |
|
2002
|
|
|
|
|
|
|
if (end - c < 8) |
|
2003
|
|
|
|
|
|
|
{ |
|
2004
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
2005
|
|
|
|
|
|
|
psTraceInfo("Invalid length of handshake message\n"); |
|
2006
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2007
|
|
|
|
|
|
|
} |
|
2008
|
|
|
|
|
|
|
c += 8; |
|
2009
|
|
|
|
|
|
|
} |
|
2010
|
|
|
|
|
|
|
#endif |
|
2011
|
|
|
|
|
|
|
#ifdef SSL_REHANDSHAKES_ENABLED |
|
2012
|
0
|
0
|
|
|
|
|
if (ssl->rehandshakeCount <= 0) |
|
2013
|
|
|
|
|
|
|
{ |
|
2014
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_NO_RENEGOTIATION; |
|
2015
|
|
|
|
|
|
|
psTraceInfo("Server re-handshaking denied. Out of credits.\n"); |
|
2016
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2017
|
|
|
|
|
|
|
} |
|
2018
|
0
|
|
|
|
|
|
ssl->rehandshakeCount--; |
|
2019
|
|
|
|
|
|
|
#endif |
|
2020
|
0
|
0
|
|
|
|
|
if (hsLen == 0) |
|
2021
|
|
|
|
|
|
|
{ |
|
2022
|
0
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
2023
|
|
|
|
|
|
|
} |
|
2024
|
|
|
|
|
|
|
else |
|
2025
|
|
|
|
|
|
|
{ |
|
2026
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2027
|
|
|
|
|
|
|
} |
|
2028
|
|
|
|
|
|
|
} |
|
2029
|
|
|
|
|
|
|
|
|
2030
|
|
|
|
|
|
|
#ifdef USE_STATELESS_SESSION_TICKETS |
|
2031
|
|
|
|
|
|
|
/* Another possible mismatch allowed is for a |
|
2032
|
|
|
|
|
|
|
SSL_HS_NEW_SESSION_TICKET message. */ |
|
2033
|
0
|
0
|
|
|
|
|
if ((hsType == SSL_HS_NEW_SESSION_TICKET) && |
|
|
|
0
|
|
|
|
|
|
|
2034
|
0
|
0
|
|
|
|
|
(ssl->hsState == SSL_HS_FINISHED) && ssl->sid && |
|
|
|
0
|
|
|
|
|
|
|
2035
|
0
|
0
|
|
|
|
|
(ssl->sid->sessionTicketState == SESS_TICKET_STATE_RECVD_EXT) && |
|
2036
|
0
|
|
|
|
|
|
!(ssl->flags & SSL_FLAGS_SERVER)) |
|
2037
|
|
|
|
|
|
|
{ |
|
2038
|
0
|
|
|
|
|
|
ssl->hsState = hsType; |
|
2039
|
0
|
|
|
|
|
|
goto hsStateDetermined; |
|
2040
|
|
|
|
|
|
|
} |
|
2041
|
|
|
|
|
|
|
|
|
2042
|
|
|
|
|
|
|
#endif /* USE_STATELESS_SESSION_TICKETS */ |
|
2043
|
|
|
|
|
|
|
|
|
2044
|
|
|
|
|
|
|
#ifdef USE_OCSP |
|
2045
|
|
|
|
|
|
|
/* Another possible mismatch is server didn't send the optional |
|
2046
|
|
|
|
|
|
|
CERTIFICATE_STATUS message. Unfortunate this was not specified |
|
2047
|
|
|
|
|
|
|
to be strictly handled in the status_request extensions */ |
|
2048
|
0
|
0
|
|
|
|
|
if (ssl->hsState == SSL_HS_CERTIFICATE_STATUS) |
|
2049
|
|
|
|
|
|
|
{ |
|
2050
|
|
|
|
|
|
|
/* The two valid states from here are identical |
|
2051
|
|
|
|
|
|
|
checking of the next state calculation at the end of the |
|
2052
|
|
|
|
|
|
|
SSL_HS_CERTIFICATE message handling. |
|
2053
|
|
|
|
|
|
|
(But in reverse order due to the precedence of DHE mode.) |
|
2054
|
|
|
|
|
|
|
*/ |
|
2055
|
|
|
|
|
|
|
# ifdef USE_OCSP_MUST_STAPLE |
|
2056
|
|
|
|
|
|
|
/* This is the case where the server sent a reply to our |
|
2057
|
|
|
|
|
|
|
status_request extension but didn't actually send the |
|
2058
|
|
|
|
|
|
|
handshake message. If we are in a MUST state, time to fail */ |
|
2059
|
|
|
|
|
|
|
psTraceInfo("Expecting CERTIFICATE_STATUS message\n"); |
|
2060
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
2061
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2062
|
|
|
|
|
|
|
# else |
|
2063
|
|
|
|
|
|
|
# ifdef USE_DHE_CIPHER_SUITE |
|
2064
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DHE_KEY_EXCH && |
|
2065
|
|
|
|
|
|
|
hsType == SSL_HS_SERVER_KEY_EXCHANGE) |
|
2066
|
|
|
|
|
|
|
{ |
|
2067
|
|
|
|
|
|
|
ssl->hsState = hsType; |
|
2068
|
|
|
|
|
|
|
goto hsStateDetermined; |
|
2069
|
|
|
|
|
|
|
} |
|
2070
|
|
|
|
|
|
|
# endif /* USE_DHE_CIPHER_SUITE */ |
|
2071
|
|
|
|
|
|
|
if (hsType == SSL_HS_SERVER_HELLO_DONE) |
|
2072
|
|
|
|
|
|
|
{ |
|
2073
|
|
|
|
|
|
|
ssl->hsState = hsType; |
|
2074
|
|
|
|
|
|
|
goto hsStateDetermined; |
|
2075
|
|
|
|
|
|
|
} |
|
2076
|
|
|
|
|
|
|
# endif /* USE_OCSP_MUST_STAPLE */ |
|
2077
|
|
|
|
|
|
|
} |
|
2078
|
|
|
|
|
|
|
#endif /* USE_OCSP */ |
|
2079
|
|
|
|
|
|
|
|
|
2080
|
|
|
|
|
|
|
#ifdef USE_PSK_CIPHER_SUITE |
|
2081
|
|
|
|
|
|
|
/* |
|
2082
|
|
|
|
|
|
|
PSK suites are probably not including SERVER_KEY_EXCHANGE message |
|
2083
|
|
|
|
|
|
|
*/ |
|
2084
|
0
|
0
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_PSK_CIPHER) |
|
2085
|
|
|
|
|
|
|
{ |
|
2086
|
0
|
0
|
|
|
|
|
if ((hsType == SSL_HS_SERVER_HELLO_DONE) && |
|
|
|
0
|
|
|
|
|
|
|
2087
|
0
|
|
|
|
|
|
(ssl->hsState == SSL_HS_SERVER_KEY_EXCHANGE)) |
|
2088
|
|
|
|
|
|
|
{ |
|
2089
|
|
|
|
|
|
|
# ifdef USE_DHE_CIPHER_SUITE |
|
2090
|
|
|
|
|
|
|
/* |
|
2091
|
|
|
|
|
|
|
DH kex suites must be sending a SERVER_KEY_EXCHANGE message |
|
2092
|
|
|
|
|
|
|
*/ |
|
2093
|
0
|
0
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DHE_KEY_EXCH) |
|
2094
|
|
|
|
|
|
|
{ |
|
2095
|
|
|
|
|
|
|
psTraceIntInfo("Expecting SKE message: %d\n", hsType); |
|
2096
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
2097
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2098
|
|
|
|
|
|
|
} |
|
2099
|
|
|
|
|
|
|
# endif /* USE_DHE_CIPHER_SUITE */ |
|
2100
|
0
|
|
|
|
|
|
ssl->hsState = hsType; |
|
2101
|
0
|
|
|
|
|
|
goto hsStateDetermined; |
|
2102
|
|
|
|
|
|
|
} |
|
2103
|
|
|
|
|
|
|
} |
|
2104
|
|
|
|
|
|
|
#endif /* USE_PSK_CIPHER_SUITE */ |
|
2105
|
|
|
|
|
|
|
|
|
2106
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
2107
|
|
|
|
|
|
|
/* |
|
2108
|
|
|
|
|
|
|
DTLS inserts an optional VERIFY_REQUEST back to clients |
|
2109
|
|
|
|
|
|
|
*/ |
|
2110
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
2111
|
|
|
|
|
|
|
{ |
|
2112
|
|
|
|
|
|
|
# ifdef USE_CLIENT_SIDE_SSL |
|
2113
|
|
|
|
|
|
|
if ((hsType == SSL_HS_HELLO_VERIFY_REQUEST) && |
|
2114
|
|
|
|
|
|
|
(ssl->hsState == SSL_HS_SERVER_HELLO)) |
|
2115
|
|
|
|
|
|
|
{ |
|
2116
|
|
|
|
|
|
|
/* However, if this is a retransmit and we've already parsed |
|
2117
|
|
|
|
|
|
|
the HELLO_VERIFY_REQUEST we can safely skip it */ |
|
2118
|
|
|
|
|
|
|
if (ssl->haveCookie == 0) |
|
2119
|
|
|
|
|
|
|
{ |
|
2120
|
|
|
|
|
|
|
ssl->hsState = hsType; |
|
2121
|
|
|
|
|
|
|
goto hsStateDetermined; |
|
2122
|
|
|
|
|
|
|
} |
|
2123
|
|
|
|
|
|
|
} |
|
2124
|
|
|
|
|
|
|
# endif |
|
2125
|
|
|
|
|
|
|
/* |
|
2126
|
|
|
|
|
|
|
A final MSN sanity test and handling of duplicate hello messages |
|
2127
|
|
|
|
|
|
|
*/ |
|
2128
|
|
|
|
|
|
|
if ((ssl->lastMsn + 1) == msn) |
|
2129
|
|
|
|
|
|
|
{ |
|
2130
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
2131
|
|
|
|
|
|
|
psTraceIntDtls("Correct MSN %d on unexpected HS msg ", msn); |
|
2132
|
|
|
|
|
|
|
psTraceIntDtls(" %d\n", hsType); |
|
2133
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2134
|
|
|
|
|
|
|
} |
|
2135
|
|
|
|
|
|
|
else if (ssl->lastMsn >= msn) |
|
2136
|
|
|
|
|
|
|
{ |
|
2137
|
|
|
|
|
|
|
psTraceDtls("IGNORING ALREADY SEEN HELLO HANDSHAKE MSG\n"); |
|
2138
|
|
|
|
|
|
|
return DTLS_RETRANSMIT; |
|
2139
|
|
|
|
|
|
|
} |
|
2140
|
|
|
|
|
|
|
} |
|
2141
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
2142
|
|
|
|
|
|
|
|
|
2143
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
2144
|
|
|
|
|
|
|
psTraceIntInfo("Out-of-order handshake message: %d\n", hsType); |
|
2145
|
|
|
|
|
|
|
psTraceIntInfo("Wanted: %d\n", ssl->hsState); |
|
2146
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2147
|
|
|
|
|
|
|
} |
|
2148
|
|
|
|
|
|
|
|
|
2149
|
|
|
|
|
|
|
hsStateDetermined: |
|
2150
|
8738
|
100
|
|
|
|
|
if (hsType == SSL_HS_CLIENT_HELLO) |
|
2151
|
|
|
|
|
|
|
{ |
|
2152
|
1149
|
|
|
|
|
|
sslInitHSHash(ssl); |
|
2153
|
1149
|
100
|
|
|
|
|
if (ssl->hsState == SSL_HS_DONE) |
|
2154
|
|
|
|
|
|
|
{ |
|
2155
|
|
|
|
|
|
|
# ifdef SSL_REHANDSHAKES_ENABLED |
|
2156
|
|
|
|
|
|
|
/* This is a 'leaky bucket' mechanism where each X bytes of data transfer gains |
|
2157
|
|
|
|
|
|
|
you a re-handshake credit. Prevents the DOS attack of repeat |
|
2158
|
|
|
|
|
|
|
re-handshake requests */ |
|
2159
|
7
|
50
|
|
|
|
|
if (ssl->rehandshakeCount <= 0) |
|
2160
|
|
|
|
|
|
|
{ |
|
2161
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_NO_RENEGOTIATION; |
|
2162
|
|
|
|
|
|
|
psTraceInfo("Client re-handshaking denied\n"); |
|
2163
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2164
|
|
|
|
|
|
|
} |
|
2165
|
7
|
|
|
|
|
|
ssl->rehandshakeBytes = 0; /* reset */ |
|
2166
|
7
|
|
|
|
|
|
ssl->rehandshakeCount--; |
|
2167
|
|
|
|
|
|
|
# endif /* SSL_REHANDSHAKES_ENABLED */ |
|
2168
|
|
|
|
|
|
|
/* Rehandshake. Server receiving client hello on existing connection */ |
|
2169
|
7
|
|
|
|
|
|
sslResetContext(ssl); |
|
2170
|
7
|
|
|
|
|
|
ssl->hsState = hsType; |
|
2171
|
|
|
|
|
|
|
} |
|
2172
|
|
|
|
|
|
|
} |
|
2173
|
|
|
|
|
|
|
|
|
2174
|
|
|
|
|
|
|
/* |
|
2175
|
|
|
|
|
|
|
We need to get a copy of the message hashes to compare to those sent |
|
2176
|
|
|
|
|
|
|
in the finished message (which does not include a hash of itself) |
|
2177
|
|
|
|
|
|
|
before we update the handshake hashes |
|
2178
|
|
|
|
|
|
|
*/ |
|
2179
|
8738
|
100
|
|
|
|
|
if (ssl->hsState == SSL_HS_FINISHED) |
|
2180
|
|
|
|
|
|
|
{ |
|
2181
|
2119
|
50
|
|
|
|
|
if (sslSnapshotHSHash(ssl, hsMsgHash, |
|
2182
|
2119
|
|
|
|
|
|
(ssl->flags & SSL_FLAGS_SERVER) ? 0 : SSL_FLAGS_SERVER) <= 0) |
|
2183
|
|
|
|
|
|
|
{ |
|
2184
|
|
|
|
|
|
|
psTraceInfo("Error snapshotting HS hash\n"); |
|
2185
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
2186
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2187
|
|
|
|
|
|
|
} |
|
2188
|
|
|
|
|
|
|
} |
|
2189
|
|
|
|
|
|
|
#ifdef USE_CLIENT_AUTH |
|
2190
|
8738
|
50
|
|
|
|
|
if (ssl->hsState == SSL_HS_CERTIFICATE_VERIFY) |
|
2191
|
|
|
|
|
|
|
{ |
|
2192
|
|
|
|
|
|
|
/* Same issue as above for client auth. Need a handshake snapshot |
|
2193
|
|
|
|
|
|
|
that doesn't include this message we are about to process */ |
|
2194
|
0
|
0
|
|
|
|
|
if (sslSnapshotHSHash(ssl, hsMsgHash, -1) <= 0) |
|
2195
|
|
|
|
|
|
|
{ |
|
2196
|
|
|
|
|
|
|
psTraceInfo("Error snapshotting HS hash\n"); |
|
2197
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
2198
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2199
|
|
|
|
|
|
|
} |
|
2200
|
|
|
|
|
|
|
} |
|
2201
|
|
|
|
|
|
|
#endif /* USE_CLIENT_AUTH */ |
|
2202
|
|
|
|
|
|
|
|
|
2203
|
|
|
|
|
|
|
/* |
|
2204
|
|
|
|
|
|
|
Process the handshake header and update the ongoing handshake hash |
|
2205
|
|
|
|
|
|
|
SSLv3: |
|
2206
|
|
|
|
|
|
|
1 byte type |
|
2207
|
|
|
|
|
|
|
3 bytes length |
|
2208
|
|
|
|
|
|
|
SSLv2: |
|
2209
|
|
|
|
|
|
|
1 byte type |
|
2210
|
|
|
|
|
|
|
*/ |
|
2211
|
8738
|
50
|
|
|
|
|
if (ssl->rec.majVer >= SSL3_MAJ_VER) |
|
2212
|
|
|
|
|
|
|
{ |
|
2213
|
8738
|
50
|
|
|
|
|
if (end - c < 3) |
|
2214
|
|
|
|
|
|
|
{ |
|
2215
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
2216
|
|
|
|
|
|
|
psTraceInfo("Invalid length of handshake message 2\n"); |
|
2217
|
|
|
|
|
|
|
psTraceIntInfo("%d\n", (int32) (end - c)); |
|
2218
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2219
|
|
|
|
|
|
|
} |
|
2220
|
8738
|
|
|
|
|
|
hsLen = *c << 16; c++; |
|
2221
|
8738
|
|
|
|
|
|
hsLen += *c << 8; c++; |
|
2222
|
8738
|
|
|
|
|
|
hsLen += *c; c++; |
|
2223
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
2224
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
2225
|
|
|
|
|
|
|
{ |
|
2226
|
|
|
|
|
|
|
if (end - c < 8) |
|
2227
|
|
|
|
|
|
|
{ |
|
2228
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
2229
|
|
|
|
|
|
|
psTraceInfo("Invalid length of handshake message\n"); |
|
2230
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2231
|
|
|
|
|
|
|
} |
|
2232
|
|
|
|
|
|
|
msn = *c << 8; c++; |
|
2233
|
|
|
|
|
|
|
msn += *c; c++; |
|
2234
|
|
|
|
|
|
|
fragOffset = *c << 16; c++; |
|
2235
|
|
|
|
|
|
|
fragOffset += *c << 8; c++; |
|
2236
|
|
|
|
|
|
|
fragOffset += *c; c++; |
|
2237
|
|
|
|
|
|
|
fragLen = *c << 16; c++; |
|
2238
|
|
|
|
|
|
|
fragLen += *c << 8; c++; |
|
2239
|
|
|
|
|
|
|
fragLen += *c; c++; |
|
2240
|
|
|
|
|
|
|
if (fragLen != hsLen) |
|
2241
|
|
|
|
|
|
|
{ |
|
2242
|
|
|
|
|
|
|
/* |
|
2243
|
|
|
|
|
|
|
Have a fragmented message here. Allocate if first time |
|
2244
|
|
|
|
|
|
|
seen and assign msn. Can only deal with single fragmented |
|
2245
|
|
|
|
|
|
|
message at a time. |
|
2246
|
|
|
|
|
|
|
*/ |
|
2247
|
|
|
|
|
|
|
if (ssl->fragTotal == 0) |
|
2248
|
|
|
|
|
|
|
{ |
|
2249
|
|
|
|
|
|
|
/* |
|
2250
|
|
|
|
|
|
|
When all the fragments are received, this allocated pointer |
|
2251
|
|
|
|
|
|
|
becomes the 'c' parsing pointer. With all the potential |
|
2252
|
|
|
|
|
|
|
exit points in the parse code from all the different |
|
2253
|
|
|
|
|
|
|
messages it is not easy to free this on the fly. So, what |
|
2254
|
|
|
|
|
|
|
happens here is that each first message fragment that is |
|
2255
|
|
|
|
|
|
|
encountered will free the previous message if it exists |
|
2256
|
|
|
|
|
|
|
(not NULL). |
|
2257
|
|
|
|
|
|
|
|
|
2258
|
|
|
|
|
|
|
The final test for freeing this pointer will be in the |
|
2259
|
|
|
|
|
|
|
encoding (client) and decoding (server) of the Finished |
|
2260
|
|
|
|
|
|
|
message. At this point we know we can't possibly be |
|
2261
|
|
|
|
|
|
|
recieving any more fragments since the CCS and Finished |
|
2262
|
|
|
|
|
|
|
messages will never be so large that they would require |
|
2263
|
|
|
|
|
|
|
fragmenting. Also, the handshake pool is freed during |
|
2264
|
|
|
|
|
|
|
the encoding of Finished. |
|
2265
|
|
|
|
|
|
|
*/ |
|
2266
|
|
|
|
|
|
|
if (ssl->fragMessage != NULL ) |
|
2267
|
|
|
|
|
|
|
{ |
|
2268
|
|
|
|
|
|
|
psFree(ssl->fragMessage, ssl->hsPool); |
|
2269
|
|
|
|
|
|
|
ssl->fragMessage = NULL; |
|
2270
|
|
|
|
|
|
|
} |
|
2271
|
|
|
|
|
|
|
ssl->fragMessage = psMalloc(ssl->hsPool, hsLen); |
|
2272
|
|
|
|
|
|
|
if (ssl->fragMessage == NULL) |
|
2273
|
|
|
|
|
|
|
{ |
|
2274
|
|
|
|
|
|
|
return SSL_MEM_ERROR; |
|
2275
|
|
|
|
|
|
|
} |
|
2276
|
|
|
|
|
|
|
ssl->fragMsn = msn; |
|
2277
|
|
|
|
|
|
|
} |
|
2278
|
|
|
|
|
|
|
|
|
2279
|
|
|
|
|
|
|
if (ssl->fragMsn != msn) |
|
2280
|
|
|
|
|
|
|
{ |
|
2281
|
|
|
|
|
|
|
/* |
|
2282
|
|
|
|
|
|
|
Got a fragment from a different msg. Ignore |
|
2283
|
|
|
|
|
|
|
*/ |
|
2284
|
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
2285
|
|
|
|
|
|
|
} |
|
2286
|
|
|
|
|
|
|
/* |
|
2287
|
|
|
|
|
|
|
Still could be a duplicate fragment. Make sure we haven't |
|
2288
|
|
|
|
|
|
|
seen it before. If we haven't this routine also returns |
|
2289
|
|
|
|
|
|
|
the next open fragment header index for use below. |
|
2290
|
|
|
|
|
|
|
*/ |
|
2291
|
|
|
|
|
|
|
if ((rc = dtlsSeenFrag(ssl, fragOffset, &j)) == 1) |
|
2292
|
|
|
|
|
|
|
{ |
|
2293
|
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
2294
|
|
|
|
|
|
|
} |
|
2295
|
|
|
|
|
|
|
else if (rc == -1) /* MAX_FRAGMENTS exceeded */ |
|
2296
|
|
|
|
|
|
|
{ |
|
2297
|
|
|
|
|
|
|
dtlsInitFrag(ssl); /* init will free memory */ |
|
2298
|
|
|
|
|
|
|
if (ssl->fragMessage != NULL) |
|
2299
|
|
|
|
|
|
|
{ |
|
2300
|
|
|
|
|
|
|
psFree(ssl->fragMessage, ssl->hsPool); |
|
2301
|
|
|
|
|
|
|
ssl->fragMessage = NULL; |
|
2302
|
|
|
|
|
|
|
} |
|
2303
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
2304
|
|
|
|
|
|
|
psTraceIntDtls("Max fragment limit exceeded: %d\n", |
|
2305
|
|
|
|
|
|
|
MAX_FRAGMENTS); |
|
2306
|
|
|
|
|
|
|
return PS_LIMIT_FAIL; |
|
2307
|
|
|
|
|
|
|
} |
|
2308
|
|
|
|
|
|
|
/* |
|
2309
|
|
|
|
|
|
|
Need to save the hs header info aside as well so that we may |
|
2310
|
|
|
|
|
|
|
pass the fragments through the handshake hash mechanism in |
|
2311
|
|
|
|
|
|
|
the correct order. This list also keeps track of the fragment |
|
2312
|
|
|
|
|
|
|
offsets and lengths for the same reason. |
|
2313
|
|
|
|
|
|
|
*/ |
|
2314
|
|
|
|
|
|
|
ssl->fragHeaders[j].hsHeader = psMalloc(ssl->hsPool, |
|
2315
|
|
|
|
|
|
|
ssl->hshakeHeadLen); |
|
2316
|
|
|
|
|
|
|
if (ssl->fragHeaders[j].hsHeader == NULL) |
|
2317
|
|
|
|
|
|
|
{ |
|
2318
|
|
|
|
|
|
|
dtlsInitFrag(ssl); /* init to free */ |
|
2319
|
|
|
|
|
|
|
return SSL_MEM_ERROR; |
|
2320
|
|
|
|
|
|
|
} |
|
2321
|
|
|
|
|
|
|
memcpy(ssl->fragHeaders[j].hsHeader, c - ssl->hshakeHeadLen, |
|
2322
|
|
|
|
|
|
|
ssl->hshakeHeadLen); |
|
2323
|
|
|
|
|
|
|
ssl->fragHeaders[j].offset = fragOffset; |
|
2324
|
|
|
|
|
|
|
ssl->fragHeaders[j].fragLen = fragLen; |
|
2325
|
|
|
|
|
|
|
|
|
2326
|
|
|
|
|
|
|
ssl->fragTotal += fragLen; |
|
2327
|
|
|
|
|
|
|
memcpy(ssl->fragMessage + fragOffset, c, fragLen); |
|
2328
|
|
|
|
|
|
|
if (ssl->fragTotal != hsLen) |
|
2329
|
|
|
|
|
|
|
{ |
|
2330
|
|
|
|
|
|
|
|
|
2331
|
|
|
|
|
|
|
/* Don't have all the fragments yet */ |
|
2332
|
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
2333
|
|
|
|
|
|
|
} |
|
2334
|
|
|
|
|
|
|
c = ssl->fragMessage; |
|
2335
|
|
|
|
|
|
|
end = ssl->fragMessage + hsLen; |
|
2336
|
|
|
|
|
|
|
} |
|
2337
|
|
|
|
|
|
|
} |
|
2338
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
2339
|
|
|
|
|
|
|
#ifdef USE_CERT_CHAIN_PARSING |
|
2340
|
|
|
|
|
|
|
if (((uint32) (end - c) < hsLen) && !ssl->rec.partial) |
|
2341
|
|
|
|
|
|
|
{ |
|
2342
|
|
|
|
|
|
|
#else |
|
2343
|
8738
|
50
|
|
|
|
|
if ((uint32) (end - c) < hsLen) |
|
2344
|
|
|
|
|
|
|
{ |
|
2345
|
|
|
|
|
|
|
#endif |
|
2346
|
|
|
|
|
|
|
/* Support for fragmented handshake messages - non-DTLS */ |
|
2347
|
0
|
0
|
|
|
|
|
if (ssl->fragMessage == NULL) |
|
2348
|
|
|
|
|
|
|
{ |
|
2349
|
|
|
|
|
|
|
/* Initial indication there is a fragmented message */ |
|
2350
|
0
|
|
|
|
|
|
ssl->fragTotal = hsLen + ssl->hshakeHeadLen; |
|
2351
|
0
|
|
|
|
|
|
ssl->fragMessage = psMalloc(ssl->hsPool, ssl->fragTotal); |
|
2352
|
0
|
0
|
|
|
|
|
if (ssl->fragMessage == NULL) |
|
2353
|
|
|
|
|
|
|
{ |
|
2354
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
2355
|
|
|
|
|
|
|
psTraceInfo("Memory allocation error\n"); |
|
2356
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2357
|
|
|
|
|
|
|
} |
|
2358
|
0
|
|
|
|
|
|
ssl->fragIndex = (uint32) (end - c) + ssl->hshakeHeadLen; |
|
2359
|
0
|
|
|
|
|
|
memcpy(ssl->fragMessage, c - ssl->hshakeHeadLen, |
|
2360
|
0
|
|
|
|
|
|
ssl->fragIndex); |
|
2361
|
0
|
|
|
|
|
|
return MATRIXSSL_SUCCESS; |
|
2362
|
|
|
|
|
|
|
} |
|
2363
|
|
|
|
|
|
|
else |
|
2364
|
|
|
|
|
|
|
{ |
|
2365
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
2366
|
|
|
|
|
|
|
psTraceInfo("Invalid handshake length\n"); |
|
2367
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2368
|
|
|
|
|
|
|
} |
|
2369
|
|
|
|
|
|
|
} |
|
2370
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
2371
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
2372
|
|
|
|
|
|
|
{ |
|
2373
|
|
|
|
|
|
|
if (ssl->fragTotal > 0) |
|
2374
|
|
|
|
|
|
|
{ |
|
2375
|
|
|
|
|
|
|
/* Run the UpdateHash over the fragmented message */ |
|
2376
|
|
|
|
|
|
|
dtlsHsHashFragMsg(ssl); |
|
2377
|
|
|
|
|
|
|
dtlsInitFrag(ssl); |
|
2378
|
|
|
|
|
|
|
} |
|
2379
|
|
|
|
|
|
|
else |
|
2380
|
|
|
|
|
|
|
{ |
|
2381
|
|
|
|
|
|
|
/* |
|
2382
|
|
|
|
|
|
|
The DTLS case in which the message was not fragmented. |
|
2383
|
|
|
|
|
|
|
Not at all unusual to hit this |
|
2384
|
|
|
|
|
|
|
*/ |
|
2385
|
|
|
|
|
|
|
sslUpdateHSHash(ssl, c - ssl->hshakeHeadLen, |
|
2386
|
|
|
|
|
|
|
hsLen + ssl->hshakeHeadLen); |
|
2387
|
|
|
|
|
|
|
} |
|
2388
|
|
|
|
|
|
|
|
|
2389
|
|
|
|
|
|
|
} |
|
2390
|
|
|
|
|
|
|
else |
|
2391
|
|
|
|
|
|
|
{ |
|
2392
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
2393
|
|
|
|
|
|
|
SKIP_HSHEADER_PARSE: |
|
2394
|
|
|
|
|
|
|
|
|
2395
|
|
|
|
|
|
|
#ifdef USE_CERT_CHAIN_PARSING |
|
2396
|
|
|
|
|
|
|
if (ssl->rec.partial) |
|
2397
|
|
|
|
|
|
|
{ |
|
2398
|
|
|
|
|
|
|
/* |
|
2399
|
|
|
|
|
|
|
Length of partial certificate records are being managed |
|
2400
|
|
|
|
|
|
|
manually with ssl->rec.len. The first pass will need to |
|
2401
|
|
|
|
|
|
|
include the record header in the hash. |
|
2402
|
|
|
|
|
|
|
*/ |
|
2403
|
|
|
|
|
|
|
if (ssl->rec.hsBytesHashed == 0) |
|
2404
|
|
|
|
|
|
|
{ |
|
2405
|
|
|
|
|
|
|
sslUpdateHSHash(ssl, c - ssl->hshakeHeadLen, ssl->rec.len); |
|
2406
|
|
|
|
|
|
|
} |
|
2407
|
|
|
|
|
|
|
else |
|
2408
|
|
|
|
|
|
|
{ |
|
2409
|
|
|
|
|
|
|
sslUpdateHSHash(ssl, c, ssl->rec.len); |
|
2410
|
|
|
|
|
|
|
} |
|
2411
|
|
|
|
|
|
|
ssl->rec.hsBytesHashed += ssl->rec.len; |
|
2412
|
|
|
|
|
|
|
} |
|
2413
|
|
|
|
|
|
|
else |
|
2414
|
|
|
|
|
|
|
{ |
|
2415
|
|
|
|
|
|
|
sslUpdateHSHash(ssl, c - ssl->hshakeHeadLen, |
|
2416
|
|
|
|
|
|
|
hsLen + ssl->hshakeHeadLen); |
|
2417
|
|
|
|
|
|
|
} |
|
2418
|
|
|
|
|
|
|
#else |
|
2419
|
8738
|
|
|
|
|
|
sslUpdateHSHash(ssl, c - ssl->hshakeHeadLen, |
|
2420
|
8738
|
|
|
|
|
|
hsLen + ssl->hshakeHeadLen); |
|
2421
|
|
|
|
|
|
|
|
|
2422
|
|
|
|
|
|
|
#endif |
|
2423
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
2424
|
|
|
|
|
|
|
} |
|
2425
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
2426
|
|
|
|
|
|
|
|
|
2427
|
|
|
|
|
|
|
} |
|
2428
|
0
|
0
|
|
|
|
|
else if (ssl->rec.majVer == SSL2_MAJ_VER) |
|
2429
|
|
|
|
|
|
|
{ |
|
2430
|
|
|
|
|
|
|
/* |
|
2431
|
|
|
|
|
|
|
Assume that the handshake len is the same as the incoming ssl record |
|
2432
|
|
|
|
|
|
|
length minus 1 byte (type), this is verified in SSL_HS_CLIENT_HELLO |
|
2433
|
|
|
|
|
|
|
*/ |
|
2434
|
0
|
|
|
|
|
|
hsLen = len - 1; |
|
2435
|
0
|
|
|
|
|
|
sslUpdateHSHash(ssl, (unsigned char *) inbuf, len); |
|
2436
|
|
|
|
|
|
|
} |
|
2437
|
|
|
|
|
|
|
else |
|
2438
|
|
|
|
|
|
|
{ |
|
2439
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
2440
|
|
|
|
|
|
|
psTraceIntInfo("Invalid record version: %d\n", ssl->rec.majVer); |
|
2441
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2442
|
|
|
|
|
|
|
} |
|
2443
|
|
|
|
|
|
|
|
|
2444
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2445
|
|
|
|
|
|
|
/* |
|
2446
|
|
|
|
|
|
|
Finished with header. Process each type of handshake message. |
|
2447
|
|
|
|
|
|
|
*/ |
|
2448
|
8738
|
|
|
|
|
|
switch (ssl->hsState) |
|
2449
|
|
|
|
|
|
|
{ |
|
2450
|
|
|
|
|
|
|
|
|
2451
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2452
|
|
|
|
|
|
|
|
|
2453
|
|
|
|
|
|
|
#ifdef USE_SERVER_SIDE_SSL |
|
2454
|
|
|
|
|
|
|
case SSL_HS_CLIENT_HELLO: |
|
2455
|
1149
|
50
|
|
|
|
|
psAssert(rc == 0); /* checking to see if this is the correct default */ |
|
2456
|
1149
|
50
|
|
|
|
|
if (c + hsLen != end) |
|
2457
|
|
|
|
|
|
|
{ |
|
2458
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
2459
|
|
|
|
|
|
|
psTraceInfo("Invalid length for Client Hello.\n"); |
|
2460
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2461
|
|
|
|
|
|
|
} |
|
2462
|
1149
|
|
|
|
|
|
rc = parseClientHello(ssl, &c, end); |
|
2463
|
|
|
|
|
|
|
/* SSL_PROCESS_DATA is a valid code to indicate the end of a flight */ |
|
2464
|
1149
|
50
|
|
|
|
|
if (rc < 0 && rc != SSL_PROCESS_DATA) |
|
|
|
50
|
|
|
|
|
|
|
2465
|
|
|
|
|
|
|
{ |
|
2466
|
0
|
|
|
|
|
|
return rc; |
|
2467
|
|
|
|
|
|
|
} |
|
2468
|
1149
|
|
|
|
|
|
break; |
|
2469
|
|
|
|
|
|
|
|
|
2470
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2471
|
|
|
|
|
|
|
|
|
2472
|
|
|
|
|
|
|
case SSL_HS_CLIENT_KEY_EXCHANGE: |
|
2473
|
1057
|
50
|
|
|
|
|
psAssert(rc == 0); /* checking to see if this is the correct default */ |
|
2474
|
1057
|
|
|
|
|
|
rc = parseClientKeyExchange(ssl, hsLen, &c, end); |
|
2475
|
1057
|
50
|
|
|
|
|
if (rc < 0) |
|
2476
|
|
|
|
|
|
|
{ |
|
2477
|
0
|
|
|
|
|
|
return rc; |
|
2478
|
|
|
|
|
|
|
} |
|
2479
|
1057
|
|
|
|
|
|
break; |
|
2480
|
|
|
|
|
|
|
#endif /* USE_SERVER_SIDE_SSL */ |
|
2481
|
|
|
|
|
|
|
|
|
2482
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2483
|
|
|
|
|
|
|
|
|
2484
|
|
|
|
|
|
|
case SSL_HS_FINISHED: |
|
2485
|
2119
|
50
|
|
|
|
|
psAssert(rc == 0); /* checking to see if this is the correct default */ |
|
2486
|
2119
|
|
|
|
|
|
rc = parseFinished(ssl, hsLen, hsMsgHash, &c, end); |
|
2487
|
|
|
|
|
|
|
/* SSL_PROCESS_DATA is a valid code to indicate the end of a flight */ |
|
2488
|
2119
|
100
|
|
|
|
|
if (rc < 0 && rc != SSL_PROCESS_DATA) |
|
|
|
50
|
|
|
|
|
|
|
2489
|
|
|
|
|
|
|
{ |
|
2490
|
0
|
|
|
|
|
|
return rc; |
|
2491
|
|
|
|
|
|
|
} |
|
2492
|
2119
|
|
|
|
|
|
break; |
|
2493
|
|
|
|
|
|
|
|
|
2494
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2495
|
|
|
|
|
|
|
#ifdef USE_CLIENT_SIDE_SSL |
|
2496
|
|
|
|
|
|
|
case SSL_HS_HELLO_REQUEST: |
|
2497
|
|
|
|
|
|
|
/* No body message and the only one in record flight */ |
|
2498
|
|
|
|
|
|
|
psTraceHs(">>> Client parsing HELLO_REQUEST message\n"); |
|
2499
|
0
|
0
|
|
|
|
|
if (end - c != 0) |
|
2500
|
|
|
|
|
|
|
{ |
|
2501
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
2502
|
|
|
|
|
|
|
psTraceInfo("Invalid hello request message\n"); |
|
2503
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2504
|
|
|
|
|
|
|
} |
|
2505
|
|
|
|
|
|
|
# ifdef SSL_REHANDSHAKES_ENABLED |
|
2506
|
0
|
0
|
|
|
|
|
if (ssl->rehandshakeCount <= 0) |
|
2507
|
|
|
|
|
|
|
{ |
|
2508
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_NO_RENEGOTIATION; |
|
2509
|
|
|
|
|
|
|
psTraceInfo("Server re-handshaking denied\n"); |
|
2510
|
|
|
|
|
|
|
/* Reset the state to done */ |
|
2511
|
0
|
|
|
|
|
|
ssl->hsState = SSL_HS_DONE; |
|
2512
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2513
|
|
|
|
|
|
|
} |
|
2514
|
0
|
|
|
|
|
|
ssl->rehandshakeCount--; |
|
2515
|
|
|
|
|
|
|
# endif |
|
2516
|
|
|
|
|
|
|
/* Intentionally not changing state here to SERVER_HELLO. The |
|
2517
|
|
|
|
|
|
|
encodeResponse case this will fall into needs to distinguish |
|
2518
|
|
|
|
|
|
|
between calling the normal sslEncodeResponse or encodeClientHello. |
|
2519
|
|
|
|
|
|
|
The HELLO_REQUEST state is used to make that determination and the |
|
2520
|
|
|
|
|
|
|
writing of CLIENT_HELLO will properly move the state along itself */ |
|
2521
|
0
|
|
|
|
|
|
ssl->decState = SSL_HS_HELLO_REQUEST; |
|
2522
|
0
|
|
|
|
|
|
rc = SSL_PROCESS_DATA; |
|
2523
|
0
|
|
|
|
|
|
break; |
|
2524
|
|
|
|
|
|
|
|
|
2525
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2526
|
|
|
|
|
|
|
|
|
2527
|
|
|
|
|
|
|
case SSL_HS_SERVER_HELLO: |
|
2528
|
|
|
|
|
|
|
|
|
2529
|
1150
|
50
|
|
|
|
|
psAssert(rc == 0); /* checking to see if this is the correct default */ |
|
2530
|
1150
|
|
|
|
|
|
rc = parseServerHello(ssl, hsLen, &c, end); |
|
2531
|
1150
|
50
|
|
|
|
|
if (rc < 0) |
|
2532
|
|
|
|
|
|
|
{ |
|
2533
|
0
|
|
|
|
|
|
return rc; |
|
2534
|
|
|
|
|
|
|
} |
|
2535
|
1150
|
|
|
|
|
|
break; |
|
2536
|
|
|
|
|
|
|
|
|
2537
|
|
|
|
|
|
|
#endif /* USE_CLIENT_SIDE_SSL */ |
|
2538
|
|
|
|
|
|
|
|
|
2539
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2540
|
|
|
|
|
|
|
|
|
2541
|
|
|
|
|
|
|
#ifndef USE_ONLY_PSK_CIPHER_SUITE |
|
2542
|
|
|
|
|
|
|
# if defined(USE_CLIENT_SIDE_SSL) || defined(USE_CLIENT_AUTH) |
|
2543
|
|
|
|
|
|
|
|
|
2544
|
|
|
|
|
|
|
case SSL_HS_CERTIFICATE: |
|
2545
|
1148
|
50
|
|
|
|
|
psAssert(rc == 0); /* checking to see if this is the correct default */ |
|
2546
|
1148
|
|
|
|
|
|
rc = parseCertificate(ssl, &c, end); |
|
2547
|
1148
|
100
|
|
|
|
|
if (rc < 0) |
|
2548
|
|
|
|
|
|
|
{ |
|
2549
|
90
|
|
|
|
|
|
return rc; |
|
2550
|
|
|
|
|
|
|
} |
|
2551
|
1058
|
|
|
|
|
|
break; |
|
2552
|
|
|
|
|
|
|
|
|
2553
|
|
|
|
|
|
|
# endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */ |
|
2554
|
|
|
|
|
|
|
#endif /* !USE_ONLY_PSK_CIPHER_SUITE */ |
|
2555
|
|
|
|
|
|
|
|
|
2556
|
|
|
|
|
|
|
#ifdef USE_CLIENT_SIDE_SSL |
|
2557
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2558
|
|
|
|
|
|
|
# ifdef USE_OCSP |
|
2559
|
|
|
|
|
|
|
case SSL_HS_CERTIFICATE_STATUS: |
|
2560
|
|
|
|
|
|
|
psTraceHs(">>> Client parsing CERTIFICATE_STATUS message\n"); |
|
2561
|
0
|
|
|
|
|
|
rc = parseCertificateStatus(ssl, hsLen, &c, end); |
|
2562
|
0
|
0
|
|
|
|
|
if (rc < 0) |
|
2563
|
|
|
|
|
|
|
{ |
|
2564
|
0
|
|
|
|
|
|
return rc; |
|
2565
|
|
|
|
|
|
|
} |
|
2566
|
0
|
|
|
|
|
|
break; |
|
2567
|
|
|
|
|
|
|
# endif /* USE_OCSP */ |
|
2568
|
|
|
|
|
|
|
|
|
2569
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2570
|
|
|
|
|
|
|
|
|
2571
|
|
|
|
|
|
|
|
|
2572
|
|
|
|
|
|
|
# ifdef USE_STATELESS_SESSION_TICKETS |
|
2573
|
|
|
|
|
|
|
case SSL_HS_NEW_SESSION_TICKET: |
|
2574
|
|
|
|
|
|
|
|
|
2575
|
|
|
|
|
|
|
psTraceHs(">>> Client parsing NEW_SESSION_TICKET message\n"); |
|
2576
|
|
|
|
|
|
|
# ifdef USE_EAP_FAST |
|
2577
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_EAP_FAST) |
|
2578
|
|
|
|
|
|
|
{ |
|
2579
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
2580
|
|
|
|
|
|
|
psTraceInfo("NEW_SESSION_TICKET unsupported in EAP-FAST\n"); |
|
2581
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2582
|
|
|
|
|
|
|
} |
|
2583
|
|
|
|
|
|
|
# endif |
|
2584
|
0
|
0
|
|
|
|
|
if (hsLen < 6) |
|
2585
|
|
|
|
|
|
|
{ |
|
2586
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
2587
|
|
|
|
|
|
|
psTraceInfo("Invalid NewSessionTicket message\n"); |
|
2588
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2589
|
|
|
|
|
|
|
} |
|
2590
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketLifetimeHint = *c << 24; c++; |
|
2591
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketLifetimeHint |= *c << 16; c++; |
|
2592
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketLifetimeHint |= *c << 8; c++; |
|
2593
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketLifetimeHint |= *c; c++; |
|
2594
|
|
|
|
|
|
|
/* Reusing hsLen here */ |
|
2595
|
0
|
|
|
|
|
|
hsLen = *c << 8; c++; |
|
2596
|
0
|
|
|
|
|
|
hsLen |= *c; c++; |
|
2597
|
|
|
|
|
|
|
|
|
2598
|
0
|
0
|
|
|
|
|
if ((uint32) (end - c) < hsLen) |
|
2599
|
|
|
|
|
|
|
{ |
|
2600
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
2601
|
|
|
|
|
|
|
psTraceInfo("Invalid NewSessionTicket message\n"); |
|
2602
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2603
|
|
|
|
|
|
|
} |
|
2604
|
0
|
0
|
|
|
|
|
if (ssl->sid->sessionTicketLen == 0) |
|
2605
|
|
|
|
|
|
|
{ |
|
2606
|
|
|
|
|
|
|
/* First time receiving a session ticket */ |
|
2607
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketLen = hsLen; |
|
2608
|
|
|
|
|
|
|
/* This client has a dedicated SessionId pool to draw from. */ |
|
2609
|
0
|
0
|
|
|
|
|
if ((ssl->sid->sessionTicket = psMalloc(ssl->sid->pool, |
|
2610
|
|
|
|
|
|
|
ssl->sid->sessionTicketLen)) != NULL) |
|
2611
|
|
|
|
|
|
|
{ |
|
2612
|
0
|
|
|
|
|
|
memcpy(ssl->sid->sessionTicket, c, ssl->sid->sessionTicketLen); |
|
2613
|
0
|
|
|
|
|
|
c += ssl->sid->sessionTicketLen; |
|
2614
|
|
|
|
|
|
|
} |
|
2615
|
|
|
|
|
|
|
else |
|
2616
|
|
|
|
|
|
|
{ |
|
2617
|
|
|
|
|
|
|
/* Don't fail on alloc error. Just won't have the ticket for |
|
2618
|
|
|
|
|
|
|
next time */ |
|
2619
|
0
|
|
|
|
|
|
c += ssl->sid->sessionTicketLen; |
|
2620
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketLen = 0; |
|
2621
|
|
|
|
|
|
|
} |
|
2622
|
|
|
|
|
|
|
} |
|
2623
|
|
|
|
|
|
|
else |
|
2624
|
|
|
|
|
|
|
{ |
|
2625
|
|
|
|
|
|
|
/* Updated (or duplicate) ticket */ |
|
2626
|
0
|
0
|
|
|
|
|
psAssert(ssl->sid->sessionTicket); /* exists from previous hs */ |
|
2627
|
0
|
0
|
|
|
|
|
if (hsLen == ssl->sid->sessionTicketLen && |
|
|
|
0
|
|
|
|
|
|
|
2628
|
0
|
|
|
|
|
|
(memcmp(c, ssl->sid->sessionTicket, hsLen) == 0)) |
|
2629
|
|
|
|
|
|
|
{ |
|
2630
|
|
|
|
|
|
|
/* server not updating the ticket */ |
|
2631
|
0
|
|
|
|
|
|
c += ssl->sid->sessionTicketLen; |
|
2632
|
|
|
|
|
|
|
} |
|
2633
|
|
|
|
|
|
|
else |
|
2634
|
|
|
|
|
|
|
{ |
|
2635
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketLen = hsLen; |
|
2636
|
0
|
|
|
|
|
|
psFree(ssl->sid->sessionTicket, ssl->sid->pool); |
|
2637
|
0
|
0
|
|
|
|
|
if ((ssl->sid->sessionTicket = psMalloc(ssl->sid->pool, |
|
2638
|
|
|
|
|
|
|
ssl->sid->sessionTicketLen)) != NULL) |
|
2639
|
|
|
|
|
|
|
{ |
|
2640
|
0
|
|
|
|
|
|
memcpy(ssl->sid->sessionTicket, c, |
|
2641
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketLen); |
|
2642
|
0
|
|
|
|
|
|
c += ssl->sid->sessionTicketLen; |
|
2643
|
|
|
|
|
|
|
} |
|
2644
|
|
|
|
|
|
|
else |
|
2645
|
|
|
|
|
|
|
{ |
|
2646
|
|
|
|
|
|
|
/* Don't fail on alloc error. Just won't have the ticket |
|
2647
|
|
|
|
|
|
|
for next time */ |
|
2648
|
0
|
|
|
|
|
|
c += ssl->sid->sessionTicketLen; |
|
2649
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketLen = 0; |
|
2650
|
|
|
|
|
|
|
} |
|
2651
|
|
|
|
|
|
|
} |
|
2652
|
|
|
|
|
|
|
} |
|
2653
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = SESS_TICKET_STATE_INIT; |
|
2654
|
0
|
|
|
|
|
|
ssl->hsState = SSL_HS_FINISHED; |
|
2655
|
0
|
|
|
|
|
|
ssl->decState = SSL_HS_NEW_SESSION_TICKET; |
|
2656
|
0
|
|
|
|
|
|
break; |
|
2657
|
|
|
|
|
|
|
# endif /* USE_STATELESS_SESSION_TICKETS */ |
|
2658
|
|
|
|
|
|
|
|
|
2659
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2660
|
|
|
|
|
|
|
|
|
2661
|
|
|
|
|
|
|
case SSL_HS_SERVER_HELLO_DONE: |
|
2662
|
|
|
|
|
|
|
|
|
2663
|
1058
|
50
|
|
|
|
|
psAssert(rc == 0); /* checking to see if this is the correct default */ |
|
2664
|
1058
|
|
|
|
|
|
rc = parseServerHelloDone(ssl, hsLen, &c, end); |
|
2665
|
1058
|
50
|
|
|
|
|
if (rc < 0 && rc != SSL_PROCESS_DATA) |
|
|
|
50
|
|
|
|
|
|
|
2666
|
|
|
|
|
|
|
{ |
|
2667
|
0
|
|
|
|
|
|
return rc; |
|
2668
|
|
|
|
|
|
|
} |
|
2669
|
1058
|
|
|
|
|
|
break; |
|
2670
|
|
|
|
|
|
|
|
|
2671
|
|
|
|
|
|
|
|
|
2672
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2673
|
|
|
|
|
|
|
|
|
2674
|
|
|
|
|
|
|
# ifndef USE_ONLY_PSK_CIPHER_SUITE |
|
2675
|
|
|
|
|
|
|
case SSL_HS_CERTIFICATE_REQUEST: |
|
2676
|
|
|
|
|
|
|
|
|
2677
|
0
|
0
|
|
|
|
|
psAssert(rc == 0); /* checking to see if this is the correct default */ |
|
2678
|
0
|
|
|
|
|
|
rc = parseCertificateRequest(ssl, hsLen, &c, end); |
|
2679
|
0
|
0
|
|
|
|
|
if (rc < 0) |
|
2680
|
|
|
|
|
|
|
{ |
|
2681
|
0
|
|
|
|
|
|
return rc; |
|
2682
|
|
|
|
|
|
|
} |
|
2683
|
0
|
|
|
|
|
|
break; |
|
2684
|
|
|
|
|
|
|
# endif /* !USE_ONLY_PSK_CIPHER_SUITE */ |
|
2685
|
|
|
|
|
|
|
#endif /* USE_CLIENT_SIDE_SSL */ |
|
2686
|
|
|
|
|
|
|
|
|
2687
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2688
|
|
|
|
|
|
|
|
|
2689
|
|
|
|
|
|
|
#ifndef USE_ONLY_PSK_CIPHER_SUITE |
|
2690
|
|
|
|
|
|
|
# if defined(USE_CLIENT_AUTH) && defined(USE_SERVER_SIDE_SSL) |
|
2691
|
|
|
|
|
|
|
case SSL_HS_CERTIFICATE_VERIFY: |
|
2692
|
|
|
|
|
|
|
|
|
2693
|
0
|
0
|
|
|
|
|
psAssert(rc == 0); /* checking to see if this is the correct default */ |
|
2694
|
0
|
|
|
|
|
|
rc = parseCertificateVerify(ssl, hsMsgHash, &c, end); |
|
2695
|
0
|
0
|
|
|
|
|
if (rc < 0) |
|
2696
|
|
|
|
|
|
|
{ |
|
2697
|
0
|
|
|
|
|
|
return rc; |
|
2698
|
|
|
|
|
|
|
} |
|
2699
|
|
|
|
|
|
|
|
|
2700
|
0
|
|
|
|
|
|
break; |
|
2701
|
|
|
|
|
|
|
# endif /* USE_SERVER_SIDE_SSL && USE_CLIENT_AUTH */ |
|
2702
|
|
|
|
|
|
|
#endif /* !USE_ONLY_PSK_CIPHER_SUITE */ |
|
2703
|
|
|
|
|
|
|
|
|
2704
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2705
|
|
|
|
|
|
|
|
|
2706
|
|
|
|
|
|
|
case SSL_HS_SERVER_KEY_EXCHANGE: |
|
2707
|
|
|
|
|
|
|
#ifdef USE_CLIENT_SIDE_SSL |
|
2708
|
1057
|
50
|
|
|
|
|
psAssert(rc == 0); /* checking to see if this is the correct default */ |
|
2709
|
1057
|
|
|
|
|
|
rc = parseServerKeyExchange(ssl, hsMsgHash, &c, end); |
|
2710
|
1057
|
50
|
|
|
|
|
if (rc < 0) |
|
2711
|
|
|
|
|
|
|
{ |
|
2712
|
0
|
|
|
|
|
|
return rc; |
|
2713
|
|
|
|
|
|
|
} |
|
2714
|
|
|
|
|
|
|
#else /* USE_CLIENT_SIDE_SSL */ |
|
2715
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
2716
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2717
|
|
|
|
|
|
|
#endif /* USE_CLIENT_SIDE_SSL */ |
|
2718
|
1057
|
|
|
|
|
|
break; |
|
2719
|
|
|
|
|
|
|
|
|
2720
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2721
|
|
|
|
|
|
|
|
|
2722
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
2723
|
|
|
|
|
|
|
# ifdef USE_CLIENT_SIDE_SSL |
|
2724
|
|
|
|
|
|
|
case SSL_HS_HELLO_VERIFY_REQUEST: |
|
2725
|
|
|
|
|
|
|
psTraceHs(">>> Client parsing HELLO_VERIFY_REQUEST message\n"); |
|
2726
|
|
|
|
|
|
|
/* |
|
2727
|
|
|
|
|
|
|
Format for message is two byte version specifier, 1 byte length, and |
|
2728
|
|
|
|
|
|
|
the cookie itself |
|
2729
|
|
|
|
|
|
|
*/ |
|
2730
|
|
|
|
|
|
|
if ((end - c) < 3) |
|
2731
|
|
|
|
|
|
|
{ |
|
2732
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
2733
|
|
|
|
|
|
|
psTraceInfo("Invalid HelloVerifyRequest message\n"); |
|
2734
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2735
|
|
|
|
|
|
|
} |
|
2736
|
|
|
|
|
|
|
hvreqMajVer = *c; c++; |
|
2737
|
|
|
|
|
|
|
hvreqMinVer = *c; c++; |
|
2738
|
|
|
|
|
|
|
(void) hvreqMajVer; /* Silence a 'set but not used' warning. */ |
|
2739
|
|
|
|
|
|
|
(void) hvreqMinVer; |
|
2740
|
|
|
|
|
|
|
ssl->cookieLen = *c; c++; |
|
2741
|
|
|
|
|
|
|
if (ssl->cookieLen > 0) |
|
2742
|
|
|
|
|
|
|
{ |
|
2743
|
|
|
|
|
|
|
if ((end - c) < ssl->cookieLen) |
|
2744
|
|
|
|
|
|
|
{ |
|
2745
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
|
2746
|
|
|
|
|
|
|
psTraceInfo("Invalid HelloVerifyRequest message\n"); |
|
2747
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2748
|
|
|
|
|
|
|
} |
|
2749
|
|
|
|
|
|
|
/* |
|
2750
|
|
|
|
|
|
|
The handshake pool does exists at this point. For DTLS handshakes |
|
2751
|
|
|
|
|
|
|
the client created the pool during the ClientHello write in order |
|
2752
|
|
|
|
|
|
|
to store the initial message in case the Server asks for cookie |
|
2753
|
|
|
|
|
|
|
(which is exactly what is happening right here). |
|
2754
|
|
|
|
|
|
|
*/ |
|
2755
|
|
|
|
|
|
|
if (ssl->haveCookie) |
|
2756
|
|
|
|
|
|
|
{ |
|
2757
|
|
|
|
|
|
|
/* retransmit. should match what we already have */ |
|
2758
|
|
|
|
|
|
|
if (memcmpct(ssl->cookie, c, ssl->cookieLen) != 0) |
|
2759
|
|
|
|
|
|
|
{ |
|
2760
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
|
2761
|
|
|
|
|
|
|
psTraceInfo("Cookie has changed on retransmit\n"); |
|
2762
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2763
|
|
|
|
|
|
|
} |
|
2764
|
|
|
|
|
|
|
c += ssl->cookieLen; |
|
2765
|
|
|
|
|
|
|
} |
|
2766
|
|
|
|
|
|
|
else |
|
2767
|
|
|
|
|
|
|
{ |
|
2768
|
|
|
|
|
|
|
ssl->cookie = psMalloc(ssl->hsPool, ssl->cookieLen); |
|
2769
|
|
|
|
|
|
|
if (ssl->cookie == NULL) |
|
2770
|
|
|
|
|
|
|
{ |
|
2771
|
|
|
|
|
|
|
return SSL_MEM_ERROR; |
|
2772
|
|
|
|
|
|
|
} |
|
2773
|
|
|
|
|
|
|
memcpy(ssl->cookie, c, ssl->cookieLen); |
|
2774
|
|
|
|
|
|
|
c += ssl->cookieLen; |
|
2775
|
|
|
|
|
|
|
} |
|
2776
|
|
|
|
|
|
|
} |
|
2777
|
|
|
|
|
|
|
ssl->haveCookie++; |
|
2778
|
|
|
|
|
|
|
ssl->hsState = SSL_HS_SERVER_HELLO; |
|
2779
|
|
|
|
|
|
|
ssl->decState = SSL_HS_HELLO_VERIFY_REQUEST; |
|
2780
|
|
|
|
|
|
|
rc = SSL_PROCESS_DATA; |
|
2781
|
|
|
|
|
|
|
break; |
|
2782
|
|
|
|
|
|
|
# endif /* USE_CLIENT_SIDE_SSL */ |
|
2783
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
2784
|
|
|
|
|
|
|
|
|
2785
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2786
|
|
|
|
|
|
|
|
|
2787
|
|
|
|
|
|
|
default: |
|
2788
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNEXPECTED_MESSAGE; |
|
2789
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2790
|
|
|
|
|
|
|
} |
|
2791
|
|
|
|
|
|
|
|
|
2792
|
|
|
|
|
|
|
#ifdef USE_DTLS |
|
2793
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_DTLS) |
|
2794
|
|
|
|
|
|
|
{ |
|
2795
|
|
|
|
|
|
|
ssl->lastMsn = msn; /* MSN of last message sucessfully parsed */ |
|
2796
|
|
|
|
|
|
|
} |
|
2797
|
|
|
|
|
|
|
#endif /* USE_DTLS */ |
|
2798
|
|
|
|
|
|
|
|
|
2799
|
|
|
|
|
|
|
/* |
|
2800
|
|
|
|
|
|
|
if we've got more data in the record, the sender has packed |
|
2801
|
|
|
|
|
|
|
multiple handshake messages in one record. Parse the next one. |
|
2802
|
|
|
|
|
|
|
*/ |
|
2803
|
8648
|
50
|
|
|
|
|
if (c < end) |
|
2804
|
|
|
|
|
|
|
{ |
|
2805
|
0
|
|
|
|
|
|
goto parseHandshake; |
|
2806
|
|
|
|
|
|
|
} |
|
2807
|
8738
|
|
|
|
|
|
return rc; |
|
2808
|
|
|
|
|
|
|
} |
|
2809
|
|
|
|
|
|
|
|
|
2810
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2811
|
|
|
|
|
|
|
#if defined(USE_CLIENT_SIDE_SSL) || defined(USE_CLIENT_AUTH) |
|
2812
|
|
|
|
|
|
|
# ifdef USE_CERT_CHAIN_PARSING |
|
2813
|
|
|
|
|
|
|
static int32 parseSingleCert(ssl_t *ssl, unsigned char *c, unsigned char *end, |
|
2814
|
|
|
|
|
|
|
int32 certLen) |
|
2815
|
|
|
|
|
|
|
{ |
|
2816
|
|
|
|
|
|
|
int32 parseLen, certFlags; |
|
2817
|
|
|
|
|
|
|
psX509Cert_t *cert, *p; |
|
2818
|
|
|
|
|
|
|
|
|
2819
|
|
|
|
|
|
|
/* |
|
2820
|
|
|
|
|
|
|
Extract the binary cert message into the cert structure |
|
2821
|
|
|
|
|
|
|
*/ |
|
2822
|
|
|
|
|
|
|
if (ssl->bflags & BFLAG_KEEP_PEER_CERT_DER) |
|
2823
|
|
|
|
|
|
|
{ |
|
2824
|
|
|
|
|
|
|
certFlags |= CERT_STORE_UNPARSED_BUFFER; |
|
2825
|
|
|
|
|
|
|
} |
|
2826
|
|
|
|
|
|
|
|
|
2827
|
|
|
|
|
|
|
if ((parseLen = psX509ParseCert(ssl->hsPool, c, certLen, &cert, certFlags)) < 0) |
|
2828
|
|
|
|
|
|
|
{ |
|
2829
|
|
|
|
|
|
|
psX509FreeCert(cert); |
|
2830
|
|
|
|
|
|
|
if (parseLen == PS_MEM_FAIL) |
|
2831
|
|
|
|
|
|
|
{ |
|
2832
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
|
2833
|
|
|
|
|
|
|
} |
|
2834
|
|
|
|
|
|
|
else |
|
2835
|
|
|
|
|
|
|
{ |
|
2836
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_BAD_CERTIFICATE; |
|
2837
|
|
|
|
|
|
|
} |
|
2838
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
|
2839
|
|
|
|
|
|
|
} |
|
2840
|
|
|
|
|
|
|
if (ssl->sec.cert == NULL) |
|
2841
|
|
|
|
|
|
|
{ |
|
2842
|
|
|
|
|
|
|
ssl->sec.cert = cert; |
|
2843
|
|
|
|
|
|
|
} |
|
2844
|
|
|
|
|
|
|
else |
|
2845
|
|
|
|
|
|
|
{ |
|
2846
|
|
|
|
|
|
|
p = ssl->sec.cert; |
|
2847
|
|
|
|
|
|
|
while (p->next != NULL) |
|
2848
|
|
|
|
|
|
|
{ |
|
2849
|
|
|
|
|
|
|
p = p->next; |
|
2850
|
|
|
|
|
|
|
} |
|
2851
|
|
|
|
|
|
|
p->next = cert; |
|
2852
|
|
|
|
|
|
|
} |
|
2853
|
|
|
|
|
|
|
return parseLen; |
|
2854
|
|
|
|
|
|
|
} |
|
2855
|
|
|
|
|
|
|
# endif /* USE_CERT_CHAIN_PARSING */ |
|
2856
|
|
|
|
|
|
|
#endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */ |
|
2857
|
|
|
|
|
|
|
|
|
2858
|
|
|
|
|
|
|
/******************************************************************************/ |
|
2859
|
|
|
|
|
|
|
|