File Coverage

inc/matrixssl-3-9-3-open/matrixssl/matrixssl.c
Criterion Covered Total %
statement 500 1098 45.5
branch 272 704 38.6
condition n/a
subroutine n/a
pod n/a
total 772 1802 42.8


line stmt bran cond sub pod time code
1             /**
2             * @file matrixssl.c
3             * @version 950bba4 (HEAD -> master)
4             *
5             * The session and authentication management portions of the MatrixSSL library.
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             static const char copyright[] =
39             "Copyright Inside Secure Corporation. All rights reserved.";
40              
41             #if defined(USE_RSA) || defined(USE_ECC)
42             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
43             static int32 verifyReadKeys(psPool_t *pool, sslKeys_t *keys, void *poolUserPtr);
44             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
45             #endif /* USE_RSA || USE_ECC */
46              
47             #ifdef USE_SERVER_SIDE_SSL
48              
49             # ifndef SSL_SESSION_TICKET_LIST_LEN
50             # define SSL_SESSION_TICKET_LIST_LEN 32
51             # endif /* SSL_SESSION_TICKET_LIST_LEN */
52              
53             /*
54             Static session table for session cache and lock for multithreaded env
55             */
56             # ifdef USE_MULTITHREADING
57             static psMutex_t g_sessionTableLock;
58             # ifdef USE_STATELESS_SESSION_TICKETS
59             static psMutex_t g_sessTicketLock;
60             # endif
61             # endif
62              
63             # ifdef USE_SHARED_SESSION_CACHE
64             # include
65             # include
66             static sslSessionEntry_t *g_sessionTable;
67             # else
68             static sslSessionEntry_t g_sessionTable[SSL_SESSION_TABLE_SIZE];
69             # endif
70              
71             static DLListEntry g_sessionChronList;
72             static void initSessionEntryChronList(void);
73              
74             #endif /* USE_SERVER_SIDE_SSL */
75              
76             #if defined(USE_RSA) || defined(USE_ECC)
77             # ifdef MATRIX_USE_FILE_SYSTEM
78             static int32 matrixSslLoadKeyMaterial(sslKeys_t *keys, const char *certFile,
79             const char *privFile, const char *privPass, const char *CAfile,
80             int32 privKeyType);
81             # endif
82             static int32 matrixSslLoadKeyMaterialMem(sslKeys_t *keys,
83             const unsigned char *certBuf, int32 certLen,
84             const unsigned char *privBuf,
85             int32 privLen, const unsigned char *CAbuf, int32 CAlen,
86             int32 privKeyType);
87             #endif /* USE_RSA || USE_ECC */
88              
89             /******************************************************************************/
90             /*
91             Open and close the SSL module. These routines are called once in the
92             lifetime of the application and initialize and clean up the library
93             respectively.
94             The config param should always be passed as:
95             MATRIXSSL_CONFIG
96             */
97             static char g_config[32] = "N";
98              
99 17           int32_t matrixSslOpenWithConfig(const char *config)
100             {
101             unsigned long clen;
102             uint32_t shared;
103             int32_t rc;
104              
105             (void) copyright; /* Prevent compiler warning. */
106 17 50         if (*g_config == 'Y')
107             {
108 0           return PS_SUCCESS; /* Function has been called previously */
109             }
110             /* config parameter is matrixconfig + cryptoconfig + coreconfig */
111 17           strncpy(g_config, MATRIXSSL_CONFIG, sizeof(g_config) - 1);
112 17           clen = strlen(MATRIXSSL_CONFIG) - strlen(PSCRYPTO_CONFIG);
113 17 50         if (strncmp(g_config, config, clen) != 0)
114             {
115 0           psErrorStr( "MatrixSSL config mismatch.\n" \
116             "Library: " MATRIXSSL_CONFIG \
117             "\nCurrent: %s\n", config);
118 0           return PS_FAIL;
119             }
120 17 50         if (psCryptoOpen(config + clen) < 0)
121             {
122 0           psError("pscrypto open failure\n");
123 0           return PS_FAIL;
124             }
125              
126             # ifdef USE_SERVER_SIDE_SSL
127             # ifdef USE_SHARED_SESSION_CACHE
128             g_sessionTable = (sslSessionEntry_t *) mmap(NULL,
129             sizeof(sslSessionEntry_t) * SSL_SESSION_TABLE_SIZE,
130             PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
131             if (g_sessionTable == MAP_FAILED)
132             {
133             psError("error creating shared memory\n");
134             return PS_PLATFORM_FAIL;
135             }
136             psTraceStrInfo("Shared sessionTable = %p\n", g_sessionTable);
137             shared = PS_SHARED;
138             # else
139 17           shared = 0;
140             /* To prevent warning if multithreading support is disabled. */
141             PS_VARIABLE_SET_BUT_UNUSED(shared);
142             # endif
143 17           memset(g_sessionTable, 0x0,
144             sizeof(sslSessionEntry_t) * SSL_SESSION_TABLE_SIZE);
145 17           initSessionEntryChronList();
146              
147 17           if ((rc = psCreateMutex(&g_sessionTableLock, shared)) < 0)
148             {
149             return rc;
150             }
151             # ifdef USE_STATELESS_SESSION_TICKETS
152 17           if ((rc = psCreateMutex(&g_sessTicketLock, shared)) < 0)
153             {
154             return rc;
155             }
156             # endif /* USE_STATELESS_SESSION_TICKETS */
157             # endif /* USE_SERVER_SIDE_SSL */
158              
159             #ifdef USE_DTLS
160             # ifdef USE_SERVER_SIDE_SSL
161             if ((rc = dtlsGenCookieSecret()) < 0)
162             {
163             return rc;
164             }
165             # endif
166             matrixDtlsSetPmtu(-1);
167             #endif /* USE_DTLS */
168              
169 17           return PS_SUCCESS;
170             }
171              
172             /*
173             matrixSslClose
174             */
175 14           void matrixSslClose(void)
176             {
177             # ifdef USE_SERVER_SIDE_SSL
178             int i;
179              
180             psLockMutex(&g_sessionTableLock);
181 462 100         for (i = 0; i < SSL_SESSION_TABLE_SIZE; i++)
182             {
183 448           if (g_sessionTable[i].inUse > 1)
184             {
185             psTraceInfo("Warning: closing while session still in use\n");
186             }
187             }
188 14           memset(g_sessionTable, 0x0,
189             sizeof(sslSessionEntry_t) * SSL_SESSION_TABLE_SIZE);
190             psUnlockMutex(&g_sessionTableLock);
191             psDestroyMutex(&g_sessionTableLock);
192             # ifdef USE_SHARED_SESSION_CACHE
193             if (munmap(g_sessionTable,
194             sizeof(sslSessionEntry_t) * SSL_SESSION_TABLE_SIZE) != 0)
195             {
196             psTraceInfo("Warning: munmap call failed.\n");
197             }
198             # endif
199             # endif /* USE_SERVER_SIDE_SSL */
200 14           psCryptoClose();
201 14           *g_config = 'N';
202 14           }
203              
204             /******************************************************************************/
205             /*
206             Must call to allocate the key structure now. After which, LoadRsaKeys,
207             LoadDhParams and/or LoadPskKey can be called
208              
209             Memory info:
210             Caller must free keys with matrixSslDeleteKeys on function success
211             Caller does not need to free keys on function failure
212             */
213 100808           int32_t matrixSslNewKeys(sslKeys_t **keys, void *memAllocUserPtr)
214             {
215 100808           psPool_t *pool = NULL;
216             sslKeys_t *lkeys;
217              
218             #if defined(USE_ECC) || defined(REQUIRE_DH_PARAMS)
219             int32_t rc;
220             #endif
221              
222 100808           lkeys = psMalloc(pool, sizeof(sslKeys_t));
223 100808 50         if (lkeys == NULL)
224             {
225 0           return PS_MEM_FAIL;
226             }
227 100808           memset(lkeys, 0x0, sizeof(sslKeys_t));
228 100808           lkeys->pool = pool;
229 100808           lkeys->poolUserPtr = memAllocUserPtr;
230              
231             #if defined(USE_ECC) || defined(REQUIRE_DH_PARAMS)
232 100808           rc = psCreateMutex(&lkeys->cache.lock, 0);
233 100808 50         if (rc < 0)
234             {
235 0           psFree(lkeys, pool);
236 0           return rc;
237             }
238             #endif
239 100808           *keys = lkeys;
240 100808           return PS_SUCCESS;
241             }
242              
243             #ifdef USE_ECC
244             /* User is specifying EC curves that are supported so check that against the
245             keys they are supporting */
246 5740           int32 psTestUserEcID(int32 id, int32 ecFlags)
247             {
248 5740 100         if (id == 19)
249             {
250 1148 50         if (!(ecFlags & IS_SECP192R1))
251             {
252 0           return PS_FAILURE;
253             }
254             }
255 4592 100         else if (id == 21)
256             {
257 1148 50         if (!(ecFlags & IS_SECP224R1))
258             {
259 0           return PS_FAILURE;
260             }
261             }
262 3444 100         else if (id == 23)
263             {
264 1148 50         if (!(ecFlags & IS_SECP256R1))
265             {
266 0           return PS_FAILURE;
267             }
268             }
269 2296 100         else if (id == 24)
270             {
271 1148 50         if (!(ecFlags & IS_SECP384R1))
272             {
273 0           return PS_FAILURE;
274             }
275             }
276 1148 50         else if (id == 25)
277             {
278 1148 50         if (!(ecFlags & IS_SECP521R1))
279             {
280 0           return PS_FAILURE;
281             }
282             }
283 0 0         else if (id == 255)
284             {
285 0 0         if (!(ecFlags & IS_BRAIN224R1))
286             {
287 0           return PS_FAILURE;
288             }
289             }
290 0 0         else if (id == 26)
291             {
292 0 0         if (!(ecFlags & IS_BRAIN256R1))
293             {
294 0           return PS_FAILURE;
295             }
296             }
297 0 0         else if (id == 27)
298             {
299 0 0         if (!(ecFlags & IS_BRAIN384R1))
300             {
301 0           return PS_FAILURE;
302             }
303             }
304 0 0         else if (id == 28)
305             {
306 0 0         if (!(ecFlags & IS_BRAIN512R1))
307             {
308 0           return PS_FAILURE;
309             }
310             }
311             else
312             {
313 0           return PS_UNSUPPORTED_FAIL;
314             }
315 5740           return PS_SUCCESS;
316             }
317              
318 5740           int32 curveIdToFlag(int32 id)
319             {
320 5740 100         if (id == 19)
321             {
322 1148           return IS_SECP192R1;
323             }
324 4592 100         else if (id == 21)
325             {
326 1148           return IS_SECP224R1;
327             }
328 3444 100         else if (id == 23)
329             {
330 1148           return IS_SECP256R1;
331             }
332 2296 100         else if (id == 24)
333             {
334 1148           return IS_SECP384R1;
335             }
336 1148 50         else if (id == 25)
337             {
338 1148           return IS_SECP521R1;
339             }
340 0 0         else if (id == 255)
341             {
342 0           return IS_BRAIN224R1;
343             }
344 0 0         else if (id == 26)
345             {
346 0           return IS_BRAIN256R1;
347             }
348 0 0         else if (id == 27)
349             {
350 0           return IS_BRAIN384R1;
351             }
352 0 0         else if (id == 28)
353             {
354 0           return IS_BRAIN512R1;
355             }
356 0           return 0;
357             }
358              
359 0           static int32 testUserEc(int32 ecFlags, const sslKeys_t *keys)
360             {
361             const psEccKey_t *eccKey;
362              
363             # ifdef USE_CERT_PARSE
364             psX509Cert_t *cert;
365             # endif /* USE_CERT_PARSE */
366              
367             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
368 0 0         if (keys->privKey.type == PS_ECC)
369             {
370 0           eccKey = &keys->privKey.key.ecc;
371 0 0         if (psTestUserEcID(eccKey->curve->curveId, ecFlags) < 0)
372             {
373 0           return PS_FAILURE;
374             }
375             }
376              
377             # ifdef USE_CERT_PARSE
378 0           cert = keys->cert;
379 0 0         while (cert)
380             {
381 0 0         if (cert->publicKey.type == PS_ECC)
382             {
383 0           eccKey = &cert->publicKey.key.ecc;
384 0 0         if (psTestUserEcID(eccKey->curve->curveId, ecFlags) < 0)
385             {
386 0           return PS_FAILURE;
387             }
388             }
389 0           cert = cert->next;
390             }
391             # endif /* USE_CERT_PARSE */
392             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
393              
394             # if defined(USE_CLIENT_SIDE_SSL) || defined(USE_CLIENT_AUTH)
395 0           cert = keys->CAcerts;
396 0 0         while (cert)
397             {
398 0 0         if (cert->publicKey.type == PS_ECC)
399             {
400 0           eccKey = &cert->publicKey.key.ecc;
401 0 0         if (psTestUserEcID(eccKey->curve->curveId, ecFlags) < 0)
402             {
403 0           return PS_FAILURE;
404             }
405             }
406 0           cert = cert->next;
407             }
408             # endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */
409              
410 0           return PS_SUCCESS;
411             }
412             #endif /* USE_ECC */
413              
414              
415             #ifdef MATRIX_USE_FILE_SYSTEM
416             # ifdef USE_PKCS12
417              
418             # ifdef USE_CERT_PARSE
419             /* Have seen cases where the PKCS#12 files are not in a child-to-parent order */
420 10           static void ReorderCertChain(psX509Cert_t *a_cert)
421             {
422 10           psX509Cert_t *prevCert = NULL;
423 10           psX509Cert_t *nextCert = NULL;
424 10           psX509Cert_t *currCert = a_cert;
425              
426 21 100         while (currCert)
427             {
428 11           nextCert = currCert->next;
429 11 100         while (nextCert && memcmp(currCert->issuer.hash, nextCert->subject.hash,
    50          
430             SHA1_HASH_SIZE) != 0)
431             {
432 0           prevCert = nextCert;
433 0           nextCert = nextCert->next;
434              
435 0 0         if (nextCert && memcmp(currCert->issuer.hash,
    0          
436 0           nextCert->subject.hash, SHA1_HASH_SIZE) == 0)
437             {
438 0           prevCert->next = nextCert->next;
439 0           nextCert->next = currCert->next;
440 0           currCert->next = nextCert;
441 0           break;
442             }
443             }
444 11           currCert = currCert->next;
445             }
446 10           }
447             # endif /* USE_CERT_PARSE */
448              
449             /******************************************************************************/
450             /*
451             File should be a binary .p12 or .pfx
452             */
453 15           int32 matrixSslLoadPkcs12(sslKeys_t *keys, const unsigned char *certFile,
454             const unsigned char *importPass, int32 ipasslen,
455             const unsigned char *macPass, int32 mpasslen, int32 flags)
456             {
457             unsigned char *mPass;
458             psPool_t *pool;
459             int32 rc;
460              
461 15 50         if (keys == NULL)
462             {
463 0           return PS_ARG_FAIL;
464             }
465 15           pool = keys->pool;
466             PS_POOL_USED(pool);
467              
468 15 100         if (macPass == NULL)
469             {
470 11           mPass = (unsigned char *) importPass;
471 11           mpasslen = ipasslen;
472             }
473             else
474             {
475 4           mPass = (unsigned char *) macPass;
476             }
477              
478 15 100         if ((rc = psPkcs12Parse(pool, &keys->cert, &keys->privKey, certFile, flags,
479             (unsigned char *) importPass, ipasslen, mPass, mpasslen)) < 0)
480             {
481 5 50         if (keys->cert)
482             {
483 0           psX509FreeCert(keys->cert);
484 0           keys->cert = NULL;
485             }
486 5           psClearPubKey(&keys->privKey);
487 5           return rc;
488             }
489             # ifdef USE_CERT_PARSE
490 10           ReorderCertChain(keys->cert);
491             # endif /* USE_CERT_PARSE */
492             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
493 10 100         if (verifyReadKeys(pool, keys, keys->poolUserPtr) < PS_SUCCESS)
494             {
495             psTraceInfo("PKCS#12 parse success but material didn't validate\n");
496 1           psX509FreeCert(keys->cert);
497 1           psClearPubKey(&keys->privKey);
498 1           keys->cert = NULL;
499 1           return PS_CERT_AUTH_FAIL;
500             }
501             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
502 9           return PS_SUCCESS;
503             }
504             # endif /* USE_PKCS12 */
505              
506             /******************************************************************************/
507              
508             # ifdef USE_RSA
509 667           int32 matrixSslLoadRsaKeys(sslKeys_t *keys, const char *certFile,
510             const char *privFile, const char *privPass, const char *CAfile)
511             {
512 667           return matrixSslLoadKeyMaterial(keys, certFile, privFile, privPass, CAfile,
513             PS_RSA);
514              
515             }
516             # endif /* USE_RSA */
517              
518             /******************************************************************************/
519              
520             # ifdef USE_ECC
521              
522             /******************************************************************************/
523              
524 0           int32 matrixSslLoadEcKeys(sslKeys_t *keys, const char *certFile,
525             const char *privFile, const char *privPass, const char *CAfile)
526             {
527 0           return matrixSslLoadKeyMaterial(keys, certFile, privFile, privPass, CAfile,
528             PS_ECC);
529              
530             }
531             # endif /* USE_ECC */
532              
533             # if defined(USE_RSA) || defined(USE_ECC)
534 0           int32_t matrixSslLoadKeysMem(sslKeys_t *keys,
535             const unsigned char *certBuf, int32 certLen,
536             const unsigned char *privBuf, int32 privLen,
537             const unsigned char *CAbuf, int32 CAlen,
538             matrixSslLoadKeysOpts_t *opts)
539             {
540             psPubKey_t tmp_privkey;
541 0           int32_t keytype = 0;
542              
543 0 0         if (opts)
544 0           keytype = opts->key_type;
545              
546 0 0         if (privBuf == NULL)
547 0           keytype = 1;
548              
549 0 0         if (privBuf != NULL && keytype == 0)
    0          
550             {
551             /*
552             Caller did not tell us the type of privkey to expect, so try
553             to find it out.*/
554 0           memset(&tmp_privkey, 0, sizeof(psPubKey_t));
555 0           keytype = psParseUnknownPrivKeyMem(NULL,
556             (unsigned char*)privBuf, privLen,
557             NULL, &tmp_privkey);
558 0 0         if (keytype < 0)
559             {
560             psTraceInfo("Could not load private key from file\n");
561 0           return keytype;
562             }
563 0           psClearPubKey(&tmp_privkey);
564             }
565              
566 0           switch (keytype)
567             {
568             case 1: /* RSA */
569 0           return matrixSslLoadKeyMaterialMem(keys, certBuf, certLen,
570             privBuf, privLen, CAbuf, CAlen, PS_RSA);
571             break;
572             case 2: /* ECC */
573 0           return matrixSslLoadKeyMaterialMem(keys, certBuf, certLen,
574             privBuf, privLen, CAbuf, CAlen, PS_ECC);
575             break;
576             }
577              
578 0           return PS_FAILURE;
579             }
580              
581 0           int32_t matrixSslLoadKeys(sslKeys_t *keys, const char *certFile,
582             const char *privFile, const char *privPass, const char *CAfile,
583             matrixSslLoadKeysOpts_t *opts)
584             {
585             psPubKey_t tmp_privkey;
586 0           int32_t keytype = 0;
587              
588 0 0         if (opts)
589 0           keytype = opts->key_type;
590              
591 0 0         if (privFile == NULL)
592 0           keytype = 1;
593              
594 0 0         if (keytype == 0)
595             {
596             /*
597             Caller did not tell us the type of privkey to expect, so try
598             to find it out.*/
599 0           memset(&tmp_privkey, 0, sizeof(psPubKey_t));
600 0           keytype = psParseUnknownPrivKey(NULL, 1, privFile, privPass,
601             &tmp_privkey);
602 0 0         if (keytype < 0)
603             {
604             psTraceInfo("Could not load private key from file\n");
605 0           return keytype;
606             }
607 0           psClearPubKey(&tmp_privkey);
608             }
609              
610 0           switch (keytype)
611             {
612             case 1: /* RSA */
613 0           return matrixSslLoadKeyMaterial(keys, certFile, privFile, privPass,
614             CAfile, PS_RSA);
615             break;
616             case 2: /* ECC */
617 0           return matrixSslLoadKeyMaterial(keys, certFile, privFile, privPass,
618             CAfile, PS_ECC);
619             break;
620             }
621              
622 0           return PS_FAILURE;
623             }
624              
625 667           static int32 matrixSslLoadKeyMaterial(sslKeys_t *keys, const char *certFile,
626             const char *privFile, const char *privPass, const char *CAfile,
627             int32 privKeyType)
628             {
629             psPool_t *pool;
630             int32 err, flags;
631              
632 667 50         if (keys == NULL)
633             {
634 0           return PS_ARG_FAIL;
635             }
636 667           pool = keys->pool;
637              
638             /*
639             Setting flags to store raw ASN.1 stream for SSL CERTIFICATE message use
640             */
641 667           flags = CERT_STORE_UNPARSED_BUFFER;
642              
643             # ifdef USE_CLIENT_AUTH
644             /*
645             If the CERTIFICATE_REQUEST message will possibly be needed we must
646             save aside the Distiguished Name portion of the certs for that message.
647             */
648 667           flags |= CERT_STORE_DN_BUFFER;
649             # endif /* USE_CLIENT_AUTH */
650              
651 667 100         if (certFile)
652             {
653             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
654 136 50         if (keys->cert != NULL)
655             {
656 0           return PS_UNSUPPORTED_FAIL;
657             }
658 136 100         if ((err = psX509ParseCertFile(pool, (char *) certFile,
659             &keys->cert, flags)) < 0)
660             {
661 1           return err;
662             }
663             # ifdef USE_CERT_PARSE
664 135 50         if (keys->cert->authFailFlags)
665             {
666 0 0         psAssert(keys->cert->authFailFlags == PS_CERT_AUTH_FAIL_DATE_FLAG);
667             # ifdef POSIX /* TODO - implement date check on WIN32, etc. */
668 0           psX509FreeCert(keys->cert);
669 0           keys->cert = NULL;
670 0           return PS_CERT_AUTH_FAIL_EXTENSION;
671             # endif /* POSIX */
672             }
673             # endif /* USE_CERT_PARSE */
674             # else
675             psTraceStrInfo("Ignoring %s certFile in matrixSslReadKeys\n",
676             (char *) certFile);
677             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
678             }
679             /*
680             Parse the private key file
681             */
682 666 100         if (privFile)
683             {
684             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
685             /* See if private key already exists */
686 134 50         if (keys->privKey.keysize > 0)
687             {
688 0 0         if (keys->cert)
689             {
690 0           psX509FreeCert(keys->cert);
691 0           keys->cert = NULL;
692 0           return PS_UNSUPPORTED_FAIL;
693             }
694             }
695             # ifdef USE_RSA
696 134 50         if (privKeyType == PS_RSA)
697             {
698 134           psInitPubKey(pool, &keys->privKey, PS_RSA);
699 134 100         if ((err = psPkcs1ParsePrivFile(pool, (char *) privFile,
700             (char *) privPass, &keys->privKey.key.rsa)) < 0)
701             {
702 5 50         if (keys->cert)
703             {
704 5           psX509FreeCert(keys->cert);
705 5           keys->cert = NULL;
706             }
707 5           return err;
708             }
709 129           keys->privKey.keysize = psRsaSize(&keys->privKey.key.rsa);
710             }
711             # endif /* USE_RSA */
712             # ifdef USE_ECC
713 129 50         if (privKeyType == PS_ECC)
714             {
715 0           psInitPubKey(pool, &keys->privKey, PS_ECC);
716 0 0         if ((err = psEccParsePrivFile(pool, (char *) privFile,
717             (char *) privPass, &keys->privKey.key.ecc)) < 0)
718             {
719 0 0         if (keys->cert)
720             {
721 0           psX509FreeCert(keys->cert);
722 0           keys->cert = NULL;
723             }
724 0           return err;
725             }
726 0           keys->privKey.keysize = psEccSize(&keys->privKey.key.ecc);
727             }
728             # endif /* USE_ECC */
729             # else
730             psTraceStrInfo("Ignoring %s privFile in matrixSslReadKeys\n",
731             (char *) privFile);
732             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
733             }
734              
735             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
736 661 100         if (verifyReadKeys(pool, keys, keys->poolUserPtr) < PS_SUCCESS)
737             {
738             psTraceInfo("Cert parse success but material didn't validate\n");
739 1           psX509FreeCert(keys->cert);
740 1           psClearPubKey(&keys->privKey);
741 1           keys->cert = NULL;
742 1           return PS_CERT_AUTH_FAIL;
743             }
744             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
745              
746             /* Not necessary to store binary representations of CA certs */
747 660           flags &= ~CERT_STORE_UNPARSED_BUFFER;
748              
749 660 100         if (CAfile)
750             {
751             # if defined(USE_CLIENT_SIDE_SSL) || defined(USE_CLIENT_AUTH)
752 641 50         if (keys->CAcerts != NULL)
753             {
754 0           return PS_UNSUPPORTED_FAIL;
755             }
756             #ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE
757             flags |= CERT_ALLOW_BUNDLE_PARTIAL_PARSE;
758             #endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */
759 641           err = psX509ParseCertFile(pool, (char *) CAfile, &keys->CAcerts, flags);
760 641 100         if (err >= 0)
761             {
762             #ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE
763             if (err == 0)
764             {
765             psTraceInfo("Failed to load any CA certs.\n");
766             err = PS_PARSE_FAIL;
767             goto ca_load_failed;
768             }
769             else
770             {
771             psTraceIntInfo("Loaded %d CA certs\n", err);
772             }
773             #endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */
774 640 50         if (keys->CAcerts->authFailFlags)
775             {
776             /* This should be the only no err, FailFlags case currently */
777 0 0         psAssert(keys->CAcerts->authFailFlags ==
778             PS_CERT_AUTH_FAIL_DATE_FLAG);
779             # ifdef POSIX /* TODO - implement date check on WIN32, etc. */
780 0           psX509FreeCert(keys->CAcerts);
781 0           keys->CAcerts = NULL;
782 0           err = PS_CERT_AUTH_FAIL_EXTENSION;
783             # endif
784             }
785             }
786              
787             #ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE
788             ca_load_failed:
789             #endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */
790              
791 641 100         if (err < 0)
792             {
793             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
794 1 50         if (keys->cert)
795             {
796 0           psX509FreeCert(keys->cert);
797 0           keys->cert = NULL;
798             }
799 1           psClearPubKey(&keys->privKey);
800             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
801 1           return err;
802             }
803             # else
804             psTraceStrInfo("Ignoring %s CAfile in matrixSslReadKeys\n", (char *) CAfile);
805             # endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */
806             }
807              
808 659           return PS_SUCCESS;
809             }
810              
811             # endif /* USE_RSA || USE_ECC */
812             #endif /* MATRIX_USE_FILE_SYSTEM */
813              
814             /******************************************************************************/
815             /*
816             Memory buffer versions of ReadKeys
817              
818             This function supports cert chains and multiple CAs. Just need to
819             string them together and let psX509ParseCert handle it
820             */
821             #ifdef USE_RSA
822 114           int32 matrixSslLoadRsaKeysMem(sslKeys_t *keys, const unsigned char *certBuf,
823             int32 certLen, const unsigned char *privBuf, int32 privLen,
824             const unsigned char *CAbuf, int32 CAlen)
825             {
826 114           return matrixSslLoadKeyMaterialMem(keys, certBuf, certLen, privBuf, privLen,
827             CAbuf, CAlen, PS_RSA);
828              
829             }
830             #endif /* USE_RSA */
831              
832             #ifdef USE_ECC
833 0           int32 matrixSslLoadEcKeysMem(sslKeys_t *keys, const unsigned char *certBuf,
834             int32 certLen, const unsigned char *privBuf, int32 privLen,
835             const unsigned char *CAbuf, int32 CAlen)
836             {
837 0           return matrixSslLoadKeyMaterialMem(keys, certBuf, certLen, privBuf, privLen,
838             CAbuf, CAlen, PS_ECC);
839              
840             }
841             /**
842             Generate and cache an ephemeral ECC key for later use in ECDHE key exchange.
843             @param[out] keys Keys structure to hold ephemeral keys
844             @param[in] curve ECC curve to generate key on, or NULL to generate for all
845             supported curves.
846             @param[in] hwCtx Context for hardware crypto.
847             */
848 2203           int32_t matrixSslGenEphemeralEcKey(sslKeys_t *keys, psEccKey_t *ecc,
849             const psEccCurve_t *curve, void *hwCtx)
850             {
851             # if ECC_EPHEMERAL_CACHE_USAGE > 0
852             psTime_t t;
853             # endif
854             int32_t rc;
855              
856 2203 50         psAssert(keys && curve);
    50          
857             # if ECC_EPHEMERAL_CACHE_USAGE > 0
858 2203           psGetTime(&t, keys->poolUserPtr);
859             psLockMutex(&keys->cache.lock);
860 2203 100         if (keys->cache.eccPrivKey.curve != curve)
861             {
862             psTraceStrInfo("Generating ephemeral %s key (new curve)\n",
863             curve->name);
864 27           goto L_REGEN;
865             }
866 2176 100         if (keys->cache.eccPrivKeyUse > ECC_EPHEMERAL_CACHE_USAGE)
867             {
868             psTraceStrInfo("Generating ephemeral %s key (usage exceeded)\n",
869             curve->name);
870 2           goto L_REGEN;
871             }
872 2174 50         if (psDiffMsecs(keys->cache.eccPrivKeyTime, t, keys->poolUserPtr) >
873             (1000 * ECC_EPHEMERAL_CACHE_SECONDS))
874             {
875             psTraceStrInfo("Generating ephemeral %s key (time exceeded)\n",
876             curve->name);
877 0           goto L_REGEN;
878             }
879 2174           keys->cache.eccPrivKeyUse++;
880 2174           rc = PS_SUCCESS;
881 2174 50         if (ecc)
882             {
883 2174           rc = psEccCopyKey(ecc, &keys->cache.eccPrivKey);
884             }
885             psUnlockMutex(&keys->cache.lock);
886 2174           return rc;
887             L_REGEN:
888 29 100         if (keys->cache.eccPrivKeyUse)
889             {
890             /* We use eccPrivKeyUse == 0 as a flag to note the key not allocated */
891 2           psEccClearKey(&keys->cache.eccPrivKey);
892 2           keys->cache.eccPrivKeyUse = 0;
893             }
894 29           rc = psEccGenKey(keys->pool, &keys->cache.eccPrivKey, curve, hwCtx);
895 29 50         if (rc < 0)
896             {
897             psUnlockMutex(&keys->cache.lock);
898 0           return rc;
899             }
900 29           keys->cache.eccPrivKeyTime = t;
901 29           keys->cache.eccPrivKeyUse = 1;
902 29           rc = PS_SUCCESS;
903 29 50         if (ecc)
904             {
905 29           rc = psEccCopyKey(ecc, &keys->cache.eccPrivKey);
906             }
907             psUnlockMutex(&keys->cache.lock);
908 2203           return rc;
909             # else
910             /* Not using ephemeral caching. */
911             if (ecc)
912             {
913             rc = psEccGenKey(keys->pool, ecc, curve, hwCtx);
914             return rc;
915             }
916             rc = PS_SUCCESS;
917             return rc;
918             # endif /* ECC_EPHEMERAL_CACHE_USAGE > 0 */
919             }
920              
921             #endif /* USE_ECC */
922              
923             #if defined(USE_RSA) || defined(USE_ECC)
924 114           static int32 matrixSslLoadKeyMaterialMem(sslKeys_t *keys,
925             const unsigned char *certBuf, int32 certLen,
926             const unsigned char *privBuf,
927             int32 privLen, const unsigned char *CAbuf, int32 CAlen,
928             int32 privKeyType)
929             {
930             psPool_t *pool;
931 114           int32 err, flags = 0;
932              
933 114 100         if (certBuf == NULL && privBuf == NULL && CAbuf == NULL)
    50          
    50          
934             {
935 0           return PS_ARG_FAIL;
936             }
937              
938 114 50         if (keys == NULL)
939             {
940 0           return PS_ARG_FAIL;
941             }
942 114           pool = keys->pool;
943              
944             /*
945             Setting flags to store raw ASN.1 stream for SSL CERTIFICATE message use
946             */
947 114           flags = CERT_STORE_UNPARSED_BUFFER;
948              
949             # ifdef USE_CLIENT_AUTH
950             /*
951             Setting flag to store raw ASN.1 DN stream for CERTIFICATE_REQUEST
952             */
953 114           flags |= CERT_STORE_DN_BUFFER;
954             # endif /* USE_CLIENT_AUTH */
955              
956 114 100         if (certBuf)
957             {
958             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
959 113 50         if (keys->cert != NULL)
960             {
961             psTraceInfo("WARNING: An identity certificate already exists\n");
962 0           return PS_UNSUPPORTED_FAIL;
963             }
964 113 100         if ((err = psX509ParseCert(pool, (unsigned char *) certBuf,
965             (uint32) certLen, &keys->cert, flags)) < 0)
966             {
967 1           psX509FreeCert(keys->cert);
968 1           keys->cert = NULL;
969 1           return err;
970             }
971             # else
972             psTraceInfo("Ignoring certBuf in matrixSslReadKeysMem\n");
973             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
974             }
975              
976 113 100         if (privBuf)
977             {
978             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
979             # ifdef USE_RSA
980 112 50         if (privKeyType == PS_RSA)
981             {
982 112           psInitPubKey(pool, &keys->privKey, PS_RSA);
983 112 50         if ((err = psRsaParsePkcs1PrivKey(pool, privBuf,
984             privLen, &keys->privKey.key.rsa)) < 0)
985             {
986             # ifdef USE_PKCS8
987             /* Attempt a PKCS#8 but mem parse doesn't take password */
988 0 0         if ((err = psPkcs8ParsePrivBin(pool, (unsigned char *) privBuf,
989             (uint32) privLen, NULL, &keys->privKey)) < 0)
990             {
991 0           psX509FreeCert(keys->cert); keys->cert = NULL;
992 0           return err;
993             }
994             # else
995             psX509FreeCert(keys->cert); keys->cert = NULL;
996             return err;
997             # endif
998             }
999 112           keys->privKey.keysize = psRsaSize(&keys->privKey.key.rsa);
1000             }
1001             # endif /* USE_RSA */
1002             # ifdef USE_ECC
1003 112 50         if (privKeyType == PS_ECC)
1004             {
1005 0           psInitPubKey(pool, &keys->privKey, PS_ECC);
1006 0 0         if ((err = psEccParsePrivKey(pool, (unsigned char *) privBuf,
1007             (uint32) privLen, &keys->privKey.key.ecc, NULL)) < 0)
1008             {
1009             # ifdef USE_PKCS8
1010             /* Attempt a PKCS#8 but mem parse doesn't take password */
1011 0 0         if ((err = psPkcs8ParsePrivBin(pool, (unsigned char *) privBuf,
1012             (uint32) privLen, NULL, &keys->privKey)) < 0)
1013             {
1014 0           psX509FreeCert(keys->cert); keys->cert = NULL;
1015 0           return err;
1016             }
1017             # else
1018             psX509FreeCert(keys->cert); keys->cert = NULL;
1019             return err;
1020             # endif
1021             }
1022 0           keys->privKey.keysize = psEccSize(&keys->privKey.key.ecc);
1023             }
1024             # endif /* USE_ECC */
1025             # else
1026             psTraceInfo("Ignoring privBuf in matrixSslReadKeysMem\n");
1027             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
1028             }
1029              
1030             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
1031 113 50         if (verifyReadKeys(pool, keys, keys->poolUserPtr) < PS_SUCCESS)
1032             {
1033 0           psX509FreeCert(keys->cert);
1034 0           psClearPubKey(&keys->privKey);
1035 0           keys->cert = NULL;
1036 0           return PS_CERT_AUTH_FAIL;
1037             }
1038             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
1039              
1040             /*
1041             Not necessary to store binary representations of CA certs
1042             */
1043 113           flags &= ~CERT_STORE_UNPARSED_BUFFER;
1044              
1045 113 100         if (CAbuf)
1046             {
1047             # if defined(USE_CLIENT_SIDE_SSL) || defined(USE_CLIENT_AUTH)
1048 112 50         if (keys->CAcerts != NULL)
1049             {
1050 0           return PS_UNSUPPORTED_FAIL;
1051             }
1052             #ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE
1053             flags |= CERT_ALLOW_BUNDLE_PARTIAL_PARSE;
1054             #endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */
1055 112           err = psX509ParseCert(pool, (unsigned char *) CAbuf, (uint32) CAlen,
1056             &keys->CAcerts, flags);
1057             if (err < 0)
1058             {
1059             #ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE
1060             if (err == 0)
1061             {
1062             psTraceInfo("Failed to load any CA certs.\n");
1063             err = PS_PARSE_FAIL;
1064             goto ca_load_failed;
1065             }
1066             else
1067             {
1068             psTraceIntInfo("Loaded %d CA certs\n", err);
1069             }
1070             #endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */
1071             }
1072             # else
1073             psTraceInfo("Ignoring CAbuf in matrixSslReadKeysMem\n");
1074             # endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */
1075             }
1076              
1077             #ifdef ALLOW_CA_BUNDLE_PARTIAL_PARSE
1078             ca_load_failed:
1079             #endif /* ALLOW_CA_BUNDLE_PARTIAL_PARSE */
1080              
1081             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
1082 113 50         if (err < 0)
1083             {
1084 0           psClearPubKey(&keys->privKey);
1085 0           psX509FreeCert(keys->cert);
1086 0           psX509FreeCert(keys->CAcerts);
1087 0           keys->cert = keys->CAcerts = NULL;
1088 0           return err;
1089             }
1090             # endif
1091              
1092 113           return PS_SUCCESS;
1093             }
1094             #endif /* USE_RSA || USE_ECC */
1095              
1096              
1097             #if defined(USE_OCSP) && defined(USE_SERVER_SIDE_SSL)
1098 3           int32_t matrixSslLoadOCSPResponse(sslKeys_t *keys,
1099             const unsigned char *OCSPResponseBuf, psSize_t OCSPResponseBufLen)
1100             {
1101             psPool_t *pool;
1102              
1103 3 50         if (keys == NULL || OCSPResponseBuf == NULL || OCSPResponseBufLen == 0)
    50          
    50          
1104             {
1105 0           return PS_ARG_FAIL;
1106             }
1107 3           pool = keys->pool;
1108             PS_POOL_USED(pool);
1109              
1110             /* Overwrite/Update any response being set */
1111 3 100         if (keys->OCSPResponseBuf != NULL)
1112             {
1113 1           psFree(keys->OCSPResponseBuf, pool);
1114 1           keys->OCSPResponseBufLen = 0;
1115             }
1116              
1117 3           keys->OCSPResponseBufLen = OCSPResponseBufLen;
1118 3 50         if ((keys->OCSPResponseBuf = psMalloc(pool, OCSPResponseBufLen)) == NULL)
1119             {
1120 0           return PS_MEM_FAIL;
1121             }
1122              
1123 3           memcpy(keys->OCSPResponseBuf, OCSPResponseBuf, OCSPResponseBufLen);
1124 3           return PS_SUCCESS;
1125             }
1126             #endif /* USE_OCSP && USE_SERVER_SIDE_SSL */
1127              
1128              
1129             #if defined(USE_SCT) && defined(USE_SERVER_SIDE_SSL)
1130 5           int32_t matrixSslLoadSCTResponse(sslKeys_t *keys,
1131             const unsigned char *SCTResponseBuf, uint16_t SCTResponseBufLen)
1132             {
1133             psPool_t *pool;
1134              
1135 5 50         if (keys == NULL || SCTResponseBuf == NULL || SCTResponseBufLen == 0) {
    50          
    50          
1136 0           return PS_ARG_FAIL;
1137             }
1138 5           pool = keys->pool;
1139              
1140             /* Overwrite/Update any response being set */
1141 5 100         if (keys->SCTResponseBuf != NULL) {
1142 3           psFree(keys->SCTResponseBuf, pool);
1143 3           keys->SCTResponseBufLen = 0;
1144             }
1145              
1146 5           keys->SCTResponseBufLen = SCTResponseBufLen;
1147 5 50         if ((keys->SCTResponseBuf = psMalloc(pool, SCTResponseBufLen)) == NULL) {
1148 0           return PS_MEM_FAIL;
1149             }
1150              
1151 5           memcpy(keys->SCTResponseBuf, SCTResponseBuf, SCTResponseBufLen);
1152 5           return PS_SUCCESS;
1153             }
1154             #endif /* USE_OCSP && USE_SERVER_SIDE_SSL */
1155              
1156              
1157             /******************************************************************************/
1158             /*
1159             This will free the struct and any key material that was loaded via:
1160             matrixSslLoadRsaKeys
1161             matrixSslLoadEcKeys
1162             matrixSslLoadDhParams
1163             matrixSslLoadPsk
1164             matrixSslLoadOCSPResponse
1165             */
1166 100808           void matrixSslDeleteKeys(sslKeys_t *keys)
1167             {
1168             #ifdef USE_PSK_CIPHER_SUITE
1169             psPsk_t *psk, *next;
1170             #endif /* USE_PSK_CIPHER_SUITE */
1171             #if defined(USE_STATELESS_SESSION_TICKETS) && defined(USE_SERVER_SIDE_SSL)
1172             psSessionTicketKeys_t *tick, *nextTick;
1173             #endif
1174              
1175 100808 50         if (keys == NULL)
1176             {
1177 0           return;
1178             }
1179             #ifndef USE_ONLY_PSK_CIPHER_SUITE
1180             # if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
1181 100808 100         if (keys->cert)
1182             {
1183 250           psX509FreeCert(keys->cert);
1184             }
1185              
1186 100808           psClearPubKey(&keys->privKey);
1187             # endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
1188              
1189             # if defined(USE_CLIENT_SIDE_SSL) || defined(USE_CLIENT_AUTH)
1190 100808 100         if (keys->CAcerts)
1191             {
1192 752           psX509FreeCert(keys->CAcerts);
1193             }
1194             # endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */
1195             #endif /* !USE_ONLY_PSK_CIPHER_SUITE */
1196              
1197             #ifdef REQUIRE_DH_PARAMS
1198 100808           psPkcs3ClearDhParams(&keys->dhParams);
1199             #endif /* REQUIRE_DH_PARAMS */
1200              
1201             #ifdef USE_PSK_CIPHER_SUITE
1202 100808 50         if (keys->pskKeys)
1203             {
1204 0           psk = keys->pskKeys;
1205 0 0         while (psk)
1206             {
1207 0           psFree(psk->pskKey, keys->pool);
1208 0           psFree(psk->pskId, keys->pool);
1209 0           next = psk->next;
1210 0           psFree(psk, keys->pool);
1211 0           psk = next;
1212             }
1213             }
1214             #endif /* USE_PSK_CIPHER_SUITE */
1215              
1216             #if defined(USE_STATELESS_SESSION_TICKETS) && defined(USE_SERVER_SIDE_SSL)
1217 100808 100         if (keys->sessTickets)
1218             {
1219 1           tick = keys->sessTickets;
1220 2 100         while (tick)
1221             {
1222 1           nextTick = tick->next;
1223 1           psFree(tick, keys->pool);
1224 1           tick = nextTick;
1225             }
1226             }
1227             #endif
1228              
1229             #if defined(USE_ECC) || defined(REQUIRE_DH_PARAMS)
1230             psDestroyMutex(&keys->cache.lock);
1231             # ifdef USE_ECC
1232 100808 100         if (keys->cache.eccPrivKeyUse > 0)
1233             {
1234 27           psEccClearKey(&keys->cache.eccPrivKey);
1235 27           psEccClearKey(&keys->cache.eccPubKey);
1236             }
1237             # endif
1238             /* Remainder of structure is cleared below */
1239             #endif
1240              
1241             #if defined(USE_OCSP) && defined(USE_SERVER_SIDE_SSL)
1242 100808 100         if (keys->OCSPResponseBuf != NULL)
1243             {
1244 2           psFree(keys->OCSPResponseBuf, keys->pool);
1245 2           keys->OCSPResponseBufLen = 0;
1246             }
1247             #endif
1248              
1249 100808           memzero_s(keys, sizeof(sslKeys_t));
1250 100808           psFree(keys, NULL);
1251             }
1252              
1253             #if defined(USE_SERVER_SIDE_SSL) || defined(USE_CLIENT_AUTH)
1254             # if defined(USE_RSA) || defined(USE_ECC)
1255             /*
1256             Validate the cert chain and the private key for the material passed
1257             to matrixSslReadKeys. Good to catch any user certifiate errors as
1258             soon as possible
1259              
1260             When the client private key is stored externally, skip all tests
1261             involving the private key, since MatrixSSL does not have direct
1262             access to the key.
1263             */
1264 784           static int32 verifyReadKeys(psPool_t *pool, sslKeys_t *keys, void *poolUserPtr)
1265             {
1266             # ifdef USE_CERT_PARSE
1267             psX509Cert_t *tmp, *found;
1268             # endif
1269              
1270 784 100         if (keys->cert == NULL && keys->privKey.type == 0)
    50          
1271             {
1272 532           return PS_SUCCESS;
1273             }
1274              
1275             # ifndef USE_EXT_CERTIFICATE_VERIFY_SIGNING
1276             /*
1277             Not allowed to have a certificate with no matching private key or
1278             private key with no cert to match with
1279             */
1280 252 50         if (keys->cert != NULL && keys->privKey.type == 0)
    100          
1281             {
1282             psTraceInfo("No private key given to matrixSslReadKeys cert\n");
1283 1           return PS_CERT_AUTH_FAIL;
1284             }
1285 251 50         if (keys->privKey.type != 0 && keys->cert == NULL)
    50          
1286             {
1287             psTraceInfo("No cert given with private key to matrixSslReadKeys\n");
1288 0           return PS_CERT_AUTH_FAIL;
1289             }
1290             # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */
1291              
1292             # ifdef USE_CERT_PARSE
1293             /*
1294             If this is a chain, we can validate it here with psX509AuthenticateCert
1295             Don't check the error return code from this call because the chaining
1296             usage restrictions will test parent-most cert for self-signed.
1297              
1298             But we can look at 'authStatus' on all but the final cert to see
1299             if the rest looks good
1300             */
1301 251 50         if (keys->cert != NULL && keys->cert->next != NULL)
    100          
1302             {
1303 1           found = NULL;
1304 1           psX509AuthenticateCert(pool, keys->cert, NULL, &found, NULL,
1305             poolUserPtr);
1306 1           tmp = keys->cert;
1307 1 50         while (tmp->next != NULL)
1308             {
1309 1 50         if (tmp->authStatus != PS_TRUE)
1310             {
1311             psTraceInfo("Failed to authenticate cert chain\n");
1312 1           return PS_CERT_AUTH_FAIL;
1313             }
1314 0           tmp = tmp->next;
1315             }
1316             }
1317              
1318             # ifndef USE_EXT_CERTIFICATE_VERIFY_SIGNING
1319             # ifdef USE_RSA
1320 250 50         if (keys->privKey.type == PS_RSA)
1321             {
1322 250 50         if (psRsaCmpPubKey(&keys->privKey.key.rsa,
1323 250           &keys->cert->publicKey.key.rsa) < 0)
1324             {
1325             psTraceInfo("Private key doesn't match cert\n");
1326 0           return PS_CERT_AUTH_FAIL;
1327             }
1328             }
1329             # endif /* USE_RSA */
1330             # endif /* !USE_EXT_CERTIFICATE_VERIFY_SIGNING */
1331             # endif /* USE_CERT_PARSE */
1332 784           return PS_SUCCESS;
1333             }
1334             # endif /* USE_RSA || USE_ECC */
1335             #endif /* USE_SERVER_SIDE_SSL || USE_CLIENT_AUTH */
1336             /******************************************************************************/
1337              
1338             #ifdef REQUIRE_DH_PARAMS
1339             /******************************************************************************/
1340             /*
1341             User level API to assign the DH parameter file to the server application.
1342             */
1343             # ifdef MATRIX_USE_FILE_SYSTEM
1344 0           int32 matrixSslLoadDhParams(sslKeys_t *keys, const char *paramFile)
1345             {
1346 0 0         if (keys == NULL)
1347             {
1348 0           return PS_ARG_FAIL;
1349             }
1350 0           return psPkcs3ParseDhParamFile(keys->pool, (char *) paramFile, &keys->dhParams);
1351             }
1352             # endif /* MATRIX_USE_FILE_SYSTEM */
1353              
1354             /******************************************************************************/
1355 0           int32 matrixSslLoadDhParamsMem(sslKeys_t *keys, const unsigned char *dhBin,
1356             int32 dhBinLen)
1357             {
1358 0 0         if (keys == NULL)
1359             {
1360 0           return PS_ARG_FAIL;
1361             }
1362 0           return psPkcs3ParseDhParamBin(keys->pool, (unsigned char *) dhBin, dhBinLen,
1363             &keys->dhParams);
1364             }
1365             #endif /* REQUIRE_DH_PARAMS */
1366              
1367             /******************************************************************************/
1368             /*
1369             New SSL protocol context
1370             This structure is associated with a single SSL connection. Each socket
1371             using SSL should be associated with a new SSL context.
1372              
1373             certBuf and privKey ARE NOT duplicated within the server context, in order
1374             to minimize memory usage with multiple simultaneous requests. They must
1375             not be deleted by caller until all server contexts using them are deleted.
1376             */
1377 22314           int32 matrixSslNewSession(ssl_t **ssl, const sslKeys_t *keys,
1378             sslSessionId_t *session, sslSessOpts_t *options)
1379             {
1380 22314           psPool_t *pool = NULL;
1381             ssl_t *lssl;
1382             int32_t specificVersion, flags;
1383              
1384             #ifdef USE_STATELESS_SESSION_TICKETS
1385             uint32_t i;
1386             #endif
1387              
1388             /* SERVER_SIDE and CLIENT_AUTH and others will have been added to
1389             versionFlag by callers */
1390 22314           flags = options->versionFlag;
1391              
1392             /*
1393             First API level chance to make sure a user is not attempting to use
1394             client or server support that was not built into this library compile
1395             */
1396             #ifndef USE_SERVER_SIDE_SSL
1397             if (flags & SSL_FLAGS_SERVER)
1398             {
1399             psTraceInfo("SSL_FLAGS_SERVER passed to matrixSslNewSession but MatrixSSL lib was not compiled with server support\n");
1400             return PS_ARG_FAIL;
1401             }
1402             #endif
1403              
1404             #ifndef USE_CLIENT_SIDE_SSL
1405             if (!(flags & SSL_FLAGS_SERVER))
1406             {
1407             psTraceInfo("SSL_FLAGS_SERVER was not passed to matrixSslNewSession but MatrixSSL was not compiled with client support\n");
1408             return PS_ARG_FAIL;
1409             }
1410             #endif
1411              
1412             #ifndef USE_CLIENT_AUTH
1413             if (flags & SSL_FLAGS_CLIENT_AUTH)
1414             {
1415             psTraceInfo("SSL_FLAGS_CLIENT_AUTH passed to matrixSslNewSession but MatrixSSL was not compiled with USE_CLIENT_AUTH enabled\n");
1416             return PS_ARG_FAIL;
1417             }
1418             #endif
1419              
1420 22314           if (flags & SSL_FLAGS_SERVER)
1421             {
1422             # ifndef USE_PSK_CIPHER_SUITE
1423             if (keys == NULL)
1424             {
1425             psTraceInfo("NULL keys parameter passed to matrixSslNewSession\n");
1426             return PS_ARG_FAIL;
1427             }
1428             # endif /* USE_PSK_CIPHER_SUITE */
1429             if (session != NULL)
1430             {
1431             psTraceInfo("Ignoring session parameter to matrixSslNewSession\n");
1432             }
1433             }
1434              
1435 22314 50         if (flags & SSL_FLAGS_INTERCEPTOR)
1436             {
1437             psTraceInfo("SSL_FLAGS_INTERCEPTOR not supported\n");
1438 0           return PS_ARG_FAIL;
1439             }
1440              
1441 22314           lssl = psMalloc(pool, sizeof(ssl_t));
1442 22314 50         if (lssl == NULL)
1443             {
1444             psTraceInfo("Out of memory for ssl_t in matrixSslNewSession\n");
1445 0           return PS_MEM_FAIL;
1446             }
1447 22314           memset(lssl, 0x0, sizeof(ssl_t));
1448 22314           lssl->memAllocPtr = options->memAllocPtr;
1449              
1450             #ifdef USE_X509
1451 22314 50         if (options->keep_peer_cert_der)
1452             {
1453 0           lssl->bFlags |= BFLAG_KEEP_PEER_CERT_DER;
1454             }
1455 22314 50         if (options->keep_peer_certs)
1456             {
1457 0           lssl->bFlags |= BFLAG_KEEP_PEER_CERTS;
1458             }
1459             #endif
1460              
1461 22314 50         if (options->validateCertsOpts.max_verify_depth >= 0)
1462             {
1463 22314           lssl->validateCertsOpts.max_verify_depth =
1464 22314           options->validateCertsOpts.max_verify_depth;
1465             }
1466              
1467 22314 50         if (options->userDataPtr != NULL)
1468 0           lssl->userDataPtr = options->userDataPtr;
1469              
1470             #ifdef USE_ECC
1471             /* If user specified EC curves they support, let's check that against
1472             the key material they provided so there are no conflicts. Don't
1473             need to test against default compiled-in curves because the keys
1474             would not have loaded at all */
1475 22314 50         if (options->ecFlags)
1476             {
1477 0 0         if (testUserEc(options->ecFlags, keys) < 0)
1478             {
1479             psTraceIntInfo("ERROR: Only EC 0x%x specified in options.ecFlags ",
1480             options->ecFlags);
1481             psTraceInfo("but other curves were found in key material\n");
1482 0           psFree(lssl, pool);
1483 0           return PS_ARG_FAIL;
1484             }
1485 0           lssl->ecInfo.ecFlags = options->ecFlags;
1486             }
1487             else
1488             {
1489 22314           lssl->ecInfo.ecFlags = compiledInEcFlags();
1490             }
1491             #endif
1492              
1493             /*
1494             Data buffers
1495             */
1496 22314           lssl->bufferPool = options->bufferPool;
1497 22314           lssl->outsize = SSL_DEFAULT_OUT_BUF_SIZE;
1498             #ifdef USE_DTLS
1499             if (flags & SSL_FLAGS_DTLS)
1500             {
1501             lssl->outsize = matrixDtlsGetPmtu();
1502             }
1503             #endif /* USE_DTLS */
1504              
1505             /* Standard software implementation */
1506 22314           lssl->outbuf = psMalloc(lssl->bufferPool, lssl->outsize);
1507              
1508 22314 50         if (lssl->outbuf == NULL)
1509             {
1510             psTraceInfo("Buffer pool is too small\n");
1511 0           psFree(lssl, pool);
1512 0           return PS_MEM_FAIL;
1513             }
1514 22314           lssl->insize = SSL_DEFAULT_IN_BUF_SIZE;
1515             #ifdef USE_DTLS
1516             if (flags & SSL_FLAGS_DTLS)
1517             {
1518             lssl->insize = matrixDtlsGetPmtu();
1519             }
1520             #endif /* USE_DTLS */
1521 22314           lssl->inbuf = psMalloc(lssl->bufferPool, lssl->insize);
1522 22314 50         if (lssl->inbuf == NULL)
1523             {
1524             psTraceInfo("Buffer pool is too small\n");
1525 0           psFree(lssl->outbuf, lssl->bufferPool);
1526 0           psFree(lssl, pool);
1527 0           return PS_MEM_FAIL;
1528             }
1529              
1530 22314           lssl->sPool = pool;
1531 22314           lssl->keys = (sslKeys_t *) keys;
1532 22314 50         if ((lssl->cipher = sslGetCipherSpec(lssl, SSL_NULL_WITH_NULL_NULL)) == NULL)
1533             {
1534 0           psFree(lssl->outbuf, lssl->bufferPool);
1535 0           psFree(lssl, pool);
1536 0           return PS_MEM_FAIL;
1537             }
1538 22314           sslActivateReadCipher(lssl);
1539 22314           sslActivateWriteCipher(lssl);
1540              
1541 22314           lssl->recordHeadLen = SSL3_HEADER_LEN;
1542 22314           lssl->hshakeHeadLen = SSL3_HANDSHAKE_HEADER_LEN;
1543              
1544             #ifdef SSL_REHANDSHAKES_ENABLED
1545 22314           lssl->rehandshakeCount = DEFAULT_RH_CREDITS;
1546             #endif /* SSL_REHANDSHAKES_ENABLED */
1547              
1548             #ifdef USE_DTLS
1549             if (flags & SSL_FLAGS_DTLS)
1550             {
1551             # ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
1552             if (options->useExtCvSigOp)
1553             {
1554             psTraceInfo("Error: External CertificateVerify signing ");
1555             psTraceInfo("not supported with the DTLS protocol\n");
1556             return PS_ARG_FAIL;
1557             }
1558             # endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */
1559             lssl->flags |= SSL_FLAGS_DTLS;
1560             lssl->recordHeadLen += DTLS_HEADER_ADD_LEN;
1561             lssl->hshakeHeadLen += DTLS_HEADER_ADD_LEN;
1562             lssl->pmtu = matrixDtlsGetPmtu();
1563             # ifdef USE_CLIENT_SIDE_SSL
1564             lssl->haveCookie = 0;
1565             # endif
1566             lssl->flightDone = 0;
1567             lssl->appDataExch = 0;
1568             lssl->lastMsn = -1;
1569             dtlsInitFrag(lssl);
1570             }
1571             #endif /* USE_DTLS */
1572              
1573 22314 100         if (flags & SSL_FLAGS_SERVER)
1574             {
1575 11158           lssl->flags |= SSL_FLAGS_SERVER;
1576             /*
1577             Client auth can only be requested by server, not set by client
1578             */
1579 11158 50         if (flags & SSL_FLAGS_CLIENT_AUTH)
1580             {
1581 0           lssl->flags |= SSL_FLAGS_CLIENT_AUTH;
1582             }
1583 11158           lssl->hsState = SSL_HS_CLIENT_HELLO;
1584              
1585             /* Is caller requesting specific protocol version for this client?
1586             Make sure it's enabled and use specificVersion var for err */
1587 11158           specificVersion = 0;
1588 11158 50         if (flags & SSL_FLAGS_SSLV3)
1589             {
1590             #ifndef DISABLE_SSLV3
1591             lssl->majVer = SSL3_MAJ_VER;
1592             lssl->minVer = SSL3_MIN_VER;
1593             #else
1594 0           specificVersion = 1;
1595             #endif
1596             }
1597              
1598 11158 50         if (flags & SSL_FLAGS_TLS_1_0)
1599             {
1600             #ifdef USE_TLS
1601             # ifndef DISABLE_TLS_1_0
1602 0           lssl->majVer = TLS_MAJ_VER;
1603 0           lssl->minVer = TLS_MIN_VER;
1604             # else
1605             specificVersion = 1; /* TLS enabled but TLS_1_0 disabled */
1606             # endif
1607             #else
1608             specificVersion = 1; /* TLS not even enabled */
1609             #endif
1610             }
1611              
1612 11158 50         if (flags & SSL_FLAGS_TLS_1_1)
1613             {
1614             #ifdef USE_TLS_1_1
1615             # ifndef DISABLE_TLS_1_1
1616 0           lssl->majVer = TLS_MAJ_VER;
1617 0           lssl->minVer = TLS_1_1_MIN_VER;
1618             # else
1619             specificVersion = 1; /* TLS_1_1 enabled but TLS_1_1 disabled */
1620             # endif
1621             #else
1622             specificVersion = 1; /* TLS not even enabled */
1623             #endif
1624             }
1625              
1626 11158 50         if (flags & SSL_FLAGS_TLS_1_2)
1627             {
1628             #ifdef USE_TLS_1_2
1629 0           lssl->majVer = TLS_MAJ_VER;
1630 0           lssl->minVer = TLS_1_2_MIN_VER;
1631             #else
1632             specificVersion = 1; /* TLS_1_2 disabled */
1633             #endif
1634             }
1635              
1636 11158 50         if (specificVersion)
1637             {
1638             psTraceInfo("ERROR: protocol version isn't compiled into matrix\n");
1639 0           matrixSslDeleteSession(lssl);
1640 0           return PS_ARG_FAIL;
1641             }
1642              
1643             #ifdef USE_DTLS
1644             /* FLAGS_DTLS used in conjuction with specific 1.1 or 1.2 protocol */
1645             if (flags & SSL_FLAGS_DTLS)
1646             {
1647             if (lssl->majVer)
1648             {
1649             if (lssl->minVer == SSL3_MIN_VER || lssl->minVer == TLS_MIN_VER)
1650             {
1651             psTraceInfo("ERROR: Can't use SSLv3 or TLS1.0 with DTLS\n");
1652             matrixSslDeleteSession(lssl);
1653             return PS_ARG_FAIL;
1654             }
1655             lssl->majVer = DTLS_MAJ_VER;
1656             if (lssl->minVer == TLS_1_2_MIN_VER)
1657             {
1658             lssl->minVer = DTLS_1_2_MIN_VER;
1659             }
1660             else if (lssl->minVer == TLS_1_1_MIN_VER)
1661             {
1662             lssl->minVer = DTLS_MIN_VER;
1663             }
1664             else
1665             {
1666             psTraceInfo("ERROR: Protocol version parse error\n");
1667             matrixSslDeleteSession(lssl);
1668             return PS_ARG_FAIL;
1669             }
1670             }
1671             }
1672             #endif
1673              
1674             }
1675             else
1676             {
1677             /*
1678             Client is first to set protocol version information based on
1679             compile and/or the 'flags' parameter so header information in
1680             the handshake messages will be correctly set.
1681              
1682             Look for specific version first... but still have to make sure library
1683             has been compiled to support it
1684             */
1685 11156           specificVersion = 0;
1686              
1687 11156 50         if (flags & SSL_FLAGS_SSLV3)
1688             {
1689             #ifndef DISABLE_SSLV3
1690             lssl->majVer = SSL3_MAJ_VER;
1691             lssl->minVer = SSL3_MIN_VER;
1692             specificVersion = 1;
1693             #else
1694 0           specificVersion = 2;
1695             #endif
1696             }
1697              
1698 11156 50         if (flags & SSL_FLAGS_TLS_1_0)
1699             {
1700             #ifdef USE_TLS
1701             # ifndef DISABLE_TLS_1_0
1702 0           lssl->majVer = TLS_MAJ_VER;
1703 0           lssl->minVer = TLS_MIN_VER;
1704 0           lssl->flags |= SSL_FLAGS_TLS;
1705 0           specificVersion = 1;
1706             # else
1707             specificVersion = 2; /* TLS enabled but TLS_1_0 disabled */
1708             # endif
1709             #else
1710             specificVersion = 2; /* TLS not even enabled */
1711             #endif
1712             }
1713              
1714 11156 50         if (flags & SSL_FLAGS_TLS_1_1)
1715             {
1716             #ifdef USE_TLS_1_1
1717             # ifndef DISABLE_TLS_1_1
1718 0           lssl->majVer = TLS_MAJ_VER;
1719 0           lssl->minVer = TLS_1_1_MIN_VER;
1720 0           lssl->flags |= SSL_FLAGS_TLS | SSL_FLAGS_TLS_1_1;
1721 0           specificVersion = 1;
1722             # else
1723             specificVersion = 2; /* TLS_1_1 enabled but TLS_1_1 disabled */
1724             # endif
1725             #else
1726             specificVersion = 2; /* TLS not even enabled */
1727             #endif
1728             }
1729              
1730 11156 50         if (flags & SSL_FLAGS_TLS_1_2)
1731             {
1732             #ifdef USE_TLS_1_2
1733 0           lssl->majVer = TLS_MAJ_VER;
1734 0           lssl->minVer = TLS_1_2_MIN_VER;
1735 0           lssl->flags |= SSL_FLAGS_TLS | SSL_FLAGS_TLS_1_1 | SSL_FLAGS_TLS_1_2;
1736 0           specificVersion = 1;
1737             #else
1738             specificVersion = 2; /* TLS_1_2 disabled */
1739             #endif
1740             }
1741              
1742 11156 50         if (specificVersion == 2)
1743             {
1744             psTraceInfo("ERROR: protocol version isn't compiled into matrix\n");
1745 0           matrixSslDeleteSession(lssl);
1746 0           return PS_ARG_FAIL;
1747             }
1748              
1749 11156 50         if (specificVersion == 0)
1750             {
1751             /* Highest available if not specified (or not legal value) */
1752             #ifdef USE_TLS
1753             # ifndef DISABLE_TLS_1_0
1754 11156           lssl->majVer = TLS_MAJ_VER;
1755 11156           lssl->minVer = TLS_MIN_VER;
1756             # endif
1757             # if defined(USE_TLS_1_1) && !defined(DISABLE_TLS_1_1)
1758 11156           lssl->majVer = TLS_MAJ_VER;
1759 11156           lssl->minVer = TLS_1_1_MIN_VER;
1760 11156           lssl->flags |= SSL_FLAGS_TLS_1_1;
1761             # endif /* USE_TLS_1_1 */
1762             # ifdef USE_TLS_1_2
1763 11156           lssl->majVer = TLS_MAJ_VER;
1764 11156           lssl->minVer = TLS_1_2_MIN_VER;
1765 11156           lssl->flags |= SSL_FLAGS_TLS_1_2 | SSL_FLAGS_TLS_1_1;
1766             # endif
1767 11156 50         if (lssl->majVer == 0)
1768             {
1769             /* USE_TLS enabled but all DISABLE_TLS versions are enabled so
1770             use SSLv3. Compile time tests would catch if no versions
1771             are enabled at all */
1772 0           lssl->majVer = SSL3_MAJ_VER;
1773 0           lssl->minVer = SSL3_MIN_VER;
1774             }
1775             else
1776             {
1777 11156           lssl->flags |= SSL_FLAGS_TLS;
1778             }
1779              
1780             # ifdef USE_DTLS
1781             /* ssl->flags will have already been set above. Just set version */
1782             if (flags & SSL_FLAGS_DTLS)
1783             {
1784             lssl->minVer = DTLS_MIN_VER;
1785             lssl->majVer = DTLS_MAJ_VER;
1786             # ifdef USE_TLS_1_2
1787             lssl->minVer = DTLS_1_2_MIN_VER;
1788             # endif
1789             }
1790             # endif /* USE_DTLS */
1791              
1792             #else /* USE_TLS */
1793             lssl->majVer = SSL3_MAJ_VER;
1794             lssl->minVer = SSL3_MIN_VER;
1795             #endif /* USE_TLS */
1796             } /* end non-specific version */
1797              
1798             #ifdef USE_DTLS
1799             if (flags & SSL_FLAGS_DTLS && specificVersion == 1)
1800             {
1801             lssl->majVer = DTLS_MAJ_VER;
1802             if (lssl->minVer == TLS_1_2_MIN_VER)
1803             {
1804             lssl->minVer = DTLS_1_2_MIN_VER;
1805             }
1806             else if (lssl->minVer == TLS_1_1_MIN_VER)
1807             {
1808             lssl->minVer = DTLS_MIN_VER;
1809             }
1810             else
1811             {
1812             psTraceInfo("ERROR: DTLS must be TLS 1.1 or TLS 1.2\n");
1813             matrixSslDeleteSession(lssl);
1814             return PS_ARG_FAIL;
1815             }
1816             }
1817             #endif
1818              
1819 11156           lssl->hsState = SSL_HS_SERVER_HELLO;
1820 11156 100         if (session != NULL && session->cipherId != SSL_NULL_WITH_NULL_NULL)
    50          
1821             {
1822 0           lssl->cipher = sslGetCipherSpec(lssl, session->cipherId);
1823 0 0         if (lssl->cipher == NULL)
1824             {
1825             psTraceInfo("Invalid session id to matrixSslNewSession\n");
1826             }
1827             else
1828             {
1829 0           memcpy(lssl->sec.masterSecret, session->masterSecret,
1830             SSL_HS_MASTER_SIZE);
1831 0           lssl->sessionIdLen = SSL_MAX_SESSION_ID_SIZE;
1832 0           memcpy(lssl->sessionId, session->id, SSL_MAX_SESSION_ID_SIZE);
1833             #ifdef USE_STATELESS_SESSION_TICKETS
1834             /* Possible no sessionId here at all if tickets used instead.
1835             Will know if all 0s */
1836 0           lssl->sessionIdLen = 0;
1837 0 0         for (i = 0; i < SSL_MAX_SESSION_ID_SIZE; i++)
1838             {
1839 0 0         if (session->id[i] != 0x0)
1840             {
1841 0           lssl->sessionIdLen = SSL_MAX_SESSION_ID_SIZE;
1842 0           break;
1843             }
1844             }
1845             #endif
1846             }
1847             }
1848 11156           lssl->sid = session;
1849             }
1850             /* Clear these to minimize damage on a protocol parsing bug */
1851 22314           memset(lssl->inbuf, 0x0, lssl->insize);
1852 22314           memset(lssl->outbuf, 0x0, lssl->outsize);
1853 22314           lssl->err = SSL_ALERT_NONE;
1854 22314           lssl->encState = SSL_HS_NONE;
1855 22314           lssl->decState = SSL_HS_NONE;
1856 22314           *ssl = lssl;
1857 22314           return PS_SUCCESS;
1858             }
1859              
1860             /******************************************************************************/
1861             /*
1862             Delete an SSL session. Some information on the session may stay around
1863             in the session resumption cache.
1864             SECURITY - We memset relevant values to zero before freeing to reduce
1865             the risk of our keys floating around in memory after we're done.
1866             */
1867 22314           void matrixSslDeleteSession(ssl_t *ssl)
1868             {
1869              
1870 22314 50         if (ssl == NULL)
1871             {
1872 0           return;
1873             }
1874              
1875 22314           ssl->flags |= SSL_FLAGS_CLOSED;
1876              
1877             /* Synchronize all digests, in case some of them have been updated, but
1878             not finished. */
1879             #ifdef USE_TLS_1_2
1880 22314           psSha256Sync(NULL, 1);
1881             #else /* !USE_TLS_1_2 */
1882             psSha1Sync(NULL, 1);
1883             #endif /* USE_TLS_1_2 */
1884              
1885             /*
1886             If we have a sessionId, for servers we need to clear the inUse flag in
1887             the session cache so the ID can be replaced if needed. In the client case
1888             the caller should have called matrixSslGetSessionId already to copy the
1889             master secret and sessionId, so free it now.
1890              
1891             In all cases except a successful updateSession call on the server, the
1892             master secret must be freed.
1893             */
1894             #ifdef USE_SERVER_SIDE_SSL
1895 22314 100         if (ssl->sessionIdLen > 0 && (ssl->flags & SSL_FLAGS_SERVER))
    100          
1896             {
1897 1142           matrixUpdateSession(ssl);
1898             }
1899             # ifdef USE_STATELESS_SESSION_TICKETS
1900 22314 100         if ((ssl->flags & SSL_FLAGS_SERVER) && ssl->sid)
    50          
1901             {
1902 0           psFree(ssl->sid, ssl->sPool);
1903 0           ssl->sid = NULL;
1904             }
1905             # endif
1906             #endif /* USE_SERVER_SIDE_SSL */
1907              
1908 22314           ssl->sessionIdLen = 0;
1909              
1910 22314 50         if (ssl->expectedName)
1911             {
1912 0           psFree(ssl->expectedName, ssl->sPool);
1913             }
1914             #ifndef USE_ONLY_PSK_CIPHER_SUITE
1915             # if defined(USE_CLIENT_SIDE_SSL) || defined(USE_CLIENT_AUTH)
1916 22314 100         if (ssl->sec.cert)
1917             {
1918 90           psX509FreeCert(ssl->sec.cert);
1919 90           ssl->sec.cert = NULL;
1920             }
1921              
1922             # endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */
1923             #endif /* !USE_ONLY_PSK_CIPHER_SUITE */
1924              
1925             #ifdef REQUIRE_DH_PARAMS
1926 22314 50         if (ssl->sec.dhP)
1927             {
1928 0           psFree(ssl->sec.dhP, ssl->hsPool); ssl->sec.dhP = NULL;
1929             }
1930 22314 50         if (ssl->sec.dhG)
1931             {
1932 0           psFree(ssl->sec.dhG, ssl->hsPool); ssl->sec.dhG = NULL;
1933             }
1934 22314 50         if (ssl->sec.dhKeyPub)
1935             {
1936 0           psDhClearKey(ssl->sec.dhKeyPub);
1937 0           psFree(ssl->sec.dhKeyPub, ssl->hsPool);
1938 0           ssl->sec.dhKeyPub = NULL;
1939             }
1940 22314 50         if (ssl->sec.dhKeyPriv)
1941             {
1942 0           psDhClearKey(ssl->sec.dhKeyPriv);
1943 0           psFree(ssl->sec.dhKeyPriv, ssl->hsPool);
1944 0           ssl->sec.dhKeyPriv = NULL;
1945             }
1946             #endif /* REQUIRE_DH_PARAMS */
1947              
1948             #ifdef USE_ECC_CIPHER_SUITE
1949 22314 50         if (ssl->sec.eccKeyPub)
1950             {
1951 0           psEccDeleteKey(&ssl->sec.eccKeyPub);
1952             }
1953 22314 100         if (ssl->sec.eccKeyPriv)
1954             {
1955 90           psEccDeleteKey(&ssl->sec.eccKeyPriv);
1956             }
1957             #endif /* USE_ECC_CIPHER_SUITE */
1958              
1959             /*
1960             Premaster could also be allocated if this DeleteSession is the result
1961             of a failed handshake. This test is fine since all frees will NULL pointer
1962             */
1963 22314 50         if (ssl->sec.premaster)
1964             {
1965 0           psFree(ssl->sec.premaster, ssl->hsPool);
1966             }
1967 22314 50         if (ssl->fragMessage)
1968             {
1969 0           psFree(ssl->fragMessage, ssl->hsPool);
1970             }
1971              
1972             #ifdef USE_DTLS
1973             # ifdef USE_CLIENT_SIDE_SSL
1974             if (ssl->cookie)
1975             {
1976             psFree(ssl->cookie, ssl->hsPool);
1977             }
1978             # endif
1979             if (ssl->helloExt)
1980             {
1981             psFree(ssl->helloExt, ssl->hsPool);
1982             }
1983             dtlsInitFrag(ssl);
1984             if (ssl->ckeMsg)
1985             {
1986             psFree(ssl->ckeMsg, ssl->hsPool);
1987             }
1988             if (ssl->certVerifyMsg)
1989             {
1990             psFree(ssl->certVerifyMsg, ssl->hsPool);
1991             }
1992             # if defined(USE_PSK_CIPHER_SUITE) && defined(USE_CLIENT_SIDE_SSL)
1993             if (ssl->sec.hint)
1994             {
1995             psFree(ssl->sec.hint, ssl->hsPool);
1996             }
1997             # endif
1998             #endif /* USE_DTLS */
1999              
2000             /*
2001             Free the data buffers, clear any remaining user data
2002             */
2003 22314           memset(ssl->inbuf, 0x0, ssl->insize);
2004 22314           memset(ssl->outbuf, 0x0, ssl->outsize);
2005 22314           psFree(ssl->outbuf, ssl->bufferPool);
2006 22314           psFree(ssl->inbuf, ssl->bufferPool);
2007              
2008 22314           freePkaAfter(ssl);
2009 22314           clearFlightList(ssl);
2010              
2011             #ifdef USE_ALPN
2012 22314 50         if (ssl->alpn)
2013             {
2014 0           psFree(ssl->alpn, ssl->sPool); ssl->alpn = NULL;
2015             }
2016             #endif
2017             /*
2018             The cipher and mac contexts are inline in the ssl structure, so
2019             clearing the structure clears those states as well.
2020             */
2021 22314           memset(ssl, 0x0, sizeof(ssl_t));
2022 22314           psFree(ssl, pool);
2023             }
2024              
2025             /******************************************************************************/
2026             /*
2027             Generic session option control for changing already connected sessions.
2028             (ie. rehandshake control). arg param is future for options that may
2029             require a value.
2030             */
2031 9           void matrixSslSetSessionOption(ssl_t *ssl, int32 option, void *arg)
2032             {
2033 9 50         if (option == SSL_OPTION_FULL_HANDSHAKE)
2034             {
2035             #ifdef USE_SERVER_SIDE_SSL
2036 9 50         if (ssl->flags & SSL_FLAGS_SERVER)
2037             {
2038 0           matrixClearSession(ssl, 1);
2039             }
2040             #endif /* USE_SERVER_SIDE_SSL */
2041 9           ssl->sessionIdLen = 0;
2042 9           memset(ssl->sessionId, 0x0, SSL_MAX_SESSION_ID_SIZE);
2043             }
2044              
2045             #ifdef SSL_REHANDSHAKES_ENABLED
2046 9 50         if (option == SSL_OPTION_DISABLE_REHANDSHAKES)
2047             {
2048 0           ssl->rehandshakeCount = -1;
2049             }
2050             /* Get one credit if re-enabling */
2051 9 50         if (option == SSL_OPTION_REENABLE_REHANDSHAKES)
2052             {
2053 0           ssl->rehandshakeCount = 1;
2054             }
2055             #endif
2056              
2057             #if defined(USE_CLIENT_AUTH) && defined(USE_SERVER_SIDE_SSL)
2058 9 50         if (ssl->flags & SSL_FLAGS_SERVER)
2059             {
2060 0 0         if (option == SSL_OPTION_DISABLE_CLIENT_AUTH)
2061             {
2062 0           ssl->flags &= ~SSL_FLAGS_CLIENT_AUTH;
2063             }
2064 0 0         else if (option == SSL_OPTION_ENABLE_CLIENT_AUTH)
2065             {
2066 0           ssl->flags |= SSL_FLAGS_CLIENT_AUTH;
2067 0           matrixClearSession(ssl, 1);
2068             }
2069             }
2070             #endif /* USE_CLIENT_AUTH && USE_SERVER_SIDE_SSL */
2071 9           }
2072              
2073             /******************************************************************************/
2074             /*
2075             Will be true if the cipher suite is an 'anon' variety OR if the
2076             user certificate callback returned SSL_ALLOW_ANON_CONNECTION
2077             */
2078 2           void matrixSslGetAnonStatus(ssl_t *ssl, int32 *certArg)
2079             {
2080 2           *certArg = ssl->sec.anon;
2081 2           }
2082              
2083              
2084             #ifdef USE_SSL_INFORMATIONAL_TRACE
2085             void matrixSslPrintHSDetails(ssl_t *ssl)
2086             {
2087             if (ssl->hsState == SSL_HS_DONE)
2088             {
2089             psTraceInfo("\n");
2090             if (ssl->minVer == SSL3_MIN_VER)
2091             {
2092             psTraceInfo("SSL 3.0 ");
2093             }
2094             else if (ssl->minVer == TLS_MIN_VER)
2095             {
2096             psTraceInfo("TLS 1.0 ");
2097             }
2098             else if (ssl->minVer == TLS_1_1_MIN_VER)
2099             {
2100             psTraceInfo("TLS 1.1 ");
2101             }
2102             else if (ssl->minVer == TLS_1_2_MIN_VER)
2103             {
2104             psTraceInfo("TLS 1.2 ");
2105             }
2106             # ifdef USE_DTLS
2107             else if (ssl->minVer == DTLS_1_2_MIN_VER)
2108             {
2109             psTraceInfo("DTLS 1.2 ");
2110             }
2111             else if (ssl->minVer == DTLS_MIN_VER)
2112             {
2113             psTraceInfo("DTLS 1.0 ");
2114             }
2115             # endif
2116             psTraceInfo("connection established: ");
2117             switch (ssl->cipher->ident)
2118             {
2119             case SSL_RSA_WITH_NULL_MD5:
2120             psTraceInfo("SSL_RSA_WITH_NULL_MD5\n");
2121             break;
2122             case SSL_RSA_WITH_NULL_SHA:
2123             psTraceInfo("SSL_RSA_WITH_NULL_SHA\n");
2124             break;
2125             case SSL_RSA_WITH_RC4_128_MD5:
2126             psTraceInfo("SSL_RSA_WITH_RC4_128_MD5\n");
2127             break;
2128             case SSL_RSA_WITH_RC4_128_SHA:
2129             psTraceInfo("SSL_RSA_WITH_RC4_128_SHA\n");
2130             break;
2131             case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
2132             psTraceInfo("SSL_RSA_WITH_3DES_EDE_CBC_SHA\n");
2133             break;
2134             case TLS_RSA_WITH_AES_128_CBC_SHA:
2135             psTraceInfo("TLS_RSA_WITH_AES_128_CBC_SHA\n");
2136             break;
2137             case TLS_RSA_WITH_AES_256_CBC_SHA:
2138             psTraceInfo("TLS_RSA_WITH_AES_256_CBC_SHA\n");
2139             break;
2140             case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
2141             psTraceInfo("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA\n");
2142             break;
2143             case SSL_DH_anon_WITH_RC4_128_MD5:
2144             psTraceInfo("SSL_DH_anon_WITH_RC4_128_MD5\n");
2145             break;
2146             case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
2147             psTraceInfo("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA\n");
2148             break;
2149             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
2150             psTraceInfo("TLS_DHE_RSA_WITH_AES_128_CBC_SHA\n");
2151             break;
2152             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
2153             psTraceInfo("TLS_DHE_RSA_WITH_AES_256_CBC_SHA\n");
2154             break;
2155             case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
2156             psTraceInfo("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256\n");
2157             break;
2158             case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
2159             psTraceInfo("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256\n");
2160             break;
2161             case TLS_DH_anon_WITH_AES_128_CBC_SHA:
2162             psTraceInfo("TLS_DH_anon_WITH_AES_128_CBC_SHA\n");
2163             break;
2164             case TLS_DH_anon_WITH_AES_256_CBC_SHA:
2165             psTraceInfo("TLS_DH_anon_WITH_AES_256_CBC_SHA\n");
2166             break;
2167             case TLS_RSA_WITH_AES_128_CBC_SHA256:
2168             psTraceInfo("TLS_RSA_WITH_AES_128_CBC_SHA256\n");
2169             break;
2170             case TLS_RSA_WITH_AES_256_CBC_SHA256:
2171             psTraceInfo("TLS_RSA_WITH_AES_256_CBC_SHA256\n");
2172             break;
2173             case TLS_RSA_WITH_SEED_CBC_SHA:
2174             psTraceInfo("TLS_RSA_WITH_SEED_CBC_SHA\n");
2175             break;
2176             case TLS_RSA_WITH_IDEA_CBC_SHA:
2177             psTraceInfo("TLS_RSA_WITH_IDEA_CBC_SHA\n");
2178             break;
2179             case TLS_PSK_WITH_AES_128_CBC_SHA:
2180             psTraceInfo("TLS_PSK_WITH_AES_128_CBC_SHA\n");
2181             break;
2182             case TLS_PSK_WITH_AES_128_CBC_SHA256:
2183             psTraceInfo("TLS_PSK_WITH_AES_128_CBC_SHA256\n");
2184             break;
2185             case TLS_PSK_WITH_AES_256_CBC_SHA384:
2186             psTraceInfo("TLS_PSK_WITH_AES_256_CBC_SHA384\n");
2187             break;
2188             case TLS_PSK_WITH_AES_256_CBC_SHA:
2189             psTraceInfo("TLS_PSK_WITH_AES_256_CBC_SHA\n");
2190             break;
2191             case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
2192             psTraceInfo("TLS_DHE_PSK_WITH_AES_128_CBC_SHA\n");
2193             break;
2194             case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
2195             psTraceInfo("TLS_DHE_PSK_WITH_AES_256_CBC_SHA\n");
2196             break;
2197             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
2198             psTraceInfo("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA\n");
2199             break;
2200             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
2201             psTraceInfo("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA\n");
2202             break;
2203             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
2204             psTraceInfo("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA\n");
2205             break;
2206             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
2207             psTraceInfo("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA\n");
2208             break;
2209             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
2210             psTraceInfo("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA\n");
2211             break;
2212             case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
2213             psTraceInfo("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA\n");
2214             break;
2215             case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
2216             psTraceInfo("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256\n");
2217             break;
2218             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
2219             psTraceInfo("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384\n");
2220             break;
2221             case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
2222             psTraceInfo("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA\n");
2223             break;
2224             case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
2225             psTraceInfo("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256\n");
2226             break;
2227             case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
2228             psTraceInfo("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n");
2229             break;
2230             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
2231             psTraceInfo("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA\n");
2232             break;
2233             case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
2234             psTraceInfo("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256\n");
2235             break;
2236             case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
2237             psTraceInfo("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384\n");
2238             break;
2239             case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
2240             psTraceInfo("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256\n");
2241             break;
2242             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
2243             psTraceInfo("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384\n");
2244             break;
2245             case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
2246             psTraceInfo("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA\n");
2247             break;
2248             case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
2249             psTraceInfo("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256\n");
2250             break;
2251             case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
2252             psTraceInfo("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384\n");
2253             break;
2254             case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
2255             psTraceInfo("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256\n");
2256             break;
2257             case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
2258             psTraceInfo("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384\n");
2259             break;
2260             case TLS_RSA_WITH_AES_128_GCM_SHA256:
2261             psTraceInfo("TLS_RSA_WITH_AES_128_GCM_SHA256\n");
2262             break;
2263             case TLS_RSA_WITH_AES_256_GCM_SHA384:
2264             psTraceInfo("TLS_RSA_WITH_AES_256_GCM_SHA384\n");
2265             break;
2266             case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
2267             psTraceInfo("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256\n");
2268             break;
2269             case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
2270             psTraceInfo("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384\n");
2271             break;
2272             case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
2273             psTraceInfo("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256\n");
2274             break;
2275             case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
2276             psTraceInfo("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384\n");
2277             break;
2278             case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
2279             psTraceInfo("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256\n");
2280             break;
2281             case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
2282             psTraceInfo("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256\n");
2283             break;
2284             default:
2285             psTraceIntInfo("!!!! DEFINE ME %d !!!!\n", ssl->cipher->ident);
2286             }
2287             }
2288             return;
2289             }
2290             #endif
2291              
2292             /******************************************************************************/
2293             /**
2294             @return PS_TRUE if we've completed the SSL handshake. PS_FALSE otherwise.
2295             */
2296 22710           int32_t matrixSslHandshakeIsComplete(const ssl_t *ssl)
2297             {
2298 22710           return (ssl->hsState == SSL_HS_DONE) ? PS_TRUE : PS_FALSE;
2299             }
2300              
2301             #if defined(USE_CLIENT_SIDE_SSL) || defined(USE_CLIENT_AUTH)
2302             /******************************************************************************/
2303             /*
2304             Set a custom callback to receive the certificate being presented to the
2305             session to perform custom authentication if needed
2306              
2307             NOTE: Must define either USE_CLIENT_SIDE_SSL or USE_CLIENT_AUTH
2308             in matrixConfig.h
2309             */
2310 10129           void matrixSslSetCertValidator(ssl_t *ssl, sslCertCb_t certValidator)
2311             {
2312 10129 50         if ((ssl != NULL) && (certValidator != NULL))
    50          
2313             {
2314             # ifndef USE_ONLY_PSK_CIPHER_SUITE
2315 10129           ssl->sec.validateCert = certValidator;
2316             # endif /* !USE_ONLY_PSK_CIPHER_SUITE */
2317             }
2318 10129           }
2319             #endif /* USE_CLIENT_SIDE_SSL || USE_CLIENT_AUTH */
2320              
2321             # ifdef USE_SERVER_SIDE_SSL
2322             /******************************************************************************/
2323             /*
2324             Initialize the session table.
2325             */
2326 17           static void initSessionEntryChronList(void)
2327             {
2328             uint32 i;
2329              
2330 17           DLListInit(&g_sessionChronList);
2331             /* Assign every session table entry with their ID from the start */
2332 561 100         for (i = 0; i < SSL_SESSION_TABLE_SIZE; i++)
2333             {
2334 544 50         DLListInsertTail(&g_sessionChronList, &g_sessionTable[i].chronList);
2335 544           g_sessionTable[i].id[0] = (unsigned char) (i & 0xFF);
2336 544           g_sessionTable[i].id[1] = (unsigned char) ((i & 0xFF00) >> 8);
2337 544           g_sessionTable[i].id[2] = (unsigned char) ((i & 0xFF0000) >> 16);
2338 544           g_sessionTable[i].id[3] = (unsigned char) ((i & 0xFF000000) >> 24);
2339             }
2340 17           }
2341              
2342             /******************************************************************************/
2343             /*
2344             Register a session in the session resumption cache. If successful (rc >=0),
2345             the ssl sessionId and sessionIdLength fields will be non-NULL upon
2346             return.
2347             */
2348 1147           int32 matrixRegisterSession(ssl_t *ssl)
2349             {
2350             uint32 i;
2351             sslSessionEntry_t *sess;
2352             DLListEntry *pList;
2353             unsigned char *id;
2354              
2355 1147 50         if (!(ssl->flags & SSL_FLAGS_SERVER))
2356             {
2357 0           return PS_FAILURE;
2358             }
2359              
2360             # ifdef USE_STATELESS_SESSION_TICKETS
2361             /* Tickets override the other resumption mechanism */
2362 1147 50         if (ssl->sid &&
    0          
2363 0           (ssl->sid->sessionTicketState == SESS_TICKET_STATE_RECVD_EXT))
2364             {
2365             /* Have recieved new ticket usage request by client */
2366 0           return PS_SUCCESS;
2367             }
2368             # endif
2369              
2370             # ifdef USE_DTLS
2371             /*
2372             Don't reassign a new sessionId if we already have one or we blow the
2373             handshake hash
2374             */
2375             if ((ssl->flags & SSL_FLAGS_DTLS) && ssl->sessionIdLen > 0)
2376             {
2377             /* This is a retransmit case */
2378             return PS_SUCCESS;
2379             }
2380             # endif
2381              
2382             /*
2383             Iterate the session table, looking for an empty entry (cipher null), or
2384             the oldest entry that is not in use
2385             */
2386             psLockMutex(&g_sessionTableLock);
2387              
2388 1147 50         if (DLListIsEmpty(&g_sessionChronList))
2389             {
2390             /* All in use */
2391             psUnlockMutex(&g_sessionTableLock);
2392 0           return PS_LIMIT_FAIL;
2393              
2394             }
2395             /* GetHead Detaches */
2396 1147           pList = DLListGetHead(&g_sessionChronList);
2397 1147           sess = DLListGetContainer(pList, sslSessionEntry_t, chronList);
2398 1147           id = sess->id;
2399 1147           i = (id[3] << 24) + (id[2] << 16) + (id[1] << 8) + id[0];
2400 1147 50         if (i >= SSL_SESSION_TABLE_SIZE)
2401             {
2402             psUnlockMutex(&g_sessionTableLock);
2403 0           return PS_LIMIT_FAIL;
2404             }
2405              
2406             /*
2407             Register the incoming masterSecret and cipher, which could still be null,
2408             depending on when we're called.
2409             */
2410 1147           memcpy(g_sessionTable[i].masterSecret, ssl->sec.masterSecret,
2411             SSL_HS_MASTER_SIZE);
2412 1147           g_sessionTable[i].cipher = ssl->cipher;
2413 1147           g_sessionTable[i].inUse += 1;
2414             /*
2415             The sessionId is the current serverRandom value, with the first 4 bytes
2416             replaced with the current cache index value for quick lookup later.
2417             FUTURE SECURITY - Should generate more random bytes here for the session
2418             id. We re-use the server random as the ID, which is OK, since it is
2419             sent plaintext on the network, but an attacker listening to a resumed
2420             connection will also be able to determine part of the original server
2421             random used to generate the master key, even if he had not seen it
2422             initially.
2423             */
2424 1147           memcpy(g_sessionTable[i].id + 4, ssl->sec.serverRandom,
2425             min(SSL_HS_RANDOM_SIZE, SSL_MAX_SESSION_ID_SIZE) - 4);
2426 1147           ssl->sessionIdLen = SSL_MAX_SESSION_ID_SIZE;
2427              
2428 1147           memcpy(ssl->sessionId, g_sessionTable[i].id, SSL_MAX_SESSION_ID_SIZE);
2429             /*
2430             startTime is used to check expiry of the entry
2431              
2432             The versions are stored, because a cached session must be reused
2433             with same SSL version.
2434             */
2435 1147           psGetTime(&g_sessionTable[i].startTime, ssl->userPtr);
2436 1147           g_sessionTable[i].majVer = ssl->majVer;
2437 1147           g_sessionTable[i].minVer = ssl->minVer;
2438              
2439 1147           g_sessionTable[i].extendedMasterSecret = ssl->extFlags.extended_master_secret;
2440              
2441             psUnlockMutex(&g_sessionTableLock);
2442 1147           return i;
2443             }
2444              
2445             /******************************************************************************/
2446             /*
2447             Decrement inUse to keep the reference count meaningful
2448             */
2449 7           int32 matrixClearSession(ssl_t *ssl, int32 remove)
2450             {
2451             unsigned char *id;
2452             uint32 i;
2453              
2454 7 50         if (ssl->sessionIdLen <= 0)
2455             {
2456 0           return PS_ARG_FAIL;
2457             }
2458 7           id = ssl->sessionId;
2459              
2460 7           i = (id[3] << 24) + (id[2] << 16) + (id[1] << 8) + id[0];
2461 7 50         if (i >= SSL_SESSION_TABLE_SIZE)
2462             {
2463 0           return PS_LIMIT_FAIL;
2464             }
2465             psLockMutex(&g_sessionTableLock);
2466 7           g_sessionTable[i].inUse -= 1;
2467 7 50         if (g_sessionTable[i].inUse == 0)
2468             {
2469 7 50         DLListInsertTail(&g_sessionChronList, &g_sessionTable[i].chronList);
2470             }
2471              
2472             /*
2473             If this is a full removal, actually delete the entry. Also need to
2474             clear any RESUME flag on the ssl connection so a new session
2475             will be correctly registered.
2476             */
2477 7 50         if (remove)
2478             {
2479 0           memset(ssl->sessionId, 0x0, SSL_MAX_SESSION_ID_SIZE);
2480 0           ssl->sessionIdLen = 0;
2481 0           ssl->flags &= ~SSL_FLAGS_RESUMED;
2482             /* Always preserve the id for chronList */
2483 0           memset(g_sessionTable[i].id + 4, 0x0, SSL_MAX_SESSION_ID_SIZE - 4);
2484 0           memset(g_sessionTable[i].masterSecret, 0x0, SSL_HS_MASTER_SIZE);
2485 0           g_sessionTable[i].extendedMasterSecret = 0;
2486 0           g_sessionTable[i].cipher = NULL;
2487             }
2488             psUnlockMutex(&g_sessionTableLock);
2489 7           return PS_SUCCESS;
2490             }
2491              
2492             /******************************************************************************/
2493             /*
2494             Look up a session ID in the cache. If found, set the ssl masterSecret
2495             and cipher to the pre-negotiated values
2496             */
2497 2           int32 matrixResumeSession(ssl_t *ssl)
2498             {
2499             psTime_t accessTime;
2500             unsigned char *id;
2501             uint32 i;
2502              
2503 2 50         if (!(ssl->flags & SSL_FLAGS_SERVER))
2504             {
2505 0           return PS_ARG_FAIL;
2506             }
2507 2 50         if (ssl->sessionIdLen <= 0)
2508             {
2509 0           return PS_ARG_FAIL;
2510             }
2511 2           id = ssl->sessionId;
2512              
2513 2           i = (id[3] << 24) + (id[2] << 16) + (id[1] << 8) + id[0];
2514             psLockMutex(&g_sessionTableLock);
2515 2 50         if (i >= SSL_SESSION_TABLE_SIZE || g_sessionTable[i].cipher == NULL)
    50          
2516             {
2517             psUnlockMutex(&g_sessionTableLock);
2518 0           return PS_LIMIT_FAIL;
2519             }
2520             /*
2521             Id looks valid. Update the access time for expiration check.
2522             Expiration is done on daily basis (86400 seconds)
2523             */
2524 2           psGetTime(&accessTime, ssl->userPtr);
2525 2 50         if ((memcmp(g_sessionTable[i].id, id,
    50          
2526 2 50         (uint32) min(ssl->sessionIdLen, SSL_MAX_SESSION_ID_SIZE)) != 0) ||
2527 2           (psDiffMsecs(g_sessionTable[i].startTime, accessTime, ssl->userPtr) >
2528 2 50         SSL_SESSION_ENTRY_LIFE) || (g_sessionTable[i].majVer != ssl->majVer)
2529 2 50         || (g_sessionTable[i].minVer != ssl->minVer))
2530             {
2531             psUnlockMutex(&g_sessionTableLock);
2532 0           return PS_FAILURE;
2533             }
2534              
2535             /* Enforce the RFC 7627 rules for resumpion and extended master secret.
2536             Essentially, a resumption must use (or not use) the extended master
2537             secret extension in step with the orginal connection */
2538 2 50         if (g_sessionTable[i].extendedMasterSecret == 0 &&
    0          
2539 0           ssl->extFlags.extended_master_secret == 1)
2540             {
2541             psUnlockMutex(&g_sessionTableLock);
2542 0           return PS_FAILURE;
2543             }
2544 2 50         if (g_sessionTable[i].extendedMasterSecret == 1 &&
    50          
2545 2           ssl->extFlags.extended_master_secret == 0)
2546             {
2547             psUnlockMutex(&g_sessionTableLock);
2548 0           return PS_FAILURE;
2549             }
2550              
2551             /* Looks good */
2552 2           memcpy(ssl->sec.masterSecret, g_sessionTable[i].masterSecret,
2553             SSL_HS_MASTER_SIZE);
2554 2           ssl->cipher = g_sessionTable[i].cipher;
2555 2           g_sessionTable[i].inUse += 1;
2556 2 50         if (g_sessionTable[i].inUse == 1)
2557             {
2558 2           DLListRemove(&g_sessionTable[i].chronList);
2559             }
2560             psUnlockMutex(&g_sessionTableLock);
2561              
2562 2           return PS_SUCCESS;
2563             }
2564              
2565             /******************************************************************************/
2566             /*
2567             Update session information in the cache.
2568             This is called when we've determined the master secret and when we're
2569             closing the connection to update various values in the cache.
2570             */
2571 2199           int32 matrixUpdateSession(ssl_t *ssl)
2572             {
2573             unsigned char *id;
2574             uint32 i;
2575              
2576 2199 50         if (!(ssl->flags & SSL_FLAGS_SERVER))
2577             {
2578 0           return PS_ARG_FAIL;
2579             }
2580 2199 50         if (ssl->sessionIdLen == 0)
2581             {
2582             /* No table entry. matrixRegisterSession was full of inUse entries */
2583 0           return PS_LIMIT_FAIL;
2584             }
2585 2199           id = ssl->sessionId;
2586 2199           i = (id[3] << 24) + (id[2] << 16) + (id[1] << 8) + id[0];
2587 2199 50         if (i >= SSL_SESSION_TABLE_SIZE)
2588             {
2589 0           return PS_LIMIT_FAIL;
2590             }
2591             /*
2592             If there is an error on the session, invalidate for any future use
2593             */
2594             psLockMutex(&g_sessionTableLock);
2595 2199 100         g_sessionTable[i].inUse += ssl->flags & SSL_FLAGS_CLOSED ? -1 : 0;
2596 2199 100         if (g_sessionTable[i].inUse == 0)
2597             {
2598             /* End of the line */
2599 1142 50         DLListInsertTail(&g_sessionChronList, &g_sessionTable[i].chronList);
2600             }
2601 2199 100         if (ssl->flags & SSL_FLAGS_ERROR)
2602             {
2603 90           memset(g_sessionTable[i].masterSecret, 0x0, SSL_HS_MASTER_SIZE);
2604 90           g_sessionTable[i].cipher = NULL;
2605             psUnlockMutex(&g_sessionTableLock);
2606 90           return PS_FAILURE;
2607             }
2608 2109           memcpy(g_sessionTable[i].masterSecret, ssl->sec.masterSecret,
2609             SSL_HS_MASTER_SIZE);
2610 2109           g_sessionTable[i].cipher = ssl->cipher;
2611             psUnlockMutex(&g_sessionTableLock);
2612 2109           return PS_SUCCESS;
2613             }
2614              
2615              
2616             # ifdef USE_STATELESS_SESSION_TICKETS
2617             /* This implementation supports AES-128/256_CBC and HMAC-SHA1/256 */
2618              
2619             /******************************************************************************/
2620             /*
2621             Remove a named key from the list.
2622              
2623             NOTE: If this list can get very large the faster DLList API should be
2624             used instead of this single linked list.
2625             */
2626 0           int32 matrixSslDeleteSessionTicketKey(sslKeys_t *keys, unsigned char name[16])
2627             {
2628             psSessionTicketKeys_t *lkey, *prev;
2629              
2630             psLockMutex(&g_sessTicketLock);
2631 0           lkey = keys->sessTickets;
2632 0           prev = NULL;
2633 0 0         while (lkey)
2634             {
2635 0 0         if (lkey->inUse == 0 && (memcmp(lkey->name, name, 16) == 0))
    0          
2636             {
2637 0 0         if (prev == NULL)
2638             {
2639             /* removing the first in the list */
2640 0 0         if (lkey->next == NULL)
2641             {
2642             /* no more list == no more session ticket support */
2643 0           psFree(lkey, keys->pool);
2644 0           keys->sessTickets = NULL;
2645             psUnlockMutex(&g_sessTicketLock);
2646 0           return PS_SUCCESS;
2647             }
2648             /* first in list but not alone */
2649 0           keys->sessTickets = lkey->next;
2650 0           psFree(lkey, keys->pool);
2651             psUnlockMutex(&g_sessTicketLock);
2652 0           return PS_SUCCESS;
2653             }
2654             /* Middle of list. Join previous with our next */
2655 0           prev->next = lkey->next;
2656 0           psFree(lkey, keys->pool);
2657             psUnlockMutex(&g_sessTicketLock);
2658 0           return PS_SUCCESS;
2659             }
2660 0           prev = lkey;
2661 0           lkey = lkey->next;
2662             }
2663             psUnlockMutex(&g_sessTicketLock);
2664 0           return PS_FAILURE; /* not found */
2665              
2666             }
2667              
2668             /******************************************************************************/
2669             /*
2670             This will be called on ticket decryption if the named key is not
2671             in the current local list
2672             */
2673 0           void matrixSslSetSessionTicketCallback(sslKeys_t *keys,
2674             int32 (*ticket_cb)(void *, unsigned char[16], short))
2675             {
2676 0           keys->ticket_cb = ticket_cb;
2677 0           }
2678              
2679             /******************************************************************************/
2680             /*
2681             The first in the list will be the one used for all newly issued tickets
2682             */
2683 1           int32 matrixSslLoadSessionTicketKeys(sslKeys_t *keys,
2684             const unsigned char name[16], const unsigned char *symkey,
2685             short symkeyLen, const unsigned char *hashkey, short hashkeyLen)
2686             {
2687             psSessionTicketKeys_t *keylist, *prev;
2688 1           int32 i = 0;
2689              
2690             /* AES-128 or AES-256 */
2691 1 50         if (symkeyLen != 16 && symkeyLen != 32)
    50          
2692             {
2693 0           return PS_LIMIT_FAIL;
2694             }
2695             /* SHA256 only */
2696 1 50         if (hashkeyLen != 32)
2697             {
2698 0           return PS_LIMIT_FAIL;
2699             }
2700              
2701             psLockMutex(&g_sessTicketLock);
2702 1 50         if (keys->sessTickets == NULL)
2703             {
2704             /* first one */
2705 1           keys->sessTickets = psMalloc(keys->pool, sizeof(psSessionTicketKeys_t));
2706 1 50         if (keys->sessTickets == NULL)
2707             {
2708             psUnlockMutex(&g_sessTicketLock);
2709 0           return PS_MEM_FAIL;
2710             }
2711 1           keylist = keys->sessTickets;
2712             }
2713             else
2714             {
2715             /* append */
2716 0           keylist = keys->sessTickets;
2717 0 0         while (keylist)
2718             {
2719 0           prev = keylist;
2720 0           keylist = keylist->next;
2721 0           i++;
2722             }
2723 0 0         if (i > SSL_SESSION_TICKET_LIST_LEN)
2724             {
2725             psTraceInfo("Session ticket list > SSL_SESSION_TICKET_LIST_LEN\n");
2726             psUnlockMutex(&g_sessTicketLock);
2727 0           return PS_LIMIT_FAIL;
2728             }
2729 0           keylist = psMalloc(keys->pool, sizeof(psSessionTicketKeys_t));
2730 0 0         if (keylist == NULL)
2731             {
2732             psUnlockMutex(&g_sessTicketLock);
2733 0           return PS_MEM_FAIL;
2734             }
2735 0           prev->next = keylist;
2736             }
2737              
2738 1           memset(keylist, 0x0, sizeof(psSessionTicketKeys_t));
2739 1           keylist->hashkeyLen = hashkeyLen;
2740 1           keylist->symkeyLen = symkeyLen;
2741 1           memcpy(keylist->name, name, 16);
2742 1           memcpy(keylist->hashkey, hashkey, hashkeyLen);
2743 1           memcpy(keylist->symkey, symkey, symkeyLen);
2744             psUnlockMutex(&g_sessTicketLock);
2745 1           return PS_SUCCESS;
2746             }
2747              
2748             /******************************************************************************/
2749             /*
2750             Size of encrypted session ticket using 16-byte block cipher and SHA-256
2751             */
2752 0           int32 matrixSessionTicketLen(void)
2753             {
2754 0           int32 len = 0;
2755              
2756             /* Master secret, 2 version, 2 cipher suite, 4 timestamp,
2757             1 extended master secret flag are encypted */
2758 0           len += SSL_HS_MASTER_SIZE + 2 + 2 + 4 + 1;
2759 0           len += psPadLenPwr2(len, 16);
2760             /* Name, IV and MAC plaintext */
2761 0           len += 16 + 16 + SHA256_HASH_SIZE;
2762 0           return len;
2763             }
2764              
2765             /******************************************************************************/
2766             /* Plaintext Format:
2767             4 bytes lifetime hint
2768             2 bytes length of following:
2769             16 bytes name
2770             16 bytes IV
2771            
2772             2 bytes protocol version
2773             2 bytes cipher suite
2774             1 byte extended master secret flag
2775             48 bytes master secret
2776             4 bytes timestamp
2777            
2778             32 byte HMAC starting at 'name'
2779             */
2780 0           int32 matrixCreateSessionTicket(ssl_t *ssl, unsigned char *out, int32 *outLen)
2781             {
2782             int32 len, ticketLen, pad, rc;
2783             uint32 timeSecs;
2784             psTime_t t;
2785             psAesCbc_t ctx;
2786              
2787             # ifdef USE_HMAC_SHA256
2788             psHmacSha256_t dgst;
2789             # else
2790             psHmacSha1_t dgst;
2791             # endif
2792             psSessionTicketKeys_t *keys;
2793 0           unsigned char *enc, *c = out;
2794             unsigned char randno[AES_IVLEN];
2795              
2796 0           ticketLen = matrixSessionTicketLen();
2797 0 0         if ((ticketLen + 6) > *outLen)
2798             {
2799 0           return PS_LIMIT_FAIL;
2800             }
2801              
2802             /* Lifetime hint taken from define in matrixsslConfig.h */
2803 0           timeSecs = SSL_SESSION_ENTRY_LIFE / 1000; /* it's in milliseconds */
2804 0           *c = (unsigned char) ((timeSecs & 0xFF000000) >> 24); c++;
2805 0           *c = (unsigned char) ((timeSecs & 0xFF0000) >> 16); c++;
2806 0           *c = (unsigned char) ((timeSecs & 0xFF00) >> 8); c++;
2807 0           *c = (unsigned char) (timeSecs & 0xFF); c++;
2808              
2809             /* Len of ticket */
2810 0           *c = (ticketLen & 0xFF00) >> 8; c++;
2811 0           *c = ticketLen & 0xFF; c++;
2812              
2813             /* Do the heavier CPU stuff outside lock */
2814 0           timeSecs = psGetTime(&t, ssl->userPtr);
2815              
2816 0           if (psGetPrngLocked(randno, AES_IVLEN, ssl->userPtr) < 0)
2817             {
2818             psTraceInfo("WARNING: psGetPrngLocked failed\n");
2819             }
2820              
2821             psLockMutex(&g_sessTicketLock);
2822             /* Ticket itself */
2823 0           keys = ssl->keys->sessTickets;
2824             /* name */
2825 0           memcpy(c, keys->name, 16);
2826 0           c += 16;
2827 0           memcpy(c, randno, AES_IVLEN);
2828 0           c += AES_IVLEN;
2829 0           enc = c; /* encrypt start */
2830 0           *c = ssl->majVer; c++;
2831 0           *c = ssl->minVer; c++;
2832 0           *c = (ssl->cipher->ident & 0xFF00) >> 8; c++;
2833 0           *c = ssl->cipher->ident & 0xFF; c++;
2834             /* Need to track if original handshake used extended master secret */
2835 0           *c = ssl->extFlags.extended_master_secret; c++;
2836              
2837 0           memcpy(c, ssl->sec.masterSecret, SSL_HS_MASTER_SIZE);
2838 0           c += SSL_HS_MASTER_SIZE;
2839              
2840 0           *c = (unsigned char) ((timeSecs & 0xFF000000) >> 24); c++;
2841 0           *c = (unsigned char) ((timeSecs & 0xFF0000) >> 16); c++;
2842 0           *c = (unsigned char) ((timeSecs & 0xFF00) >> 8); c++;
2843 0           *c = (unsigned char) (timeSecs & 0xFF); c++;
2844              
2845             /* 4 time stamp, 2 version, 2 cipher, 1 extended master secret */
2846 0           len = SSL_HS_MASTER_SIZE + 4 + 2 + 2 + 1;
2847              
2848 0           pad = psPadLenPwr2(len, AES_BLOCKLEN);
2849 0           c += sslWritePad(c, (unsigned char) pad); len += pad;
2850             /* out + 6 + 16 (name) is pointing at IV */
2851 0 0         if ((rc = psAesInitCBC(&ctx, out + 6 + 16, keys->symkey, keys->symkeyLen, PS_AES_ENCRYPT)) < 0)
2852             {
2853 0           goto ERR_LOCKED;
2854             }
2855 0           psAesEncryptCBC(&ctx, enc, enc, len);
2856 0           psAesClearCBC(&ctx);
2857              
2858             /* HMAC starting from the Name */
2859             # ifdef USE_HMAC_SHA256
2860 0 0         if ((rc = psHmacSha256Init(&dgst, keys->hashkey, keys->hashkeyLen)) < 0)
2861             {
2862 0           goto ERR_LOCKED;
2863             }
2864 0           psHmacSha256Update(&dgst, out + 6, len + 16 + 16);
2865 0           psHmacSha256Final(&dgst, c);
2866 0           *outLen = len + SHA256_HASHLEN + 16 + 16 + 6;
2867             # else
2868             if ((rc = psHmacSha1Init(&dgst, keys->hashkey, keys->hashkeyLen)) < 0)
2869             {
2870             goto ERR_LOCKED;
2871             }
2872             psHmacSha1Update(&dgst, out + 6, len + 16 + 16);
2873             psHmacSha1Final(&dgst, c);
2874             *outLen = len + SHA1_HASHLEN + 16 + 16 + 6;
2875             # endif
2876 0           rc = PS_SUCCESS;
2877             ERR_LOCKED:
2878 0           memzero_s(randno, sizeof(randno));
2879             psUnlockMutex(&g_sessTicketLock);
2880 0           return rc;
2881             }
2882              
2883             /******************************************************************************/
2884             /*
2885             @pre Must be called with g_sessTicketLock locked. Returns in all cases
2886             with g_sessTicketLock locked.
2887             */
2888 0           static int32 getTicketKeys(ssl_t *ssl, unsigned char *c,
2889             psSessionTicketKeys_t **keys)
2890             {
2891             psSessionTicketKeys_t *lkey;
2892             unsigned char name[16];
2893             int32_t rc;
2894 0           short cachedTicket = 0;
2895              
2896             /* First 16 bytes are the key name */
2897 0           memcpy(name, c, 16);
2898 0           *keys = NULL;
2899             /* check our cached list beginning with our own encryption key */
2900 0           lkey = ssl->keys->sessTickets;
2901 0 0         while (lkey)
2902             {
2903 0 0         if (memcmp(lkey->name, name, 16) == 0)
2904             {
2905 0           lkey->inUse = 1;
2906 0           *keys = lkey;
2907             /* Have the key. Invoke callback with SUCCESS */
2908 0 0         if (ssl->keys->ticket_cb)
2909             {
2910 0           cachedTicket++;
2911 0           break;
2912             }
2913             else
2914             {
2915 0           return PS_SUCCESS;
2916             }
2917             }
2918 0           lkey = lkey->next;
2919             }
2920             /* didn't find it. Ask user */
2921 0 0         if (ssl->keys->ticket_cb)
2922             {
2923             /* Unlock. Cback will likely call matrixSslLoadSessionTicketKeys */
2924             psUnlockMutex(&g_sessTicketLock);
2925 0           rc = ssl->keys->ticket_cb((struct sslKeys_t *) ssl->keys, name, cachedTicket);
2926             psLockMutex(&g_sessTicketLock);
2927 0 0         if (rc < 0)
2928             {
2929 0 0         if (lkey)
2930             {
2931             /* inUse could be set in the odd case where we
2932             found the cached key but the user didn't want to use it. */
2933 0           lkey->inUse = 0;
2934             }
2935 0           return PS_FAILURE; /* user couldn't find it either */
2936             }
2937             /* found it */
2938 0 0         if (cachedTicket == 0)
2939             {
2940             /* it's been found and added at end of list. confirm this */
2941 0           lkey = ssl->keys->sessTickets;
2942 0 0         if (lkey == NULL)
2943             {
2944 0           return PS_FAILURE; /* user claims they added, but empty */
2945             }
2946 0 0         while (lkey->next)
2947             {
2948 0           lkey = lkey->next;
2949             }
2950 0 0         if (memcmp(lkey->name, c, 16) != 0)
2951             {
2952 0           return PS_FAILURE; /* user claims to have added, but... */
2953             }
2954 0           lkey->inUse = 1;
2955 0           *keys = lkey;
2956             }
2957 0           return PS_SUCCESS;
2958             }
2959 0           return PS_FAILURE; /* not in list and no callback registered */
2960             }
2961              
2962             /******************************************************************************/
2963              
2964 0           int32 matrixUnlockSessionTicket(ssl_t *ssl, unsigned char *in, int32 inLen)
2965             {
2966             unsigned char *c, *enc;
2967             unsigned char name[16];
2968             psSessionTicketKeys_t *keys;
2969              
2970             # ifdef USE_HMAC_SHA256
2971             psHmacSha256_t dgst;
2972             # define L_HASHLEN SHA256_HASHLEN
2973             # else
2974             psHmacSha1_t dgst;
2975             # define L_HASHLEN SHA1_HASHLEN
2976             # endif
2977             unsigned char hash[L_HASHLEN];
2978             psAesCbc_t ctx;
2979             int32 len;
2980             psTime_t t;
2981             uint32 majVer, minVer, cipherSuite, time, now;
2982              
2983             /* Validate that the incoming ticket is the length we expect */
2984 0 0         if (inLen != matrixSessionTicketLen())
2985             {
2986 0           return PS_FAILURE;
2987             }
2988 0           c = in;
2989 0           len = inLen;
2990             psLockMutex(&g_sessTicketLock);
2991 0 0         if (getTicketKeys(ssl, c, &keys) < 0)
2992             {
2993             psUnlockMutex(&g_sessTicketLock);
2994             psTraceInfo("No key found for session ticket\n");
2995 0           return PS_FAILURE;
2996             }
2997              
2998             /* Mac is over the name, IV and encrypted data */
2999             # ifdef USE_HMAC_SHA256
3000 0           psHmacSha256Init(&dgst, keys->hashkey, keys->hashkeyLen);
3001 0           psHmacSha256Update(&dgst, c, len - L_HASHLEN);
3002 0           psHmacSha256Final(&dgst, hash);
3003             # else
3004             psHmacSha1Init(&dgst, keys->hashkey, keys->hashkeyLen);
3005             psHmacSha1Update(&dgst, c, len - L_HASHLEN);
3006             psHmacSha1Final(&dgst, hash);
3007             # endif
3008              
3009 0           memcpy(name, c, 16);
3010 0           c += 16;
3011              
3012             /* out is pointing at IV */
3013 0           psAesInitCBC(&ctx, c, keys->symkey, keys->symkeyLen, PS_AES_DECRYPT);
3014 0           psAesDecryptCBC(&ctx, c + 16, c + 16, len - 16 - 16 - L_HASHLEN);
3015 0           psAesClearCBC(&ctx);
3016 0           keys->inUse = 0;
3017             psUnlockMutex(&g_sessTicketLock);
3018              
3019             /* decrypted marker */
3020 0           enc = c + 16;
3021              
3022 0           c += (len - 16 - L_HASHLEN); /* already moved past name */
3023              
3024 0 0         if (memcmp(hash, c, L_HASHLEN) != 0)
3025             {
3026             psTraceInfo("HMAC check failure on session ticket\n");
3027 0           return PS_FAILURE;
3028             }
3029             # undef L_HASHLEN
3030              
3031 0           majVer = *enc; enc++;
3032 0           minVer = *enc; enc++;
3033              
3034             /* Match protcol version */
3035 0 0         if (majVer != ssl->majVer || minVer != ssl->minVer)
    0          
3036             {
3037             psTraceInfo("Protocol check failure on session ticket\n");
3038 0           return PS_FAILURE;
3039             }
3040              
3041 0           cipherSuite = *enc << 8; enc++;
3042 0           cipherSuite += *enc; enc++;
3043              
3044             /* Force cipher suite */
3045 0 0         if ((ssl->cipher = sslGetCipherSpec(ssl, cipherSuite)) == NULL)
3046             {
3047             psTraceInfo("Cipher suite check failure on session ticket\n");
3048 0           return PS_FAILURE;
3049             }
3050              
3051             /* Did the initial connection use extended master secret? */
3052             /* First round of "require" testing can be done here. If server is
3053             set to require extended master secret and this ticket DOES NOT have it
3054             then we can stop resumption right now */
3055 0 0         if (*enc == 0x0 && ssl->extFlags.require_extended_master_secret == 1)
    0          
3056             {
3057             psTraceInfo("Ticket and master secret derivation methods differ\n");
3058 0           return PS_FAILURE;
3059             }
3060 0           ssl->extFlags.require_extended_master_secret = *enc; enc++;
3061              
3062             /* Set aside masterSecret */
3063 0           memcpy(ssl->sid->masterSecret, enc, SSL_HS_MASTER_SIZE);
3064 0           enc += SSL_HS_MASTER_SIZE;
3065              
3066             /* Check lifetime */
3067 0           time = *enc << 24; enc++;
3068 0           time += *enc << 16; enc++;
3069 0           time += *enc << 8; enc++;
3070 0           time += *enc; enc++;
3071              
3072 0           now = psGetTime(&t, ssl->userPtr);
3073              
3074 0 0         if ((now - time) > (SSL_SESSION_ENTRY_LIFE / 1000))
3075             {
3076             /* Expired session ticket. New one will be issued */
3077             psTraceInfo("Session ticket was expired\n");
3078 0           return PS_FAILURE;
3079             }
3080 0           ssl->sid->cipherId = cipherSuite;
3081              
3082 0           return PS_SUCCESS;
3083             }
3084             # endif /* USE_STATELESS_SESSION_TICKETS */
3085             # endif /* USE_SERVER_SIDE_SSL */
3086              
3087             #ifdef USE_CLIENT_SIDE_SSL
3088             /******************************************************************************/
3089             /*
3090             Get session information from the ssl structure and populate the given
3091             session structure. Session will contain a copy of the relevant session
3092             information, suitable for creating a new, resumed session.
3093              
3094             NOTE: Must define USE_CLIENT_SIDE_SSL in matrixConfig.h
3095              
3096             sslSessionId_t myClientSession;
3097              
3098             ...&myClientSession
3099             */
3100 2119           int32 matrixSslGetSessionId(ssl_t *ssl, sslSessionId_t *session)
3101             {
3102              
3103 2119 50         if (ssl == NULL || ssl->flags & SSL_FLAGS_SERVER || session == NULL)
    100          
    100          
3104             {
3105 1609           return PS_ARG_FAIL;
3106             }
3107              
3108 510 50         if (ssl->cipher != NULL && ssl->cipher->ident != SSL_NULL_WITH_NULL_NULL &&
    50          
    50          
3109 510           ssl->sessionIdLen == SSL_MAX_SESSION_ID_SIZE)
3110             {
3111              
3112             # ifdef USE_STATELESS_SESSION_TICKETS
3113             /* There is only one sessionId_t structure for any given session and
3114             it is possible a re-handshake on a session ticket connection will
3115             agree on using standard resumption and so the old master secret
3116             for the session ticket will be overwritten. Check for this case
3117             here and do not update our session if a ticket is in use */
3118 510 50         if (session->sessionTicket != NULL && session->sessionTicketLen > 0)
    0          
3119             {
3120 0           return PS_SUCCESS;
3121             }
3122             # endif
3123 510           session->cipherId = ssl->cipher->ident;
3124 510           memcpy(session->id, ssl->sessionId, ssl->sessionIdLen);
3125 510           memcpy(session->masterSecret, ssl->sec.masterSecret,
3126             SSL_HS_MASTER_SIZE);
3127 510           return PS_SUCCESS;
3128             }
3129             # ifdef USE_STATELESS_SESSION_TICKETS
3130 0 0         if (ssl->cipher != NULL && ssl->cipher->ident != SSL_NULL_WITH_NULL_NULL &&
    0          
    0          
3131 0 0         session->sessionTicket != NULL && session->sessionTicketLen > 0)
3132             {
3133 0           session->cipherId = ssl->cipher->ident;
3134 0           memcpy(session->masterSecret, ssl->sec.masterSecret,
3135             SSL_HS_MASTER_SIZE);
3136 0           return PS_SUCCESS;
3137             }
3138             # endif
3139              
3140 0           return PS_FAILURE;
3141             }
3142              
3143             # ifdef USE_ALPN
3144             /******************************************************************************/
3145              
3146 0           int32 matrixSslCreateALPNext(psPool_t *pool, int32 protoCount,
3147             unsigned char *proto[MAX_PROTO_EXT], int32 protoLen[MAX_PROTO_EXT],
3148             unsigned char **extOut, int32 *extLen)
3149             {
3150             int32 i, len;
3151             unsigned char *c;
3152              
3153 0 0         if (protoCount > MAX_PROTO_EXT)
3154             {
3155             psTraceIntInfo("Must increase MAX_PROTO_EXT to %d\n", protoCount);
3156 0           return PS_ARG_FAIL;
3157             }
3158 0           len = 2; /* overall len is 2 bytes */
3159 0 0         for (i = 0; i < protoCount; i++)
3160             {
3161 0 0         if (protoLen[i] <= 0 || protoLen[i] > 255)
    0          
3162             {
3163 0           return PS_ARG_FAIL;
3164             }
3165 0           len += protoLen[i] + 1; /* each string has 1 byte len */
3166             }
3167 0 0         if ((c = psMalloc(pool, len)) == NULL)
3168             {
3169 0           return PS_MEM_FAIL;
3170             }
3171 0           memset(c, 0, len);
3172 0           *extOut = c;
3173 0           *extLen = len;
3174              
3175 0           *c = ((len - 2) & 0xFF00) >> 8; c++; /* don't include ourself */
3176 0           *c = (len - 2) & 0xFF; c++;
3177 0 0         for (i = 0; i < protoCount; i++)
3178             {
3179 0           *c = protoLen[i]; c++;
3180 0           memcpy(c, proto[i], protoLen[i]);
3181 0           c += protoLen[i];
3182             }
3183 0           return PS_SUCCESS;
3184             }
3185             # endif
3186              
3187             /******************************************************************************/
3188              
3189 0           int32 matrixSslCreateSNIext(psPool_t *pool, unsigned char *host, int32 hostLen,
3190             unsigned char **extOut, int32 *extLen)
3191             {
3192             unsigned char *c;
3193              
3194 0           *extLen = hostLen + 5;
3195 0 0         if ((c = psMalloc(pool, *extLen)) == NULL)
3196             {
3197 0           return PS_MEM_FAIL;
3198             }
3199 0           memset(c, 0, *extLen);
3200 0           *extOut = c;
3201              
3202 0           *c = ((hostLen + 3) & 0xFF00) >> 8; c++;
3203 0           *c = (hostLen + 3) & 0xFF; c++;
3204 0           c++; /* host_name enum */
3205 0           *c = (hostLen & 0xFF00) >> 8; c++;
3206 0           *c = hostLen & 0xFF; c++;
3207 0           memcpy(c, host, hostLen);
3208 0           return PS_SUCCESS;
3209             }
3210             #endif /* USE_CLIENT_SIDE_SSL */
3211              
3212             #ifdef USE_SERVER_SIDE_SSL
3213             /******************************************************************************/
3214             /*
3215             If client sent a ServerNameIndication extension, see if we have those
3216             keys to load
3217             */
3218 0           int32 matrixServerSetKeysSNI(ssl_t *ssl, char *host, int32 hostLen)
3219             {
3220             sslKeys_t *keys;
3221              
3222 0 0         if (ssl->sni_cb)
3223             {
3224 0           ssl->extFlags.sni = 1; /* extension was actually handled */
3225 0           keys = NULL;
3226 0           (ssl->sni_cb)((void *) ssl, host, hostLen, &keys);
3227 0 0         if (keys)
3228             {
3229 0           ssl->keys = keys;
3230 0           return 0;
3231             }
3232 0           return PS_UNSUPPORTED_FAIL; /* callback didn't provide keys */
3233             }
3234              
3235 0           return 0; /* No callback registered. Go with default */
3236             }
3237             #endif /* USE_SERVER_SIDE_SSL */
3238              
3239             /******************************************************************************/
3240             /*
3241             Rehandshake. Free any allocated sec members that will be repopulated
3242             */
3243 14           void sslResetContext(ssl_t *ssl)
3244             {
3245             #ifdef USE_CLIENT_SIDE_SSL
3246 14 100         if (!(ssl->flags & SSL_FLAGS_SERVER))
3247             {
3248 7           ssl->anonBk = ssl->sec.anon;
3249 7           ssl->flagsBk = ssl->flags;
3250 7           ssl->bFlagsBk = ssl->bFlags;
3251             }
3252             #endif
3253 14           ssl->sec.anon = 0;
3254             #ifdef USE_SERVER_SIDE_SSL
3255 14 100         if (ssl->flags & SSL_FLAGS_SERVER)
3256             {
3257 7           matrixClearSession(ssl, 0);
3258             }
3259             #endif /* USE_SERVER_SIDE_SSL */
3260              
3261             #ifdef USE_DHE_CIPHER_SUITE
3262 14           ssl->flags &= ~SSL_FLAGS_DHE_KEY_EXCH;
3263 14           ssl->flags &= ~SSL_FLAGS_DHE_WITH_RSA;
3264             # ifdef USE_ANON_DH_CIPHER_SUITE
3265 14           ssl->flags &= ~SSL_FLAGS_ANON_CIPHER;
3266             # endif /* USE_ANON_DH_CIPHER_SUITE */
3267             # ifdef USE_ECC_CIPHER_SUITE
3268 14           ssl->flags &= ~SSL_FLAGS_ECC_CIPHER;
3269 14           ssl->flags &= ~SSL_FLAGS_DHE_WITH_RSA;
3270 14           ssl->flags &= ~SSL_FLAGS_DHE_WITH_DSA;
3271             # endif /* USE_ECC_CIPHER_SUITE */
3272             #endif /* USE_DHE_CIPHER_SUITE */
3273              
3274             #ifdef USE_PSK_CIPHER_SUITE
3275 14           ssl->flags &= ~SSL_FLAGS_PSK_CIPHER;
3276             #endif /* USE_PSK_CIPHER_SUITE */
3277              
3278             #ifdef USE_DTLS
3279             /*
3280             This flag is used in conjuction with flightDone in the buffer
3281             management API set to determine whether we are still in a handshake
3282             state for attempting flight resends. If we are resetting context we
3283             know a handshake phase is starting up again
3284             */
3285             if (ssl->flags & SSL_FLAGS_DTLS)
3286             {
3287             ssl->appDataExch = 0;
3288             }
3289             #endif
3290 14           ssl->bFlags = 0; /* Reset buffer control */
3291 14           }
3292              
3293             #ifdef USE_CERT_VALIDATE
3294 0           static int wildcardMatch(char *wild, char *s)
3295             {
3296             char *c, *e;
3297              
3298 0           c = wild;
3299 0 0         if (*c == '*')
3300             {
3301 0           c++;
3302             /* TODO - this is actually a parse error */
3303 0 0         if (*c != '.')
3304             {
3305 0           return -1;
3306             }
3307 0 0         if (strchr(s, '@'))
3308             {
3309 0           return -1;
3310             }
3311 0 0         if ((e = strchr(s, '.')) == NULL)
3312             {
3313 0           return -1;
3314             }
3315 0 0         if (strcasecmp(c, e) == 0)
3316             {
3317 0           return 0;
3318             }
3319             }
3320 0 0         else if (*c == '.')
3321             {
3322             /* TODO - this is actually a parse error */
3323 0           return -1;
3324             }
3325 0 0         else if (strcasecmp(c, s) == 0)
3326             {
3327 0           return 0;
3328             }
3329 0           return -1;
3330             }
3331              
3332 0           static int matchEmail(char *email, int32 emailLen,
3333             char *expectedEmail,
3334             int32 caseSensitiveLocalPart)
3335             {
3336             int32_t at_i;
3337              
3338 0 0         if (strlen(expectedEmail) != emailLen)
3339             {
3340 0           return 0;
3341             }
3342              
3343 0 0         if (caseSensitiveLocalPart)
3344             {
3345             /* Look for "@". The address has been checked
3346             during parsing, se we know it exists. */
3347 0 0         for (at_i = 0; at_i < emailLen; at_i++)
3348             {
3349 0 0         if (email[at_i] == '@')
3350             {
3351 0           break;
3352             }
3353             }
3354             /* Case-sensitive match for the local part,
3355             case-insensitive for the host part. */
3356 0 0         if (((strncmp(email,
3357 0 0         expectedEmail, at_i)) == 0) &&
3358 0           (strcasecmp(email + at_i,
3359             expectedEmail + at_i) == 0))
3360             {
3361 0           return 1;
3362             }
3363             }
3364             else
3365             {
3366             /* Case-insensitive match for everything. */
3367 0 0         if (strcasecmp(email, expectedEmail) == 0)
3368             {
3369 0           return 1;
3370             }
3371             }
3372              
3373 0           return 0;
3374             }
3375              
3376             /******************************************************************************/
3377             /*
3378             Wrapper for matrixValidateCertsExt taking in no extra options, using
3379             default options instead.
3380             */
3381 0           int32 matrixValidateCerts(psPool_t *pool, psX509Cert_t *subjectCerts,
3382             psX509Cert_t *issuerCerts, char *expectedName,
3383             psX509Cert_t **foundIssuer, void *hwCtx,
3384             void *poolUserPtr)
3385             {
3386             matrixValidateCertsOptions_t options;
3387              
3388 0           memset(&options, 0, sizeof(matrixValidateCertsOptions_t));
3389              
3390             /*
3391             By default, earlier versions of matrixValidateCerts checked
3392             expectedName against all supported fields in the SAN and the CN.
3393             For now, retain this behaviour for backwards compatibility.
3394             */
3395 0           options.nameType = NAME_TYPE_ANY;
3396              
3397             # ifdef ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION
3398             /*
3399             In earlier versions, this feature was always enabled.
3400             */
3401             options.mFlags |= VCERTS_MFLAG_ALWAYS_CHECK_SUBJECT_CN;
3402             # endif /* ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */
3403              
3404             /*
3405             In earlier versions, this feature was always enabled.
3406             */
3407             /* options.mFlags |= VCERTS_MFLAG_SAN_EMAIL_CASE_INSENSITIVE_LOCAL_PART; */
3408              
3409 0           return matrixValidateCertsExt(pool, subjectCerts, issuerCerts, expectedName,
3410             foundIssuer, hwCtx, poolUserPtr, &options);
3411             }
3412              
3413             /*
3414             Subject certs is the leaf first chain of certs from the peer
3415             Issuer certs is a flat list of trusted CAs loaded by LoadKeys
3416             */
3417 1148           int32 matrixValidateCertsExt(psPool_t *pool, psX509Cert_t *subjectCerts,
3418             psX509Cert_t *issuerCerts, char *expectedName,
3419             psX509Cert_t **foundIssuer, void *hwCtx,
3420             void *poolUserPtr,
3421             const matrixValidateCertsOptions_t *opts)
3422             {
3423              
3424             psX509Cert_t *ic, *sc;
3425             x509GeneralName_t *n;
3426             x509v3extensions_t *ext;
3427             char ip[16];
3428 1148           int32 rc, foundSupportedSAN, pathLen = 0;
3429              
3430             /*
3431             Check for illegal option combinations.
3432             */
3433 1148 50         if (opts->mFlags & VCERTS_MFLAG_ALWAYS_CHECK_SUBJECT_CN)
3434             {
3435 0 0         if (opts->nameType != NAME_TYPE_ANY &&
    0          
3436 0 0         opts->nameType != NAME_TYPE_HOSTNAME &&
3437 0           opts->nameType != NAME_TYPE_CN)
3438             {
3439 0           return PS_ARG_FAIL;
3440             }
3441             }
3442              
3443 1148 50         if (opts->flags & VCERTS_FLAG_VALIDATE_EXPECTED_GENERAL_NAME)
3444             {
3445             /*
3446             Validate expectedName.
3447             */
3448 0 0         if (expectedName)
3449             {
3450 0 0         if (psX509ValidateGeneralName(expectedName) < 0)
3451             {
3452             psTraceInfo("expectedName is not a valid GeneralName\n");
3453 0           return PS_ARG_FAIL;
3454             }
3455             }
3456             }
3457              
3458 1148           *foundIssuer = NULL;
3459             /*
3460             Case #1 is no issuing cert. Going to want to check that the final
3461             subject cert presented is a SelfSigned CA
3462             */
3463 1148 50         if (issuerCerts == NULL)
3464             {
3465 0           return psX509AuthenticateCert(pool, subjectCerts, NULL, foundIssuer,
3466             hwCtx, poolUserPtr);
3467             }
3468             /*
3469             Case #2 is an issuing cert AND possibly a chain of subjectCerts.
3470             */
3471 1148           sc = subjectCerts;
3472 1148 100         if ((ic = sc->next) != NULL)
3473             {
3474             /*
3475             We do have a chain. Authenticate the chain before even looking
3476             to our issuer CAs.
3477             */
3478 1 50         while (ic->next != NULL)
3479             {
3480 0 0         if ((rc = psX509AuthenticateCert(pool, sc, ic, foundIssuer, hwCtx,
3481             poolUserPtr)) < PS_SUCCESS)
3482             {
3483 0           return rc;
3484             }
3485 0 0         if (ic->extensions.bc.pathLenConstraint >= 0)
3486             {
3487             /* Make sure the pathLen is not exceeded */
3488 0 0         if (ic->extensions.bc.pathLenConstraint < pathLen)
3489             {
3490             psTraceInfo("Authentication failed due to X.509 pathLen\n");
3491 0           sc->authStatus = PS_CERT_AUTH_FAIL_PATH_LEN;
3492 0           return PS_CERT_AUTH_FAIL_PATH_LEN;
3493             }
3494             }
3495 0           pathLen++;
3496 0           sc = sc->next;
3497 0           ic = sc->next;
3498             }
3499             /*
3500             Test using the parent-most in chain as the subject
3501             */
3502 1 50         if ((rc = psX509AuthenticateCert(pool, sc, ic, foundIssuer, hwCtx,
3503             poolUserPtr)) < PS_SUCCESS)
3504             {
3505 0           return rc;
3506             }
3507 1 50         if (ic->extensions.bc.pathLenConstraint >= 0)
3508             {
3509             /* Make sure the pathLen is not exceeded */
3510 1 50         if (ic->extensions.bc.pathLenConstraint < pathLen)
3511             {
3512             psTraceInfo("Authentication failed due to X.509 pathLen\n");
3513 0           sc->authStatus = PS_CERT_AUTH_FAIL_PATH_LEN;
3514 0           return PS_CERT_AUTH_FAIL_PATH_LEN;
3515             }
3516             }
3517 1           pathLen++;
3518             /*
3519             Lastly, set subject to the final cert for the real issuer test below
3520             */
3521 1           sc = sc->next;
3522             }
3523             /*
3524             Now loop through the issuer certs and see if we can authenticate this chain
3525              
3526             If subject cert was a chain, that has already been authenticated above so
3527             we only need to pass in the single parent-most cert to be tested against
3528             */
3529 1148           *foundIssuer = NULL;
3530 1148           ic = issuerCerts;
3531 1294 100         while (ic != NULL)
3532             {
3533 1293           sc->authStatus = PS_FALSE;
3534 1293 100         if ((rc = psX509AuthenticateCert(pool, sc, ic, foundIssuer, hwCtx,
3535             poolUserPtr)) == PS_SUCCESS)
3536             {
3537 1147 50         if (ic->extensions.bc.pathLenConstraint >= 0)
3538             {
3539             /* Make sure the pathLen is not exceeded. If the sc and ic
3540             are the same CA at this point, this means the peer
3541             included the root CA in the chain it sent. It's not good
3542             practice to do this but implementations seem to allow it.
3543             Subtract one from pathLen in this case since one got
3544             added when it was truly just self-authenticating */
3545 0 0         if (ic->signatureLen == sc->signatureLen &&
    0          
3546 0           (memcmp(ic->signature, sc->signature,
3547 0           sc->signatureLen) == 0))
3548             {
3549 0 0         if (pathLen > 0)
3550             {
3551 0           pathLen--;
3552             }
3553             }
3554 0 0         if (ic->extensions.bc.pathLenConstraint < pathLen)
3555             {
3556             psTraceInfo("Authentication failed due to X.509 pathLen\n");
3557 0           rc = sc->authStatus = PS_CERT_AUTH_FAIL_PATH_LEN;
3558 0           return rc;
3559             }
3560             }
3561              
3562             /* Validate extensions of leaf certificate */
3563 1147           ext = &subjectCerts->extensions;
3564              
3565             /* Validate extended key usage */
3566 1147 50         if (ext->critFlags & EXT_CRIT_FLAG(OID_ENUM(id_ce_extKeyUsage)))
3567             {
3568 0 0         if (!(ext->ekuFlags & (EXT_KEY_USAGE_TLS_SERVER_AUTH |
3569             EXT_KEY_USAGE_TLS_CLIENT_AUTH)))
3570             {
3571 0           _psTrace("End-entity certificate not for TLS usage!\n");
3572 0           subjectCerts->authFailFlags |= PS_CERT_AUTH_FAIL_EKU_FLAG;
3573 0           rc = subjectCerts->authStatus = PS_CERT_AUTH_FAIL_EXTENSION;
3574             }
3575             }
3576              
3577             /* Check the subject/altSubject. Should match requested domain */
3578 1147 50         if (expectedName == NULL ||
    0          
3579 0           (opts->flags & VCERTS_FLAG_SKIP_EXPECTED_NAME_VALIDATION))
3580             {
3581 1147           return rc;
3582             }
3583 0           foundSupportedSAN = 0;
3584 0 0         for (n = ext->san; n != NULL; n = n->next)
3585             {
3586 0           switch (n->id)
3587             {
3588             case GN_DNS:
3589 0           foundSupportedSAN = 1;
3590 0 0         if (opts->nameType == NAME_TYPE_ANY ||
    0          
3591 0 0         opts->nameType == NAME_TYPE_HOSTNAME ||
3592 0           opts->nameType == NAME_TYPE_SAN_DNS)
3593             {
3594 0 0         if (wildcardMatch((char *) n->data, expectedName) == 0)
3595             {
3596 0           return rc;
3597             }
3598             }
3599 0           break;
3600             case GN_EMAIL:
3601 0           foundSupportedSAN = 1;
3602 0 0         if (opts->nameType == NAME_TYPE_ANY ||
    0          
3603 0           opts->nameType == NAME_TYPE_SAN_EMAIL)
3604             {
3605 0 0         if (opts->mFlags &
3606             VCERTS_MFLAG_SAN_EMAIL_CASE_INSENSITIVE_LOCAL_PART)
3607             {
3608 0 0         if (matchEmail((char *) n->data, n->dataLen,
3609             expectedName, 0))
3610             {
3611 0           return rc;
3612             }
3613             }
3614             else
3615             {
3616 0 0         if (matchEmail((char *) n->data, n->dataLen,
3617             expectedName, 1))
3618             {
3619 0           return rc;
3620             }
3621             }
3622             }
3623 0           break;
3624             case GN_IP:
3625 0           foundSupportedSAN = 1;
3626 0 0         if (opts->nameType == NAME_TYPE_ANY ||
    0          
3627 0           opts->nameType == NAME_TYPE_SAN_IP_ADDRESS)
3628             {
3629 0           snprintf(ip, 15, "%u.%u.%u.%u",
3630 0           (unsigned char) (n->data[0]),
3631 0           (unsigned char ) (n->data[1]),
3632 0           (unsigned char ) (n->data[2]),
3633 0           (unsigned char ) (n->data[3]));
3634 0           ip[15] = '\0';
3635 0 0         if (strcmp(ip, expectedName) == 0)
3636             {
3637 0           return rc;
3638             }
3639             }
3640 0           break;
3641             case GN_OTHER:
3642             case GN_X400:
3643             case GN_DIR:
3644             case GN_EDI:
3645             case GN_URI:
3646             case GN_REGID:
3647             /* No support for these currently. */
3648 0           break;
3649             }
3650             }
3651              
3652             /*
3653             Now check the subject CN, if necessary.
3654              
3655             RFC 6125, Section 6.4.4:
3656             "a client MUST NOT seek a match for a reference identifier
3657             of CN-ID if the presented identifiers include a DNS-ID, SRV-ID,
3658             URI-ID, or any application-specific identifier types supported
3659             by the client."
3660             */
3661              
3662             # ifdef ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION
3663             if (wildcardMatch(subjectCerts->subject.commonName,
3664             expectedName) == 0)
3665             {
3666             return rc;
3667             }
3668             # else
3669 0 0         if (opts->nameType == NAME_TYPE_ANY ||
    0          
3670 0 0         opts->nameType == NAME_TYPE_CN ||
3671 0           opts->nameType == NAME_TYPE_HOSTNAME)
3672             {
3673 0 0         if (!foundSupportedSAN ||
    0          
3674 0           (opts->mFlags & VCERTS_MFLAG_ALWAYS_CHECK_SUBJECT_CN))
3675             {
3676 0 0         if (wildcardMatch(subjectCerts->subject.commonName,
3677             expectedName) == 0)
3678             {
3679 0           return rc;
3680             }
3681             }
3682             }
3683             # endif /* ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */
3684              
3685             psTraceInfo("Authentication failed: no matching subject\n");
3686 0           subjectCerts->authFailFlags |= PS_CERT_AUTH_FAIL_SUBJECT_FLAG;
3687 0           rc = subjectCerts->authStatus = PS_CERT_AUTH_FAIL_EXTENSION;
3688 0           return rc;
3689             }
3690 146 50         else if (rc == PS_MEM_FAIL)
3691             {
3692             /*
3693             OK to fail on the authentication because there may be a list here
3694             but MEM failures prevent us from continuing at all.
3695             */
3696 0           return rc;
3697             }
3698 146           ic = ic->next;
3699             }
3700             /*
3701             Success would have returned if it happen
3702             */
3703 1148           return PS_CERT_AUTH_FAIL;
3704             }
3705              
3706             /******************************************************************************/
3707             /*
3708             Calls a user defined callback to allow for manual validation of the
3709             certificate.
3710             */
3711 1148           int32 matrixUserCertValidator(ssl_t *ssl, int32 alert,
3712             psX509Cert_t *subjectCert, sslCertCb_t certValidator)
3713             {
3714             int32 status;
3715              
3716             /*
3717             If there is no callback, return PS_SUCCESS because there has already been
3718             a test for the case where the certificate did NOT PASS pubkey test
3719             and a callback does not exist to manually handle.
3720              
3721             It is highly recommended that the user manually verify, but the cert
3722             material has internally authenticated and the user has implied that
3723             is sufficient enough.
3724             */
3725 1148 100         if (certValidator == NULL)
3726             {
3727             psTraceInfo("Internal cert auth passed. No user callback registered\n");
3728 1029           return PS_SUCCESS;
3729             }
3730              
3731             /*
3732             Finally, let the user know what the alert status is and
3733             give them the cert material to access. Any non-zero value in alert
3734             indicates there is a pending fatal alert.
3735              
3736             The user can look at authStatus members if they want to examine the cert
3737             that did not pass.
3738             */
3739 119 100         if (alert == SSL_ALERT_NONE)
3740             {
3741 1           status = 0;
3742             }
3743             else
3744             {
3745 118           status = alert;
3746             }
3747              
3748             /*
3749             The user callback
3750             */
3751 119           return certValidator(ssl, subjectCert, status);
3752             }
3753             #endif /* USE_CERT_VALIDATE */
3754              
3755             /******************************************************************************/
3756             #ifdef USE_MATRIXSSL_STATS
3757             void matrixSslRegisterStatCallback(ssl_t *ssl, void (*stat_cb)(void *ssl,
3758             void *stats_ptr, int32 type, int32 value), void *stats_ptr)
3759             {
3760             ssl->statCb = stat_cb;
3761             ssl->statsPtr = stats_ptr;
3762             }
3763              
3764             void matrixsslUpdateStat(ssl_t *ssl, int32 type, int32 value)
3765             {
3766             if (ssl->statCb)
3767             {
3768             (ssl->statCb)(ssl, ssl->statsPtr, type, value);
3769             }
3770             }
3771              
3772             #endif /* USE_MATRIXSSL_STATS */
3773             /******************************************************************************/
3774