line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/** |
2
|
|
|
|
|
|
|
* @file extDecode.c |
3
|
|
|
|
|
|
|
* @version 950bba4 (HEAD -> master) |
4
|
|
|
|
|
|
|
* |
5
|
|
|
|
|
|
|
* CLIENT_HELLO and SERVER_HELLO extension parsing |
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
|
|
|
|
|
|
|
#ifdef USE_SERVER_SIDE_SSL |
40
|
|
|
|
|
|
|
static int ClientHelloExt(ssl_t *ssl, unsigned short extType, |
41
|
|
|
|
|
|
|
unsigned short extLen, const unsigned char *c); |
42
|
|
|
|
|
|
|
#endif |
43
|
|
|
|
|
|
|
#ifdef USE_CLIENT_SIDE_SSL |
44
|
|
|
|
|
|
|
static int ServerHelloExt(ssl_t *ssl, unsigned short extType, |
45
|
|
|
|
|
|
|
unsigned short extLen, const unsigned char *c); |
46
|
|
|
|
|
|
|
#endif |
47
|
|
|
|
|
|
|
#ifdef USE_ALPN |
48
|
|
|
|
|
|
|
static int dealWithAlpnExt(ssl_t *ssl, const unsigned char *c, |
49
|
|
|
|
|
|
|
unsigned short extLen); |
50
|
|
|
|
|
|
|
#endif |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
#ifdef USE_SERVER_SIDE_SSL |
53
|
|
|
|
|
|
|
/******************************************************************************/ |
54
|
|
|
|
|
|
|
/* |
55
|
|
|
|
|
|
|
Parse the ClientHello extension list. |
56
|
|
|
|
|
|
|
*/ |
57
|
1149
|
|
|
|
|
|
int32 parseClientHelloExtensions(ssl_t *ssl, unsigned char **cp, unsigned short len) |
58
|
|
|
|
|
|
|
{ |
59
|
|
|
|
|
|
|
unsigned short extLen, extType; |
60
|
|
|
|
|
|
|
unsigned char *c, *end; |
61
|
|
|
|
|
|
|
int rc; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# ifdef ENABLE_SECURE_REHANDSHAKES |
64
|
1149
|
|
|
|
|
|
unsigned short renegotiationExtSent = 0; |
65
|
|
|
|
|
|
|
# endif |
66
|
|
|
|
|
|
|
|
67
|
1149
|
|
|
|
|
|
c = *cp; |
68
|
1149
|
|
|
|
|
|
end = c + len; |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
/* Clear extFlags in case of rehandshakes */ |
71
|
1149
|
|
|
|
|
|
ssl->extFlags.truncated_hmac = 0; |
72
|
1149
|
|
|
|
|
|
ssl->extFlags.sni = 0; |
73
|
1149
|
|
|
|
|
|
ssl->extFlags.session_id = 0; |
74
|
1149
|
|
|
|
|
|
ssl->extFlags.session_ticket = 0; |
75
|
1149
|
|
|
|
|
|
ssl->extFlags.extended_master_secret = 0; |
76
|
1149
|
|
|
|
|
|
ssl->extFlags.status_request = 0; |
77
|
1149
|
|
|
|
|
|
ssl->extFlags.signed_certificate_timestamp = 0; |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
/* There could be extension data to parse here: |
80
|
|
|
|
|
|
|
Two byte length and extension info. |
81
|
|
|
|
|
|
|
http://www.faqs.org/rfcs/rfc3546.html |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
NOTE: This c != end test is only safe because ClientHello is the |
84
|
|
|
|
|
|
|
only record/message in the flight of supported handshake protocols. */ |
85
|
1149
|
50
|
|
|
|
|
if (c != end) |
86
|
|
|
|
|
|
|
{ |
87
|
1149
|
50
|
|
|
|
|
if (end - c < 2) |
88
|
|
|
|
|
|
|
{ |
89
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
90
|
|
|
|
|
|
|
psTraceInfo("Invalid extension header len\n"); |
91
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
92
|
|
|
|
|
|
|
} |
93
|
1149
|
|
|
|
|
|
extLen = *c << 8; c++; /* Total length of list, in bytes */ |
94
|
1149
|
|
|
|
|
|
extLen += *c; c++; |
95
|
|
|
|
|
|
|
/* extLen must be minimum 2 b type 2 b len and 0 b value */ |
96
|
1149
|
50
|
|
|
|
|
if ((uint32) (end - c) != extLen || extLen < 4) |
|
|
50
|
|
|
|
|
|
97
|
|
|
|
|
|
|
{ |
98
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
99
|
|
|
|
|
|
|
psTraceInfo("Invalid extension header len\n"); |
100
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# ifdef USE_TLS_1_2 |
104
|
1149
|
|
|
|
|
|
ssl->hashSigAlg = 0; |
105
|
|
|
|
|
|
|
# endif |
106
|
5750
|
100
|
|
|
|
|
while (c != end) |
107
|
|
|
|
|
|
|
{ |
108
|
4601
|
|
|
|
|
|
extType = *c << 8; c++; /* Individual hello ext */ |
109
|
4601
|
|
|
|
|
|
extType += *c; c++; |
110
|
4601
|
50
|
|
|
|
|
if (end - c < 2) |
111
|
|
|
|
|
|
|
{ |
112
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
113
|
|
|
|
|
|
|
psTraceInfo("Invalid extension header len\n"); |
114
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
115
|
|
|
|
|
|
|
} |
116
|
4601
|
|
|
|
|
|
extLen = *c << 8; c++; /* length of one extension */ |
117
|
4601
|
|
|
|
|
|
extLen += *c; c++; |
118
|
|
|
|
|
|
|
/* Minimum extension value len is 0 bytes */ |
119
|
4601
|
50
|
|
|
|
|
if ((uint32) (end - c) < extLen) |
120
|
|
|
|
|
|
|
{ |
121
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
122
|
|
|
|
|
|
|
psTraceInfo("Invalid extension header len\n"); |
123
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
# ifdef ENABLE_SECURE_REHANDSHAKES |
126
|
4601
|
100
|
|
|
|
|
if (extType == EXT_RENEGOTIATION_INFO) |
127
|
|
|
|
|
|
|
{ |
128
|
7
|
|
|
|
|
|
renegotiationExtSent = 1; |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
# endif |
131
|
|
|
|
|
|
|
/* Parse incoming client extensions we support. */ |
132
|
4601
|
50
|
|
|
|
|
if ((rc = ClientHelloExt(ssl, extType, extLen, c)) < 0) |
133
|
|
|
|
|
|
|
{ |
134
|
|
|
|
|
|
|
/* On error, ssl->error will have been set */ |
135
|
0
|
|
|
|
|
|
return rc; |
136
|
|
|
|
|
|
|
} |
137
|
4601
|
|
|
|
|
|
c += extLen; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
/* Handle the extensions that were missing or not what we wanted */ |
142
|
1149
|
50
|
|
|
|
|
if (ssl->extFlags.require_extended_master_secret == 1 && |
|
|
0
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
ssl->extFlags.extended_master_secret == 0) |
144
|
|
|
|
|
|
|
{ |
145
|
|
|
|
|
|
|
psTraceInfo("Client doesn't support extended master secret\n"); |
146
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
147
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# if defined(USE_TLS_1_2) && defined(USE_CERT_PARSE) |
151
|
1149
|
50
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_TLS_1_2) |
152
|
|
|
|
|
|
|
{ |
153
|
1149
|
50
|
|
|
|
|
if (!ssl->hashSigAlg) |
154
|
|
|
|
|
|
|
{ |
155
|
|
|
|
|
|
|
# ifdef USE_SHA1 |
156
|
|
|
|
|
|
|
/* Client didn't send the extension at all. Unfortunately, spec says we |
157
|
|
|
|
|
|
|
have to assume SHA1 in this case, even though both peers are |
158
|
|
|
|
|
|
|
already calculating a SHA256 based handshake hash. */ |
159
|
|
|
|
|
|
|
# ifdef USE_RSA_CIPHER_SUITE |
160
|
0
|
|
|
|
|
|
ssl->hashSigAlg |= HASH_SIG_SHA1_RSA_MASK; |
161
|
|
|
|
|
|
|
# endif |
162
|
|
|
|
|
|
|
# ifdef USE_ECC_CIPHER_SUITE |
163
|
0
|
|
|
|
|
|
ssl->hashSigAlg |= HASH_SIG_SHA1_ECDSA_MASK; |
164
|
|
|
|
|
|
|
# endif |
165
|
|
|
|
|
|
|
# else |
166
|
|
|
|
|
|
|
if (ssl->flags & SSL_FLAGS_CLIENT_AUTH) |
167
|
|
|
|
|
|
|
{ |
168
|
|
|
|
|
|
|
psTraceInfo("Client didn't provide hashSigAlg and sha1 not supported\n"); |
169
|
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
170
|
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
# endif /* USE_SHA1 */ |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
} |
175
|
|
|
|
|
|
|
# endif /* USE_TLS_1_2 */ |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# ifdef USE_STATELESS_SESSION_TICKETS |
178
|
|
|
|
|
|
|
/* If session ID was sent that we didn't like AND no ticket was sent |
179
|
|
|
|
|
|
|
then we can forget we ever received a sessionID now */ |
180
|
1149
|
50
|
|
|
|
|
if (ssl->extFlags.session_id == 1) |
181
|
|
|
|
|
|
|
{ |
182
|
0
|
|
|
|
|
|
memset(ssl->sessionId, 0, SSL_MAX_SESSION_ID_SIZE); |
183
|
0
|
|
|
|
|
|
ssl->sessionIdLen = 0; |
184
|
|
|
|
|
|
|
} |
185
|
1149
|
|
|
|
|
|
ssl->extFlags.session_id = 0; |
186
|
1149
|
|
|
|
|
|
ssl->extFlags.session_ticket = 0; |
187
|
|
|
|
|
|
|
# endif |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
# ifdef ENABLE_SECURE_REHANDSHAKES |
190
|
1149
|
100
|
|
|
|
|
if (!renegotiationExtSent) |
191
|
|
|
|
|
|
|
{ |
192
|
|
|
|
|
|
|
# ifdef REQUIRE_SECURE_REHANDSHAKES |
193
|
|
|
|
|
|
|
/* Check if SCSV was sent instead */ |
194
|
1142
|
50
|
|
|
|
|
if (ssl->secureRenegotiationFlag == PS_FALSE && |
|
|
0
|
|
|
|
|
|
195
|
0
|
|
|
|
|
|
ssl->myVerifyDataLen == 0) |
196
|
|
|
|
|
|
|
{ |
197
|
|
|
|
|
|
|
psTraceInfo("Client doesn't support renegotiation hello\n"); |
198
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
199
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
# endif /* REQUIRE_SECURE_REHANDSHAKES */ |
202
|
1142
|
50
|
|
|
|
|
if (ssl->secureRenegotiationFlag == PS_TRUE && |
|
|
50
|
|
|
|
|
|
203
|
1142
|
|
|
|
|
|
ssl->myVerifyDataLen > 0) |
204
|
|
|
|
|
|
|
{ |
205
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
206
|
|
|
|
|
|
|
psTraceInfo("Cln missing renegotiationInfo on re-hndshk\n"); |
207
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
# ifndef ENABLE_INSECURE_REHANDSHAKES |
210
|
1142
|
50
|
|
|
|
|
if (ssl->secureRenegotiationFlag == PS_FALSE && |
|
|
0
|
|
|
|
|
|
211
|
0
|
|
|
|
|
|
ssl->myVerifyDataLen > 0) |
212
|
|
|
|
|
|
|
{ |
213
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
214
|
|
|
|
|
|
|
psTraceInfo("Cln attempting insecure handshake\n"); |
215
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
# endif /* !ENABLE_INSECURE_REHANDSHAKES */ |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
# endif /* ENABLE_SECURE_REHANDSHAKES */ |
220
|
|
|
|
|
|
|
|
221
|
1149
|
|
|
|
|
|
*cp = c; |
222
|
1149
|
|
|
|
|
|
return PS_SUCCESS; |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
/******************************************************************************/ |
226
|
|
|
|
|
|
|
/* |
227
|
|
|
|
|
|
|
Parse a single client extension |
228
|
|
|
|
|
|
|
*/ |
229
|
4601
|
|
|
|
|
|
static int ClientHelloExt(ssl_t *ssl, unsigned short extType, unsigned short extLen, |
230
|
|
|
|
|
|
|
const unsigned char *c) |
231
|
|
|
|
|
|
|
{ |
232
|
|
|
|
|
|
|
int i; |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
# ifdef USE_ECC_CIPHER_SUITE |
235
|
|
|
|
|
|
|
unsigned short dataLen, curveId; |
236
|
|
|
|
|
|
|
uint32 ecFlags; |
237
|
|
|
|
|
|
|
# elif defined USE_OCSP |
238
|
|
|
|
|
|
|
unsigned short dataLen; |
239
|
|
|
|
|
|
|
# endif /* USE_ECC_CIPHER_SUITE || USE_OCSP */ |
240
|
|
|
|
|
|
|
# ifdef USE_TLS_1_2 |
241
|
|
|
|
|
|
|
unsigned short tmpLen; |
242
|
|
|
|
|
|
|
# endif |
243
|
|
|
|
|
|
|
|
244
|
4601
|
|
|
|
|
|
switch (extType) |
245
|
|
|
|
|
|
|
{ |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
/**************************************************************************/ |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
case EXT_TRUNCATED_HMAC: |
250
|
0
|
0
|
|
|
|
|
if (extLen != 0) |
251
|
|
|
|
|
|
|
{ |
252
|
|
|
|
|
|
|
psTraceInfo("Bad truncated HMAC extension\n"); |
253
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
254
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
/* User could have disabled for this session */ |
257
|
0
|
0
|
|
|
|
|
if (!ssl->extFlags.deny_truncated_hmac) |
258
|
|
|
|
|
|
|
{ |
259
|
0
|
|
|
|
|
|
ssl->extFlags.truncated_hmac = 1; |
260
|
|
|
|
|
|
|
} |
261
|
0
|
|
|
|
|
|
break; |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
case EXT_EXTENDED_MASTER_SECRET: |
264
|
1149
|
50
|
|
|
|
|
if (extLen != 0) |
265
|
|
|
|
|
|
|
{ |
266
|
|
|
|
|
|
|
psTraceInfo("Bad extended master secret extension\n"); |
267
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
268
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
269
|
|
|
|
|
|
|
} |
270
|
1149
|
|
|
|
|
|
ssl->extFlags.extended_master_secret = 1; |
271
|
1149
|
|
|
|
|
|
break; |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
/**************************************************************************/ |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
case EXT_MAX_FRAGMENT_LEN: |
276
|
0
|
0
|
|
|
|
|
if (extLen != 1) |
277
|
|
|
|
|
|
|
{ |
278
|
|
|
|
|
|
|
psTraceInfo("Invalid frag len ext len\n"); |
279
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
280
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
/* User could have disabled for this session using |
283
|
|
|
|
|
|
|
the session options */ |
284
|
0
|
0
|
|
|
|
|
if (!ssl->extFlags.deny_max_fragment_len) |
285
|
|
|
|
|
|
|
{ |
286
|
0
|
0
|
|
|
|
|
if (*c == 0x1) |
287
|
|
|
|
|
|
|
{ |
288
|
0
|
|
|
|
|
|
ssl->maxPtFrag = 0x200; |
289
|
|
|
|
|
|
|
} |
290
|
0
|
0
|
|
|
|
|
else if (*c == 0x2) |
291
|
|
|
|
|
|
|
{ |
292
|
0
|
|
|
|
|
|
ssl->maxPtFrag = 0x400; |
293
|
|
|
|
|
|
|
} |
294
|
0
|
0
|
|
|
|
|
else if (*c == 0x3) |
295
|
|
|
|
|
|
|
{ |
296
|
0
|
|
|
|
|
|
ssl->maxPtFrag = 0x800; |
297
|
|
|
|
|
|
|
} |
298
|
0
|
0
|
|
|
|
|
else if (*c == 0x4) |
299
|
|
|
|
|
|
|
{ |
300
|
0
|
|
|
|
|
|
ssl->maxPtFrag = 0x1000; |
301
|
|
|
|
|
|
|
} |
302
|
|
|
|
|
|
|
else |
303
|
|
|
|
|
|
|
{ |
304
|
|
|
|
|
|
|
psTraceInfo("Client sent bad frag len value\n"); |
305
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
306
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
} |
309
|
0
|
|
|
|
|
|
break; |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
/**************************************************************************/ |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
case EXT_SNI: |
314
|
|
|
|
|
|
|
/* Must hold (2 b len + 1 b zero) + 2 b len */ |
315
|
0
|
0
|
|
|
|
|
if (extLen < 5) |
316
|
|
|
|
|
|
|
{ |
317
|
|
|
|
|
|
|
psTraceInfo("Invalid server name ext len\n"); |
318
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
319
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
/* Two length bytes. May seem odd to ignore but |
322
|
|
|
|
|
|
|
the inner length is repeated right below after |
323
|
|
|
|
|
|
|
the expected 0x0 bytes */ |
324
|
0
|
|
|
|
|
|
i = *c << 8; c++; |
325
|
0
|
|
|
|
|
|
i += *c; c++; |
326
|
0
|
0
|
|
|
|
|
if (*c++ != 0x0) |
327
|
|
|
|
|
|
|
{ |
328
|
|
|
|
|
|
|
psTraceInfo("Expected host_name in SNI ext\n"); |
329
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
330
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
(void) i; /* TODO - validate against length determined below */ |
333
|
0
|
|
|
|
|
|
extLen -= 3; |
334
|
0
|
|
|
|
|
|
i = *c << 8; c++; |
335
|
0
|
|
|
|
|
|
i += *c; c++; |
336
|
0
|
|
|
|
|
|
extLen -= 2; /* Length check covered above */ |
337
|
|
|
|
|
|
|
/* Arbitrary length cap between 1 and min(extlen,255) */ |
338
|
0
|
0
|
|
|
|
|
if ((int32) extLen < i || i > 255 || i <= 0) |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
339
|
|
|
|
|
|
|
{ |
340
|
|
|
|
|
|
|
psTraceInfo("Invalid host name ext len\n"); |
341
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
342
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
343
|
|
|
|
|
|
|
} |
344
|
0
|
0
|
|
|
|
|
if (ssl->expectedName) |
345
|
|
|
|
|
|
|
{ |
346
|
0
|
|
|
|
|
|
psFree(ssl->expectedName, ssl->sPool); |
347
|
|
|
|
|
|
|
} |
348
|
0
|
0
|
|
|
|
|
if ((ssl->expectedName = psMalloc(ssl->sPool, i + 1)) == NULL) |
349
|
|
|
|
|
|
|
{ |
350
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
351
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
352
|
|
|
|
|
|
|
} |
353
|
0
|
|
|
|
|
|
memcpy(ssl->expectedName, c, i); |
354
|
0
|
|
|
|
|
|
ssl->expectedName[i] = '\0'; |
355
|
0
|
|
|
|
|
|
break; |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
# ifdef USE_ALPN |
358
|
|
|
|
|
|
|
/**************************************************************************/ |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
case EXT_ALPN: |
361
|
|
|
|
|
|
|
/* Must hold 2 b len 1 b zero 2 b len */ |
362
|
0
|
0
|
|
|
|
|
if (extLen < 2) |
363
|
|
|
|
|
|
|
{ |
364
|
|
|
|
|
|
|
psTraceInfo("Invalid ALPN ext len\n"); |
365
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
366
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
/* Skip extension if server didn't register callback */ |
369
|
0
|
0
|
|
|
|
|
if (ssl->srv_alpn_cb) |
370
|
|
|
|
|
|
|
{ |
371
|
|
|
|
|
|
|
int rc; |
372
|
0
|
0
|
|
|
|
|
if ((rc = dealWithAlpnExt(ssl, c, extLen)) < 0) |
373
|
|
|
|
|
|
|
{ |
374
|
0
|
0
|
|
|
|
|
if (rc == PS_PROTOCOL_FAIL) |
375
|
|
|
|
|
|
|
{ |
376
|
|
|
|
|
|
|
/* This is a user space rejection */ |
377
|
|
|
|
|
|
|
psTraceInfo("User rejects ALPN ext\n"); |
378
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_NO_APP_PROTOCOL; |
379
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
psTraceInfo("Invalid ALPN ext\n"); |
382
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
383
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
384
|
|
|
|
|
|
|
} |
385
|
|
|
|
|
|
|
} |
386
|
0
|
|
|
|
|
|
break; |
387
|
|
|
|
|
|
|
# endif |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
# ifdef ENABLE_SECURE_REHANDSHAKES |
390
|
|
|
|
|
|
|
/**************************************************************************/ |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
case EXT_RENEGOTIATION_INFO: |
393
|
7
|
50
|
|
|
|
|
if (ssl->secureRenegotiationFlag == PS_FALSE && |
|
|
0
|
|
|
|
|
|
394
|
0
|
|
|
|
|
|
ssl->myVerifyDataLen == 0) |
395
|
|
|
|
|
|
|
{ |
396
|
0
|
0
|
|
|
|
|
if (extLen == 1 && *c == '\0') |
|
|
0
|
|
|
|
|
|
397
|
|
|
|
|
|
|
{ |
398
|
0
|
|
|
|
|
|
ssl->secureRenegotiationFlag = PS_TRUE; |
399
|
|
|
|
|
|
|
} |
400
|
|
|
|
|
|
|
else |
401
|
|
|
|
|
|
|
{ |
402
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
403
|
|
|
|
|
|
|
psTraceInfo("Cln sent bad renegotiationInfo\n"); |
404
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
} |
407
|
7
|
50
|
|
|
|
|
else if ((extLen == ssl->peerVerifyDataLen + 1) && |
|
|
50
|
|
|
|
|
|
408
|
7
|
|
|
|
|
|
(ssl->secureRenegotiationFlag == PS_TRUE)) |
409
|
|
|
|
|
|
|
{ |
410
|
7
|
50
|
|
|
|
|
if (*c != ssl->peerVerifyDataLen) |
411
|
|
|
|
|
|
|
{ |
412
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
413
|
|
|
|
|
|
|
psTraceInfo("Invalid renegotiation encoding\n"); |
414
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
415
|
|
|
|
|
|
|
} |
416
|
7
|
50
|
|
|
|
|
if (memcmpct(c + 1, ssl->peerVerifyData, |
417
|
7
|
|
|
|
|
|
ssl->peerVerifyDataLen) != 0) |
418
|
|
|
|
|
|
|
{ |
419
|
|
|
|
|
|
|
psTraceInfo("Cli verify renegotiation fail\n"); |
420
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
421
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
422
|
|
|
|
|
|
|
} |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
else |
425
|
|
|
|
|
|
|
{ |
426
|
|
|
|
|
|
|
psTraceInfo("Bad state/len of renegotiation ext\n"); |
427
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
428
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
429
|
|
|
|
|
|
|
} |
430
|
7
|
|
|
|
|
|
break; |
431
|
|
|
|
|
|
|
# endif /* ENABLE_SECURE_REHANDSHAKES */ |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
# ifdef USE_TLS_1_2 |
434
|
|
|
|
|
|
|
/**************************************************************************/ |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
case EXT_SIGNATURE_ALGORITHMS: |
437
|
|
|
|
|
|
|
/* This extension is responsible for telling the server which |
438
|
|
|
|
|
|
|
sig algorithms it accepts so here we are saving them |
439
|
|
|
|
|
|
|
aside for when user chooses identity certificate. |
440
|
|
|
|
|
|
|
https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */ |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
/* Minimum length of 2 b type, 2 b alg */ |
443
|
|
|
|
|
|
|
/* Arbitrary Max of 16 suites */ |
444
|
1149
|
50
|
|
|
|
|
if (extLen > (2 + 32) || extLen < 4 || (extLen & 1)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
445
|
|
|
|
|
|
|
{ |
446
|
|
|
|
|
|
|
psTraceInfo("Malformed sig_alg len\n"); |
447
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
448
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
449
|
|
|
|
|
|
|
} |
450
|
|
|
|
|
|
|
|
451
|
1149
|
|
|
|
|
|
tmpLen = *c << 8; c++; |
452
|
1149
|
|
|
|
|
|
tmpLen |= *c; c++; |
453
|
1149
|
|
|
|
|
|
extLen -= 2; |
454
|
|
|
|
|
|
|
|
455
|
1149
|
50
|
|
|
|
|
if ((uint32) tmpLen > extLen || tmpLen < 2 || (tmpLen & 1)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
456
|
|
|
|
|
|
|
{ |
457
|
|
|
|
|
|
|
psTraceInfo("Malformed sig_alg extension\n"); |
458
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
459
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
460
|
|
|
|
|
|
|
} |
461
|
|
|
|
|
|
|
/* list of 2 byte pairs in a hash/sig format that |
462
|
|
|
|
|
|
|
need to be searched to find match with server |
463
|
|
|
|
|
|
|
cert sigAlgorithm |
464
|
|
|
|
|
|
|
Test if client will be able to accept our sigs |
465
|
|
|
|
|
|
|
based on what our idenity certificate is */ |
466
|
10341
|
100
|
|
|
|
|
while (tmpLen >= 2 && extLen >= 2) |
|
|
50
|
|
|
|
|
|
467
|
|
|
|
|
|
|
{ |
468
|
9192
|
|
|
|
|
|
ssl->hashSigAlg |= HASH_SIG_MASK(c[0], c[1]); |
469
|
9192
|
|
|
|
|
|
c += 2; |
470
|
9192
|
|
|
|
|
|
tmpLen -= 2; |
471
|
9192
|
|
|
|
|
|
extLen -= 2; |
472
|
|
|
|
|
|
|
} |
473
|
1149
|
|
|
|
|
|
break; |
474
|
|
|
|
|
|
|
# endif /* USE_TLS_1_2 */ |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
# ifdef USE_STATELESS_SESSION_TICKETS |
477
|
|
|
|
|
|
|
/**************************************************************************/ |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
case EXT_SESSION_TICKET: |
480
|
|
|
|
|
|
|
/* Have a handy place to store this info. Tickets are |
481
|
|
|
|
|
|
|
the only way a server will make use of 'sid'. |
482
|
|
|
|
|
|
|
Could already exist if rehandshake case here */ |
483
|
0
|
0
|
|
|
|
|
if (ssl->sid == NULL) |
484
|
|
|
|
|
|
|
{ |
485
|
|
|
|
|
|
|
/* Server just needs a spot to manage the state |
486
|
|
|
|
|
|
|
of the negotiation. Uses the sessionTicketState |
487
|
|
|
|
|
|
|
of this structure */ |
488
|
0
|
|
|
|
|
|
ssl->sid = psMalloc(ssl->sPool, sizeof(sslSessionId_t)); |
489
|
0
|
0
|
|
|
|
|
if (ssl->sid == NULL) |
490
|
|
|
|
|
|
|
{ |
491
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_INTERNAL_ERROR; |
492
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
493
|
|
|
|
|
|
|
} |
494
|
0
|
|
|
|
|
|
memset(ssl->sid, 0x0, sizeof(sslSessionId_t)); |
495
|
0
|
|
|
|
|
|
ssl->sid->pool = ssl->sPool; |
496
|
|
|
|
|
|
|
} |
497
|
0
|
0
|
|
|
|
|
if (extLen > 0) /* received a ticket */ |
498
|
|
|
|
|
|
|
{ |
499
|
0
|
|
|
|
|
|
ssl->extFlags.session_ticket = 1; |
500
|
|
|
|
|
|
|
|
501
|
0
|
0
|
|
|
|
|
if (matrixUnlockSessionTicket(ssl, (unsigned char *) c, extLen) == |
502
|
|
|
|
|
|
|
PS_SUCCESS) |
503
|
|
|
|
|
|
|
{ |
504
|
|
|
|
|
|
|
/* Understood the token */ |
505
|
0
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_RESUMED; |
506
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = SESS_TICKET_STATE_USING_TICKET; |
507
|
0
|
|
|
|
|
|
memcpy(ssl->sec.masterSecret, ssl->sid->masterSecret, |
508
|
|
|
|
|
|
|
SSL_HS_MASTER_SIZE); |
509
|
|
|
|
|
|
|
# ifdef USE_MATRIXSSL_STATS |
510
|
|
|
|
|
|
|
matrixsslUpdateStat(ssl, RESUMPTIONS_STAT, 1); |
511
|
|
|
|
|
|
|
# endif |
512
|
|
|
|
|
|
|
} |
513
|
|
|
|
|
|
|
else |
514
|
|
|
|
|
|
|
{ |
515
|
|
|
|
|
|
|
/* If client sent a sessionId in the hello, |
516
|
|
|
|
|
|
|
we can ignore that here now */ |
517
|
0
|
0
|
|
|
|
|
if (ssl->sessionIdLen > 0) |
518
|
|
|
|
|
|
|
{ |
519
|
0
|
|
|
|
|
|
memset(ssl->sessionId, 0, SSL_MAX_SESSION_ID_SIZE); |
520
|
0
|
|
|
|
|
|
ssl->sessionIdLen = 0; |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
/* Issue another one if we have any keys */ |
523
|
0
|
0
|
|
|
|
|
if (ssl->keys && ssl->keys->sessTickets) |
|
|
0
|
|
|
|
|
|
524
|
|
|
|
|
|
|
{ |
525
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = SESS_TICKET_STATE_RECVD_EXT; |
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
else |
528
|
|
|
|
|
|
|
{ |
529
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = SESS_TICKET_STATE_INIT; |
530
|
|
|
|
|
|
|
} |
531
|
|
|
|
|
|
|
# ifdef USE_MATRIXSSL_STATS |
532
|
|
|
|
|
|
|
matrixsslUpdateStat(ssl, FAILED_RESUMPTIONS_STAT, 1); |
533
|
|
|
|
|
|
|
# endif |
534
|
|
|
|
|
|
|
} |
535
|
|
|
|
|
|
|
} |
536
|
|
|
|
|
|
|
else |
537
|
|
|
|
|
|
|
{ |
538
|
|
|
|
|
|
|
/* Request for session ticket. Can we honor? */ |
539
|
0
|
0
|
|
|
|
|
if (ssl->keys && ssl->keys->sessTickets) |
|
|
0
|
|
|
|
|
|
540
|
|
|
|
|
|
|
{ |
541
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = SESS_TICKET_STATE_RECVD_EXT; |
542
|
|
|
|
|
|
|
} |
543
|
|
|
|
|
|
|
else |
544
|
|
|
|
|
|
|
{ |
545
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = SESS_TICKET_STATE_INIT; |
546
|
|
|
|
|
|
|
} |
547
|
|
|
|
|
|
|
} |
548
|
0
|
|
|
|
|
|
break; |
549
|
|
|
|
|
|
|
# endif /* USE_STATELESS_SESSION_TICKETS */ |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
# ifdef USE_ECC_CIPHER_SUITE |
552
|
|
|
|
|
|
|
/**************************************************************************/ |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
case EXT_ELLIPTIC_CURVE: |
555
|
|
|
|
|
|
|
/* Minimum is 2 b dataLen and 2 b cipher */ |
556
|
1148
|
50
|
|
|
|
|
if (extLen < 4) |
557
|
|
|
|
|
|
|
{ |
558
|
|
|
|
|
|
|
psTraceInfo("Invalid ECC Curve len\n"); |
559
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
560
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
561
|
|
|
|
|
|
|
} |
562
|
1148
|
|
|
|
|
|
dataLen = *c << 8; c++; |
563
|
1148
|
|
|
|
|
|
dataLen += *c; c++; |
564
|
1148
|
|
|
|
|
|
extLen -= 2; |
565
|
1148
|
50
|
|
|
|
|
if (dataLen > extLen || dataLen < 2 || (dataLen & 1)) |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
566
|
|
|
|
|
|
|
{ |
567
|
|
|
|
|
|
|
psTraceInfo("Malformed ECC Curve extension\n"); |
568
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
569
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
570
|
|
|
|
|
|
|
} |
571
|
|
|
|
|
|
|
/* Matching EC curve logic */ |
572
|
1148
|
|
|
|
|
|
ecFlags = IS_RECVD_EXT; /* Flag if we got it */ |
573
|
1148
|
|
|
|
|
|
ssl->ecInfo.ecCurveId = 0; |
574
|
6888
|
100
|
|
|
|
|
while (dataLen >= 2 && extLen >= 2) |
|
|
50
|
|
|
|
|
|
575
|
|
|
|
|
|
|
{ |
576
|
5740
|
|
|
|
|
|
curveId = *c << 8; c++; |
577
|
5740
|
|
|
|
|
|
curveId += *c; c++; |
578
|
5740
|
|
|
|
|
|
dataLen -= 2; |
579
|
5740
|
|
|
|
|
|
extLen -= 2; |
580
|
|
|
|
|
|
|
/* |
581
|
|
|
|
|
|
|
Find the curves that are in common between client and server. |
582
|
|
|
|
|
|
|
ssl->ecInfo.ecFlags defaults to all curves compiled into the library. |
583
|
|
|
|
|
|
|
*/ |
584
|
5740
|
50
|
|
|
|
|
if (psTestUserEcID(curveId, ssl->ecInfo.ecFlags) == 0) |
585
|
|
|
|
|
|
|
{ |
586
|
|
|
|
|
|
|
/* |
587
|
|
|
|
|
|
|
Client sends curves in priority order, so choose the first |
588
|
|
|
|
|
|
|
one we have in common. If ECDHE, it will be used after |
589
|
|
|
|
|
|
|
this CLIENT_HELLO parse as the ephemeral key gen curve. |
590
|
|
|
|
|
|
|
If ECDH, it will be used to find a matching cert, and for |
591
|
|
|
|
|
|
|
key exchange. |
592
|
|
|
|
|
|
|
*/ |
593
|
5740
|
100
|
|
|
|
|
if (ecFlags == IS_RECVD_EXT) |
594
|
|
|
|
|
|
|
{ |
595
|
1148
|
|
|
|
|
|
ssl->ecInfo.ecCurveId = curveId; |
596
|
|
|
|
|
|
|
} |
597
|
5740
|
|
|
|
|
|
ecFlags |= curveIdToFlag(curveId); |
598
|
|
|
|
|
|
|
} |
599
|
|
|
|
|
|
|
} |
600
|
1148
|
|
|
|
|
|
ssl->ecInfo.ecFlags = ecFlags; |
601
|
1148
|
|
|
|
|
|
break; |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
/**************************************************************************/ |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
case EXT_ELLIPTIC_POINTS: |
606
|
1148
|
50
|
|
|
|
|
if (extLen < 1) |
607
|
|
|
|
|
|
|
{ |
608
|
|
|
|
|
|
|
psTraceInfo("Invaid ECC Points len\n"); |
609
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
610
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
611
|
|
|
|
|
|
|
} |
612
|
1148
|
|
|
|
|
|
dataLen = *c; c++; /* single byte data len */ |
613
|
1148
|
|
|
|
|
|
extLen -= 1; |
614
|
1148
|
50
|
|
|
|
|
if (dataLen > extLen || dataLen < 1) |
|
|
50
|
|
|
|
|
|
615
|
|
|
|
|
|
|
{ |
616
|
|
|
|
|
|
|
psTraceInfo("Malformed ECC Points extension\n"); |
617
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
618
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
619
|
|
|
|
|
|
|
} |
620
|
|
|
|
|
|
|
/* One of them has to be a zero (uncompressed) and that |
621
|
|
|
|
|
|
|
is all we are looking for at the moment */ |
622
|
1148
|
50
|
|
|
|
|
if (memchr(c, '\0', dataLen) == NULL) |
623
|
|
|
|
|
|
|
{ |
624
|
|
|
|
|
|
|
psTraceInfo("ECC Uncommpressed Points missing\n"); |
625
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
626
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
627
|
|
|
|
|
|
|
} |
628
|
1148
|
|
|
|
|
|
break; |
629
|
|
|
|
|
|
|
# endif /* USE_ECC_CIPHER_SUITE */ |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
# ifdef USE_OCSP |
632
|
|
|
|
|
|
|
case EXT_STATUS_REQUEST: |
633
|
|
|
|
|
|
|
/* Validation of minimum size and status_type of 1 (ocsp) */ |
634
|
0
|
0
|
|
|
|
|
if (extLen < 5 || *c != 0x1) |
|
|
0
|
|
|
|
|
|
635
|
|
|
|
|
|
|
{ |
636
|
|
|
|
|
|
|
psTraceIntInfo("Bad cert_status_request extension: %d\n", extType); |
637
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
638
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
639
|
|
|
|
|
|
|
} |
640
|
0
|
|
|
|
|
|
c++; extLen--; /* checked status type above */ |
641
|
|
|
|
|
|
|
/* Skipping the ResponderIDs */ |
642
|
0
|
|
|
|
|
|
dataLen = *c << 8; c++; extLen--; |
643
|
0
|
|
|
|
|
|
dataLen += *c; c++; extLen--; |
644
|
0
|
0
|
|
|
|
|
if (dataLen + 2 > extLen) |
645
|
|
|
|
|
|
|
{ |
646
|
|
|
|
|
|
|
psTraceIntInfo("Bad cert_status_request extension: \n", extType); |
647
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
648
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
649
|
|
|
|
|
|
|
} |
650
|
0
|
|
|
|
|
|
c += dataLen; |
651
|
|
|
|
|
|
|
/* Skipping the Extensions */ |
652
|
0
|
|
|
|
|
|
dataLen = *c << 8; c++; extLen--; |
653
|
0
|
|
|
|
|
|
dataLen += *c; c++; extLen--; |
654
|
0
|
0
|
|
|
|
|
if (dataLen > extLen) |
655
|
|
|
|
|
|
|
{ |
656
|
|
|
|
|
|
|
psTraceIntInfo("Bad cert_status_request extension: \n", extType); |
657
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
658
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
659
|
|
|
|
|
|
|
} |
660
|
0
|
|
|
|
|
|
c += dataLen; |
661
|
|
|
|
|
|
|
/* Currently, the OCSPResponse must be loaded into the key material |
662
|
|
|
|
|
|
|
so we check if that exists to determine if we will reply with |
663
|
|
|
|
|
|
|
the extension and CERTIFICATE_STATUS handshake message */ |
664
|
0
|
0
|
|
|
|
|
if (ssl->keys->OCSPResponseBufLen > 0 && |
|
|
0
|
|
|
|
|
|
665
|
0
|
|
|
|
|
|
ssl->keys->OCSPResponseBuf != NULL) |
666
|
|
|
|
|
|
|
{ |
667
|
0
|
|
|
|
|
|
ssl->extFlags.status_request = 1; |
668
|
|
|
|
|
|
|
} |
669
|
|
|
|
|
|
|
else |
670
|
|
|
|
|
|
|
{ |
671
|
|
|
|
|
|
|
psTraceInfo("Client requesting OCSP but we have no response\n"); |
672
|
|
|
|
|
|
|
} |
673
|
|
|
|
|
|
|
|
674
|
0
|
|
|
|
|
|
break; |
675
|
|
|
|
|
|
|
# endif |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
/**************************************************************************/ |
678
|
|
|
|
|
|
|
#ifdef USE_SCT |
679
|
|
|
|
|
|
|
case EXT_SIGNED_CERTIFICATE_TIMESTAMP: |
680
|
|
|
|
|
|
|
/* TODO: add client extension parsing */ |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
/* Currently, the SCTResponse must be loaded into the key material |
683
|
|
|
|
|
|
|
so we check if that exists to determine if we will reply with |
684
|
|
|
|
|
|
|
the extension */ |
685
|
0
|
0
|
|
|
|
|
if (ssl->keys->SCTResponseBufLen > 0 && |
|
|
0
|
|
|
|
|
|
686
|
0
|
|
|
|
|
|
ssl->keys->SCTResponseBuf != NULL) { |
687
|
0
|
|
|
|
|
|
ssl->extFlags.signed_certificate_timestamp = 1; |
688
|
|
|
|
|
|
|
} else { |
689
|
|
|
|
|
|
|
psTraceInfo("Client requesting SCT but we have no response\n"); |
690
|
|
|
|
|
|
|
} |
691
|
|
|
|
|
|
|
|
692
|
0
|
|
|
|
|
|
break; |
693
|
|
|
|
|
|
|
#endif |
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
/**************************************************************************/ |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
default: |
698
|
|
|
|
|
|
|
psTraceIntInfo("Ignoring unknown extension: %d\n", extType); |
699
|
0
|
|
|
|
|
|
break; |
700
|
|
|
|
|
|
|
} |
701
|
4601
|
|
|
|
|
|
return PS_SUCCESS; |
702
|
|
|
|
|
|
|
} |
703
|
|
|
|
|
|
|
|
704
|
|
|
|
|
|
|
# ifdef USE_ALPN |
705
|
|
|
|
|
|
|
/**************************************************************************/ |
706
|
|
|
|
|
|
|
/* |
707
|
|
|
|
|
|
|
Parse Application Layer Protocol extension and invoke callback. No need |
708
|
|
|
|
|
|
|
to advance any buffer pointers, caller is managing. |
709
|
|
|
|
|
|
|
*/ |
710
|
0
|
|
|
|
|
|
static int dealWithAlpnExt(ssl_t *ssl, const unsigned char *c, unsigned short extLen) |
711
|
|
|
|
|
|
|
{ |
712
|
|
|
|
|
|
|
int32 totLen, i, userChoice; |
713
|
|
|
|
|
|
|
unsigned char *end; |
714
|
|
|
|
|
|
|
char *proto[MAX_PROTO_EXT]; |
715
|
|
|
|
|
|
|
int32 protoLen[MAX_PROTO_EXT]; |
716
|
|
|
|
|
|
|
|
717
|
0
|
|
|
|
|
|
end = (unsigned char *) c + extLen; |
718
|
|
|
|
|
|
|
|
719
|
0
|
|
|
|
|
|
totLen = *c << 8; c++; |
720
|
0
|
|
|
|
|
|
totLen += *c; c++; |
721
|
0
|
0
|
|
|
|
|
if (totLen != extLen - 2) |
722
|
|
|
|
|
|
|
{ |
723
|
0
|
|
|
|
|
|
return PS_PARSE_FAIL; |
724
|
|
|
|
|
|
|
} |
725
|
|
|
|
|
|
|
|
726
|
0
|
0
|
|
|
|
|
for (i = 0; totLen > 0; i++) |
727
|
|
|
|
|
|
|
{ |
728
|
0
|
0
|
|
|
|
|
if (i + 1 > MAX_PROTO_EXT) |
729
|
|
|
|
|
|
|
{ |
730
|
0
|
|
|
|
|
|
i--; |
731
|
0
|
|
|
|
|
|
break; |
732
|
|
|
|
|
|
|
} |
733
|
0
|
|
|
|
|
|
protoLen[i] = *c; c++; totLen--; |
734
|
0
|
0
|
|
|
|
|
if (protoLen[i] > totLen) |
735
|
|
|
|
|
|
|
{ |
736
|
0
|
0
|
|
|
|
|
while (i > 0) |
737
|
|
|
|
|
|
|
{ |
738
|
0
|
|
|
|
|
|
psFree(proto[i - 1], ssl->sPool); |
739
|
0
|
|
|
|
|
|
i--; |
740
|
|
|
|
|
|
|
} |
741
|
0
|
|
|
|
|
|
return PS_PARSE_FAIL; |
742
|
|
|
|
|
|
|
} |
743
|
0
|
0
|
|
|
|
|
if ((proto[i] = psMalloc(ssl->sPool, protoLen[i])) == NULL) |
744
|
|
|
|
|
|
|
{ |
745
|
0
|
0
|
|
|
|
|
while (i > 0) |
746
|
|
|
|
|
|
|
{ |
747
|
0
|
|
|
|
|
|
psFree(proto[i - 1], ssl->sPool); |
748
|
0
|
|
|
|
|
|
i--; |
749
|
|
|
|
|
|
|
} |
750
|
0
|
|
|
|
|
|
return PS_MEM_FAIL; |
751
|
|
|
|
|
|
|
} |
752
|
0
|
|
|
|
|
|
memcpy(proto[i], c, protoLen[i]); |
753
|
0
|
|
|
|
|
|
totLen -= protoLen[i]; |
754
|
0
|
|
|
|
|
|
c += protoLen[i]; |
755
|
|
|
|
|
|
|
} |
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
/* see if they touch it. Using a value outside the range to gauge */ |
758
|
0
|
|
|
|
|
|
userChoice = MAX_PROTO_EXT; |
759
|
|
|
|
|
|
|
|
760
|
|
|
|
|
|
|
/* Already tested if callback exists */ |
761
|
0
|
|
|
|
|
|
(*ssl->srv_alpn_cb)((void *) ssl, (short) i, proto, protoLen, &userChoice); |
762
|
|
|
|
|
|
|
|
763
|
0
|
0
|
|
|
|
|
if (userChoice == MAX_PROTO_EXT) |
764
|
|
|
|
|
|
|
{ |
765
|
|
|
|
|
|
|
/* User chose to completely ignore. No reply extension will be sent */ |
766
|
0
|
0
|
|
|
|
|
while (i > 0) |
767
|
|
|
|
|
|
|
{ |
768
|
0
|
|
|
|
|
|
psFree(proto[i - 1], ssl->sPool); |
769
|
0
|
|
|
|
|
|
i--; |
770
|
|
|
|
|
|
|
} |
771
|
0
|
|
|
|
|
|
return PS_SUCCESS; |
772
|
|
|
|
|
|
|
} |
773
|
0
|
0
|
|
|
|
|
if (userChoice >= i) |
774
|
|
|
|
|
|
|
{ |
775
|
|
|
|
|
|
|
/* User chose something completely unreasonable */ |
776
|
0
|
0
|
|
|
|
|
while (i > 0) |
777
|
|
|
|
|
|
|
{ |
778
|
0
|
|
|
|
|
|
psFree(proto[i - 1], ssl->sPool); |
779
|
0
|
|
|
|
|
|
i--; |
780
|
|
|
|
|
|
|
} |
781
|
0
|
|
|
|
|
|
return PS_LIMIT_FAIL; |
782
|
|
|
|
|
|
|
} |
783
|
|
|
|
|
|
|
|
784
|
0
|
0
|
|
|
|
|
if (userChoice < 0) |
785
|
|
|
|
|
|
|
{ |
786
|
|
|
|
|
|
|
/* They actually rejected these completely. Returning the |
787
|
|
|
|
|
|
|
no-application-protocol alert per the spec */ |
788
|
0
|
0
|
|
|
|
|
while (i > 0) |
789
|
|
|
|
|
|
|
{ |
790
|
0
|
|
|
|
|
|
psFree(proto[i - 1], ssl->sPool); |
791
|
0
|
|
|
|
|
|
i--; |
792
|
|
|
|
|
|
|
} |
793
|
0
|
|
|
|
|
|
return PS_PROTOCOL_FAIL; |
794
|
|
|
|
|
|
|
} |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
/* Allocated to session pool so fine to point to it and just skip |
797
|
|
|
|
|
|
|
freeing it while cleaning up here */ |
798
|
0
|
|
|
|
|
|
ssl->alpn = proto[userChoice]; |
799
|
0
|
|
|
|
|
|
ssl->alpnLen = protoLen[userChoice]; |
800
|
|
|
|
|
|
|
|
801
|
0
|
0
|
|
|
|
|
while (i > 0) |
802
|
|
|
|
|
|
|
{ |
803
|
0
|
0
|
|
|
|
|
if (i - 1 != userChoice) |
804
|
|
|
|
|
|
|
{ |
805
|
0
|
|
|
|
|
|
psFree(proto[i - 1], ssl->sPool); |
806
|
|
|
|
|
|
|
} |
807
|
0
|
|
|
|
|
|
i--; |
808
|
|
|
|
|
|
|
} |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
/** HTTP2 places some constraints on TLS configuration, so flag |
811
|
|
|
|
|
|
|
that here for checking later (in choosing cipher suite, etc). |
812
|
|
|
|
|
|
|
@see https://tools.ietf.org/html/rfc7540#section-9.2 |
813
|
|
|
|
|
|
|
*/ |
814
|
0
|
0
|
|
|
|
|
if ((ssl->alpnLen == 2) && (memcmp(ssl->alpn, "h2", 2) == 0)) |
|
|
0
|
|
|
|
|
|
815
|
|
|
|
|
|
|
{ |
816
|
0
|
|
|
|
|
|
ssl->flags |= SSL_FLAGS_HTTP2; |
817
|
|
|
|
|
|
|
} |
818
|
|
|
|
|
|
|
|
819
|
0
|
|
|
|
|
|
return PS_SUCCESS; |
820
|
|
|
|
|
|
|
} |
821
|
|
|
|
|
|
|
# endif /* USE_ALPN */ |
822
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
#endif /* USE_SERVER_SIDE_SSL */ |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
#ifdef USE_CLIENT_SIDE_SSL |
826
|
|
|
|
|
|
|
/******************************************************************************/ |
827
|
|
|
|
|
|
|
/* |
828
|
|
|
|
|
|
|
Parse the ServerHello extension list. |
829
|
|
|
|
|
|
|
*/ |
830
|
1150
|
|
|
|
|
|
int32 parseServerHelloExtensions(ssl_t *ssl, int32 hsLen, |
831
|
|
|
|
|
|
|
unsigned char *extData, unsigned char **cp, |
832
|
|
|
|
|
|
|
unsigned short len) |
833
|
|
|
|
|
|
|
{ |
834
|
|
|
|
|
|
|
unsigned short extLen, extType; |
835
|
|
|
|
|
|
|
int32 rc; |
836
|
|
|
|
|
|
|
unsigned char *c, *end; |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
# ifdef ENABLE_SECURE_REHANDSHAKES |
839
|
1150
|
|
|
|
|
|
unsigned short renegotiationExtSent = 0; |
840
|
|
|
|
|
|
|
# endif |
841
|
|
|
|
|
|
|
|
842
|
1150
|
|
|
|
|
|
rc = PS_SUCCESS; |
843
|
1150
|
|
|
|
|
|
c = *cp; |
844
|
1150
|
|
|
|
|
|
end = c + len; |
845
|
|
|
|
|
|
|
|
846
|
1150
|
50
|
|
|
|
|
if (end - c < 2) |
847
|
|
|
|
|
|
|
{ |
848
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
849
|
|
|
|
|
|
|
psTraceInfo("Invalid extension header len\n"); |
850
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
851
|
|
|
|
|
|
|
} |
852
|
1150
|
|
|
|
|
|
extLen = *c << 8; c++; /* Total length of list */ |
853
|
1150
|
|
|
|
|
|
extLen += *c; c++; |
854
|
1150
|
50
|
|
|
|
|
if ((uint32) (end - c) < extLen) |
855
|
|
|
|
|
|
|
{ |
856
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
857
|
|
|
|
|
|
|
psTraceInfo("Invalid extension header len\n"); |
858
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
859
|
|
|
|
|
|
|
} |
860
|
4599
|
100
|
|
|
|
|
while ((int32) hsLen > (c - extData)) |
861
|
|
|
|
|
|
|
{ |
862
|
3449
|
|
|
|
|
|
extType = *c << 8; c++; /* Individual hello ext */ |
863
|
3449
|
|
|
|
|
|
extType += *c; c++; |
864
|
3449
|
50
|
|
|
|
|
if (end - c < 2) |
865
|
|
|
|
|
|
|
{ |
866
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
867
|
|
|
|
|
|
|
psTraceInfo("Invalid extension header len\n"); |
868
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
869
|
|
|
|
|
|
|
} |
870
|
3449
|
|
|
|
|
|
extLen = *c << 8; c++; /* Length of individual extension */ |
871
|
3449
|
|
|
|
|
|
extLen += *c; c++; |
872
|
3449
|
50
|
|
|
|
|
if ((uint32) (end - c) < extLen) |
873
|
|
|
|
|
|
|
{ |
874
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_DECODE_ERROR; |
875
|
|
|
|
|
|
|
psTraceInfo("Invalid extension header len\n"); |
876
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
877
|
|
|
|
|
|
|
} |
878
|
|
|
|
|
|
|
# ifdef ENABLE_SECURE_REHANDSHAKES |
879
|
3449
|
100
|
|
|
|
|
if (extType == EXT_RENEGOTIATION_INFO) |
880
|
|
|
|
|
|
|
{ |
881
|
1150
|
|
|
|
|
|
renegotiationExtSent = 1; |
882
|
|
|
|
|
|
|
} |
883
|
|
|
|
|
|
|
# endif |
884
|
3449
|
50
|
|
|
|
|
if ((rc = ServerHelloExt(ssl, extType, extLen, c)) < 0) |
885
|
|
|
|
|
|
|
{ |
886
|
|
|
|
|
|
|
/* On error, ssl->error will have been set */ |
887
|
0
|
|
|
|
|
|
return rc; |
888
|
|
|
|
|
|
|
} |
889
|
3449
|
|
|
|
|
|
c += extLen; |
890
|
|
|
|
|
|
|
} |
891
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
/* Enforce the rules for extensions that require the server to send |
893
|
|
|
|
|
|
|
something back to us */ |
894
|
|
|
|
|
|
|
|
895
|
1150
|
50
|
|
|
|
|
if (ssl->extFlags.req_extended_master_secret == 1) |
896
|
|
|
|
|
|
|
{ |
897
|
|
|
|
|
|
|
/* The req_extended_master_secret is reset to 0 when the server sends |
898
|
|
|
|
|
|
|
one so this case means the server doesn't support it */ |
899
|
0
|
0
|
|
|
|
|
if (ssl->extFlags.require_extended_master_secret == 1) |
900
|
|
|
|
|
|
|
{ |
901
|
|
|
|
|
|
|
psTraceInfo("Server doesn't support extended master secret\n"); |
902
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
903
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
904
|
|
|
|
|
|
|
} |
905
|
|
|
|
|
|
|
} |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
# ifdef USE_OCSP_MUST_STAPLE |
908
|
1150
|
50
|
|
|
|
|
if (ssl->extFlags.req_status_request == 1) |
909
|
|
|
|
|
|
|
{ |
910
|
0
|
0
|
|
|
|
|
if (ssl->extFlags.status_request == 0) |
911
|
|
|
|
|
|
|
{ |
912
|
|
|
|
|
|
|
psTraceInfo("Server doesn't support OCSP stapling\n"); |
913
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
914
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
915
|
|
|
|
|
|
|
} |
916
|
|
|
|
|
|
|
} |
917
|
|
|
|
|
|
|
# endif |
918
|
|
|
|
|
|
|
|
919
|
|
|
|
|
|
|
# ifdef ENABLE_SECURE_REHANDSHAKES |
920
|
1150
|
50
|
|
|
|
|
if (!renegotiationExtSent) |
921
|
|
|
|
|
|
|
{ |
922
|
|
|
|
|
|
|
# ifdef REQUIRE_SECURE_REHANDSHAKES |
923
|
|
|
|
|
|
|
/* Check if SCSV was sent instead */ |
924
|
0
|
0
|
|
|
|
|
if (ssl->secureRenegotiationFlag == PS_FALSE && |
|
|
0
|
|
|
|
|
|
925
|
0
|
|
|
|
|
|
ssl->myVerifyDataLen == 0) |
926
|
|
|
|
|
|
|
{ |
927
|
|
|
|
|
|
|
psTraceInfo("Server doesn't support renegotiation hello\n"); |
928
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
929
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
930
|
|
|
|
|
|
|
} |
931
|
|
|
|
|
|
|
# endif /* REQUIRE_SECURE_REHANDSHAKES */ |
932
|
0
|
0
|
|
|
|
|
if (ssl->secureRenegotiationFlag == PS_TRUE && |
|
|
0
|
|
|
|
|
|
933
|
0
|
|
|
|
|
|
ssl->myVerifyDataLen > 0) |
934
|
|
|
|
|
|
|
{ |
935
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
936
|
|
|
|
|
|
|
psTraceInfo("Server missing renegotiationInfo on re-hndshk\n"); |
937
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
938
|
|
|
|
|
|
|
} |
939
|
|
|
|
|
|
|
# ifndef ENABLE_INSECURE_REHANDSHAKES |
940
|
0
|
0
|
|
|
|
|
if (ssl->secureRenegotiationFlag == PS_FALSE && |
|
|
0
|
|
|
|
|
|
941
|
0
|
|
|
|
|
|
ssl->myVerifyDataLen > 0) |
942
|
|
|
|
|
|
|
{ |
943
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
944
|
|
|
|
|
|
|
psTraceInfo("Server attempting insecure handshake\n"); |
945
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
946
|
|
|
|
|
|
|
} |
947
|
|
|
|
|
|
|
# endif /* !ENABLE_INSECURE_REHANDSHAKES */ |
948
|
|
|
|
|
|
|
} |
949
|
|
|
|
|
|
|
# endif /* ENABLE_SECURE_REHANDSHAKES */ |
950
|
|
|
|
|
|
|
|
951
|
1150
|
|
|
|
|
|
*cp = c; |
952
|
1150
|
|
|
|
|
|
return rc; |
953
|
|
|
|
|
|
|
} |
954
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
/******************************************************************************/ |
956
|
|
|
|
|
|
|
/* |
957
|
|
|
|
|
|
|
Parse the ServerHello extension list. |
958
|
|
|
|
|
|
|
*/ |
959
|
3449
|
|
|
|
|
|
static int ServerHelloExt(ssl_t *ssl, unsigned short extType, unsigned short extLen, |
960
|
|
|
|
|
|
|
const unsigned char *c) |
961
|
|
|
|
|
|
|
{ |
962
|
|
|
|
|
|
|
int rc; |
963
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
/* Verify the server only responds with an extension the client requested. |
965
|
|
|
|
|
|
|
Zero the value once seen so that it will catch the error if sent twice */ |
966
|
3449
|
|
|
|
|
|
rc = -1; |
967
|
3449
|
|
|
|
|
|
switch (extType) |
968
|
|
|
|
|
|
|
{ |
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
/**************************************************************************/ |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
case EXT_SNI: |
973
|
0
|
0
|
|
|
|
|
if (ssl->extFlags.req_sni) |
974
|
|
|
|
|
|
|
{ |
975
|
0
|
|
|
|
|
|
ssl->extFlags.req_sni = 0; |
976
|
0
|
0
|
|
|
|
|
if (ssl->extCb) |
977
|
|
|
|
|
|
|
{ |
978
|
0
|
|
|
|
|
|
rc = (*ssl->extCb)(ssl, extType, extLen, (void *) c); |
979
|
|
|
|
|
|
|
} |
980
|
|
|
|
|
|
|
else |
981
|
|
|
|
|
|
|
{ |
982
|
0
|
|
|
|
|
|
rc = 0; |
983
|
|
|
|
|
|
|
} |
984
|
|
|
|
|
|
|
} |
985
|
0
|
|
|
|
|
|
break; |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
/**************************************************************************/ |
988
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
case EXT_MAX_FRAGMENT_LEN: |
990
|
0
|
0
|
|
|
|
|
if (ssl->extFlags.req_max_fragment_len) |
991
|
|
|
|
|
|
|
{ |
992
|
0
|
|
|
|
|
|
ssl->extFlags.req_max_fragment_len = 0; |
993
|
0
|
|
|
|
|
|
rc = 0; |
994
|
|
|
|
|
|
|
} |
995
|
0
|
0
|
|
|
|
|
if (!(ssl->maxPtFrag & 0x10000)) |
996
|
|
|
|
|
|
|
{ |
997
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
998
|
|
|
|
|
|
|
psTraceInfo("Server sent unexpected MAX_FRAG ext\n"); |
999
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1000
|
|
|
|
|
|
|
} |
1001
|
0
|
0
|
|
|
|
|
if (extLen != 1) |
1002
|
|
|
|
|
|
|
{ |
1003
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
1004
|
|
|
|
|
|
|
psTraceInfo("Server sent bad MAX_FRAG ext\n"); |
1005
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1006
|
|
|
|
|
|
|
} |
1007
|
|
|
|
|
|
|
/* Confirm it's the same size we requested and strip |
1008
|
|
|
|
|
|
|
off 0x10000 from maxPtrFrag */ |
1009
|
0
|
0
|
|
|
|
|
if (*c == 0x01 && |
|
|
0
|
|
|
|
|
|
1010
|
0
|
|
|
|
|
|
(ssl->maxPtFrag & 0x200)) |
1011
|
|
|
|
|
|
|
{ |
1012
|
0
|
|
|
|
|
|
ssl->maxPtFrag = 0x200; |
1013
|
|
|
|
|
|
|
} |
1014
|
0
|
0
|
|
|
|
|
else if (*c == 0x02 && |
|
|
0
|
|
|
|
|
|
1015
|
0
|
|
|
|
|
|
(ssl->maxPtFrag & 0x400)) |
1016
|
|
|
|
|
|
|
{ |
1017
|
0
|
|
|
|
|
|
ssl->maxPtFrag = 0x400; |
1018
|
|
|
|
|
|
|
} |
1019
|
0
|
0
|
|
|
|
|
else if (*c == 0x03 && |
|
|
0
|
|
|
|
|
|
1020
|
0
|
|
|
|
|
|
(ssl->maxPtFrag & 0x800)) |
1021
|
|
|
|
|
|
|
{ |
1022
|
0
|
|
|
|
|
|
ssl->maxPtFrag = 0x800; |
1023
|
|
|
|
|
|
|
} |
1024
|
0
|
0
|
|
|
|
|
else if (*c == 0x04 && |
|
|
0
|
|
|
|
|
|
1025
|
0
|
|
|
|
|
|
(ssl->maxPtFrag & 0x1000)) |
1026
|
|
|
|
|
|
|
{ |
1027
|
0
|
|
|
|
|
|
ssl->maxPtFrag = 0x1000; |
1028
|
|
|
|
|
|
|
} |
1029
|
|
|
|
|
|
|
else |
1030
|
|
|
|
|
|
|
{ |
1031
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
1032
|
|
|
|
|
|
|
psTraceInfo("Server sent mismatched MAX_FRAG ext\n"); |
1033
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1034
|
|
|
|
|
|
|
} |
1035
|
0
|
|
|
|
|
|
c++; extLen--; |
1036
|
0
|
|
|
|
|
|
break; |
1037
|
|
|
|
|
|
|
|
1038
|
|
|
|
|
|
|
/**************************************************************************/ |
1039
|
|
|
|
|
|
|
|
1040
|
|
|
|
|
|
|
case EXT_TRUNCATED_HMAC: |
1041
|
0
|
0
|
|
|
|
|
if (ssl->extFlags.req_truncated_hmac) |
1042
|
|
|
|
|
|
|
{ |
1043
|
0
|
|
|
|
|
|
ssl->extFlags.req_truncated_hmac = 0; |
1044
|
0
|
|
|
|
|
|
rc = 0; |
1045
|
|
|
|
|
|
|
} |
1046
|
0
|
0
|
|
|
|
|
if (extLen != 0) |
1047
|
|
|
|
|
|
|
{ |
1048
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
1049
|
|
|
|
|
|
|
psTraceInfo("Server sent bad truncated hmac ext\n"); |
1050
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1051
|
|
|
|
|
|
|
} |
1052
|
0
|
|
|
|
|
|
ssl->extFlags.truncated_hmac = 1; |
1053
|
0
|
|
|
|
|
|
break; |
1054
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
case EXT_EXTENDED_MASTER_SECRET: |
1056
|
1150
|
50
|
|
|
|
|
if (ssl->extFlags.req_extended_master_secret) |
1057
|
|
|
|
|
|
|
{ |
1058
|
1150
|
|
|
|
|
|
ssl->extFlags.req_extended_master_secret = 0; |
1059
|
1150
|
|
|
|
|
|
rc = 0; |
1060
|
|
|
|
|
|
|
} |
1061
|
1150
|
50
|
|
|
|
|
if (extLen != 0) |
1062
|
|
|
|
|
|
|
{ |
1063
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
1064
|
|
|
|
|
|
|
psTraceInfo("Server sent bad extended master secret ext\n"); |
1065
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1066
|
|
|
|
|
|
|
} |
1067
|
1150
|
|
|
|
|
|
ssl->extFlags.extended_master_secret = 1; |
1068
|
1150
|
|
|
|
|
|
break; |
1069
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
# ifdef USE_ECC_CIPHER_SUITE |
1071
|
|
|
|
|
|
|
/**************************************************************************/ |
1072
|
|
|
|
|
|
|
|
1073
|
|
|
|
|
|
|
case EXT_ELLIPTIC_CURVE: |
1074
|
|
|
|
|
|
|
/* @note we do not allow EXT_ELLIPTIC_CURVE from server */ |
1075
|
0
|
|
|
|
|
|
break; |
1076
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
/**************************************************************************/ |
1078
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
case EXT_ELLIPTIC_POINTS: |
1080
|
1149
|
50
|
|
|
|
|
if (ssl->extFlags.req_elliptic_points) |
1081
|
|
|
|
|
|
|
{ |
1082
|
1149
|
|
|
|
|
|
ssl->extFlags.req_elliptic_points = 0; |
1083
|
1149
|
|
|
|
|
|
rc = 0; |
1084
|
|
|
|
|
|
|
} |
1085
|
1149
|
50
|
|
|
|
|
if (*c++ != (extLen - 1)) |
1086
|
|
|
|
|
|
|
{ |
1087
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
1088
|
|
|
|
|
|
|
psTraceInfo("Server sent bad ECPointFormatList\n"); |
1089
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1090
|
|
|
|
|
|
|
} |
1091
|
1149
|
|
|
|
|
|
extLen--; |
1092
|
1149
|
|
|
|
|
|
break; |
1093
|
|
|
|
|
|
|
# endif /* USE_ECC_CIPHER_SUITE */ |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
/**************************************************************************/ |
1096
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
case EXT_SIGNATURE_ALGORITHMS: |
1098
|
|
|
|
|
|
|
/* @note we do not allow EXT_SIGNATURE_ALGORITHMS from server */ |
1099
|
0
|
|
|
|
|
|
break; |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
/**************************************************************************/ |
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
case EXT_ALPN: |
1104
|
0
|
0
|
|
|
|
|
if (ssl->extFlags.req_alpn) |
1105
|
|
|
|
|
|
|
{ |
1106
|
0
|
|
|
|
|
|
ssl->extFlags.req_alpn = 0; |
1107
|
0
|
0
|
|
|
|
|
if (ssl->extCb) |
1108
|
|
|
|
|
|
|
{ |
1109
|
0
|
|
|
|
|
|
rc = (*ssl->extCb)(ssl, extType, extLen, (void *) c); |
1110
|
|
|
|
|
|
|
} |
1111
|
|
|
|
|
|
|
else |
1112
|
|
|
|
|
|
|
{ |
1113
|
0
|
|
|
|
|
|
rc = 0; |
1114
|
|
|
|
|
|
|
} |
1115
|
|
|
|
|
|
|
} |
1116
|
0
|
|
|
|
|
|
break; |
1117
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
# ifdef USE_STATELESS_SESSION_TICKETS |
1119
|
|
|
|
|
|
|
/**************************************************************************/ |
1120
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
case EXT_SESSION_TICKET: |
1122
|
0
|
0
|
|
|
|
|
if (ssl->extFlags.req_session_ticket) |
1123
|
|
|
|
|
|
|
{ |
1124
|
0
|
|
|
|
|
|
ssl->extFlags.req_session_ticket = 0; |
1125
|
0
|
|
|
|
|
|
rc = 0; |
1126
|
|
|
|
|
|
|
} |
1127
|
0
|
0
|
|
|
|
|
if (ssl->sid && ssl->sid->sessionTicketState == |
|
|
0
|
|
|
|
|
|
1128
|
|
|
|
|
|
|
SESS_TICKET_STATE_SENT_EMPTY) |
1129
|
|
|
|
|
|
|
{ |
1130
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = |
1131
|
|
|
|
|
|
|
SESS_TICKET_STATE_RECVD_EXT; /* expecting ticket */ |
1132
|
|
|
|
|
|
|
} |
1133
|
0
|
0
|
|
|
|
|
else if (ssl->sid && ssl->sid->sessionTicketState == |
|
|
0
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
SESS_TICKET_STATE_SENT_TICKET) |
1135
|
|
|
|
|
|
|
{ |
1136
|
0
|
|
|
|
|
|
ssl->sid->sessionTicketState = |
1137
|
|
|
|
|
|
|
SESS_TICKET_STATE_RECVD_EXT; /* expecting ticket */ |
1138
|
|
|
|
|
|
|
} |
1139
|
|
|
|
|
|
|
else |
1140
|
|
|
|
|
|
|
{ |
1141
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
1142
|
|
|
|
|
|
|
psTraceInfo("Server sent unexpected SESSION_TICKET\n"); |
1143
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1144
|
|
|
|
|
|
|
} |
1145
|
0
|
|
|
|
|
|
break; |
1146
|
|
|
|
|
|
|
# endif /* USE_STATELESS_SESSION_TICKETS */ |
1147
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
# ifdef ENABLE_SECURE_REHANDSHAKES |
1149
|
|
|
|
|
|
|
/**************************************************************************/ |
1150
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
case EXT_RENEGOTIATION_INFO: |
1152
|
1150
|
50
|
|
|
|
|
if (ssl->extFlags.req_renegotiation_info) |
1153
|
|
|
|
|
|
|
{ |
1154
|
1150
|
|
|
|
|
|
ssl->extFlags.req_renegotiation_info = 0; |
1155
|
1150
|
|
|
|
|
|
rc = 0; |
1156
|
|
|
|
|
|
|
} |
1157
|
1150
|
100
|
|
|
|
|
if (ssl->secureRenegotiationFlag == PS_FALSE && |
|
|
50
|
|
|
|
|
|
1158
|
1143
|
|
|
|
|
|
ssl->myVerifyDataLen == 0) |
1159
|
|
|
|
|
|
|
{ |
1160
|
1143
|
50
|
|
|
|
|
if (extLen == 1 && *c == '\0') |
|
|
50
|
|
|
|
|
|
1161
|
|
|
|
|
|
|
{ |
1162
|
1143
|
|
|
|
|
|
ssl->secureRenegotiationFlag = PS_TRUE; |
1163
|
|
|
|
|
|
|
} |
1164
|
|
|
|
|
|
|
else |
1165
|
|
|
|
|
|
|
{ |
1166
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
1167
|
|
|
|
|
|
|
psTraceInfo("Server sent bad renegotiationInfo\n"); |
1168
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1169
|
|
|
|
|
|
|
} |
1170
|
|
|
|
|
|
|
} |
1171
|
7
|
50
|
|
|
|
|
else if (ssl->secureRenegotiationFlag == PS_TRUE && |
|
|
50
|
|
|
|
|
|
1172
|
7
|
|
|
|
|
|
extLen == ((ssl->myVerifyDataLen * 2) + 1)) |
1173
|
|
|
|
|
|
|
{ |
1174
|
7
|
|
|
|
|
|
c++; extLen--; |
1175
|
7
|
50
|
|
|
|
|
if (memcmpct(c, ssl->myVerifyData, |
1176
|
7
|
|
|
|
|
|
ssl->myVerifyDataLen) != 0) |
1177
|
|
|
|
|
|
|
{ |
1178
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
1179
|
|
|
|
|
|
|
psTraceInfo("Srv had bad my renegotiationInfo\n"); |
1180
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1181
|
|
|
|
|
|
|
} |
1182
|
7
|
50
|
|
|
|
|
if (memcmpct(c + ssl->myVerifyDataLen, ssl->peerVerifyData, |
1183
|
7
|
|
|
|
|
|
ssl->peerVerifyDataLen) != 0) |
1184
|
|
|
|
|
|
|
{ |
1185
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
1186
|
|
|
|
|
|
|
psTraceInfo("Srv had bad peer renegotiationInfo\n"); |
1187
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1188
|
|
|
|
|
|
|
} |
1189
|
|
|
|
|
|
|
} |
1190
|
|
|
|
|
|
|
else |
1191
|
|
|
|
|
|
|
{ |
1192
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_HANDSHAKE_FAILURE; |
1193
|
|
|
|
|
|
|
psTraceInfo("Server sent bad renegotiationInfo\n"); |
1194
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1195
|
|
|
|
|
|
|
} |
1196
|
1150
|
|
|
|
|
|
break; |
1197
|
|
|
|
|
|
|
# endif /* ENABLE_SECURE_REHANDSHAKES */ |
1198
|
|
|
|
|
|
|
|
1199
|
|
|
|
|
|
|
case EXT_STATUS_REQUEST: |
1200
|
0
|
0
|
|
|
|
|
if (ssl->extFlags.req_status_request) |
1201
|
|
|
|
|
|
|
{ |
1202
|
|
|
|
|
|
|
/* Weed out the unsolicited status_request */ |
1203
|
0
|
|
|
|
|
|
ssl->extFlags.status_request = 1; |
1204
|
0
|
|
|
|
|
|
rc = 0; |
1205
|
|
|
|
|
|
|
} |
1206
|
0
|
|
|
|
|
|
break; |
1207
|
|
|
|
|
|
|
|
1208
|
|
|
|
|
|
|
|
1209
|
|
|
|
|
|
|
/**************************************************************************/ |
1210
|
|
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
default: |
1212
|
|
|
|
|
|
|
/* We don't recognize the extension, maybe the callback will */ |
1213
|
0
|
0
|
|
|
|
|
if (ssl->extCb) |
1214
|
|
|
|
|
|
|
{ |
1215
|
0
|
|
|
|
|
|
rc = (*ssl->extCb)(ssl, extType, extLen, (void *) c); |
1216
|
|
|
|
|
|
|
} |
1217
|
0
|
|
|
|
|
|
break; |
1218
|
|
|
|
|
|
|
} |
1219
|
|
|
|
|
|
|
|
1220
|
3449
|
50
|
|
|
|
|
if (rc < 0) |
1221
|
|
|
|
|
|
|
{ |
1222
|
0
|
0
|
|
|
|
|
if (ssl->minVer >= TLS_1_2_MIN_VER) |
1223
|
|
|
|
|
|
|
{ |
1224
|
|
|
|
|
|
|
/* This alert was added only in 1.2 */ |
1225
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_UNSUPPORTED_EXTENSION; |
1226
|
|
|
|
|
|
|
} |
1227
|
|
|
|
|
|
|
else |
1228
|
|
|
|
|
|
|
{ |
1229
|
|
|
|
|
|
|
/* Use a generic alert for older versions */ |
1230
|
0
|
|
|
|
|
|
ssl->err = SSL_ALERT_ILLEGAL_PARAMETER; |
1231
|
|
|
|
|
|
|
} |
1232
|
|
|
|
|
|
|
psTraceIntInfo("Server sent unsolicited or duplicate ext %d\n", |
1233
|
|
|
|
|
|
|
extType); |
1234
|
0
|
|
|
|
|
|
return MATRIXSSL_ERROR; |
1235
|
|
|
|
|
|
|
} |
1236
|
3449
|
|
|
|
|
|
return rc; |
1237
|
|
|
|
|
|
|
} |
1238
|
|
|
|
|
|
|
#endif |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
/**************************************************************************/ |
1241
|
|
|
|
|
|
|
|