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