File Coverage

inc/matrixssl-3-9-3-open/matrixssl/extDecode.c
Criterion Covered Total %
statement 146 457 31.9
branch 77 320 24.0
condition n/a
subroutine n/a
pod n/a
total 223 777 28.7


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