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
|
|
|
|
|
|
|
|