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