1 /*
2 * Copyright 2016 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 /* Licensed to the Apache Software Foundation (ASF) under one or more
17 * contributor license agreements. See the NOTICE file distributed with
18 * this work for additional information regarding copyright ownership.
19 * The ASF licenses this file to You under the Apache License, Version 2.0
20 * (the "License"); you may not use this file except in compliance with
21 * the License. You may obtain a copy of the License at
22 *
23 * http://www.apache.org/licenses/LICENSE-2.0
24 *
25 * Unless required by applicable law or agreed to in writing, software
26 * distributed under the License is distributed on an "AS IS" BASIS,
27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28 * See the License for the specific language governing permissions and
29 * limitations under the License.
30 */
31
32 #include "tcn.h"
33
34 #include "ssl_private.h"
35
36 /* _________________________________________________________________
37 **
38 ** Additional High-Level Functions for OpenSSL
39 ** _________________________________________________________________
40 */
41
42
43 /*
44 * Adapted from OpenSSL:
45 * http://osxr.org/openssl/source/ssl/ssl_locl.h#0291
46 */
47 /* Bits for algorithm_mkey (key exchange algorithm) */
48 #define SSL_kRSA 0x00000001L /* RSA key exchange */
49 #define SSL_kDHr 0x00000002L /* DH cert, RSA CA cert */ /* no such ciphersuites supported! */
50 #define SSL_kDHd 0x00000004L /* DH cert, DSA CA cert */ /* no such ciphersuite supported! */
51 #define SSL_kEDH 0x00000008L /* tmp DH key no DH cert */
52 #define SSL_kKRB5 0x00000010L /* Kerberos5 key exchange */
53 #define SSL_kECDHr 0x00000020L /* ECDH cert, RSA CA cert */
54 #define SSL_kECDHe 0x00000040L /* ECDH cert, ECDSA CA cert */
55 #define SSL_kEECDH 0x00000080L /* ephemeral ECDH */
56 #define SSL_kPSK 0x00000100L /* PSK */
57 #define SSL_kGOST 0x00000200L /* GOST key exchange */
58 #define SSL_kSRP 0x00000400L /* SRP */
59
60 /* Bits for algorithm_auth (server authentication) */
61 #define SSL_aRSA 0x00000001L /* RSA auth */
62 #define SSL_aDSS 0x00000002L /* DSS auth */
63 #define SSL_aNULL 0x00000004L /* no auth (i.e. use ADH or AECDH) */
64 #define SSL_aDH 0x00000008L /* Fixed DH auth (kDHd or kDHr) */ /* no such ciphersuites supported! */
65 #define SSL_aECDH 0x00000010L /* Fixed ECDH auth (kECDHe or kECDHr) */
66 #define SSL_aKRB5 0x00000020L /* KRB5 auth */
67 #define SSL_aECDSA 0x00000040L /* ECDSA auth*/
68 #define SSL_aPSK 0x00000080L /* PSK auth */
69 #define SSL_aGOST94 0x00000100L /* GOST R 34.10-94 signature auth */
70 #define SSL_aGOST01 0x00000200L /* GOST R 34.10-2001 signature auth */
71
72 const char* TCN_UNKNOWN_AUTH_METHOD = "UNKNOWN";
73
74 /* OpenSSL end */
75
76 /*
77 * Adapted from Android:
78 * https://android.googlesource.com/platform/external/openssl/+/master/patches/0003-jsse.patch
79 */
SSL_cipher_authentication_method(const SSL_CIPHER * cipher)80 const char* SSL_cipher_authentication_method(const SSL_CIPHER* cipher){
81 #ifndef OPENSSL_IS_BORINGSSL
82 switch (cipher->algorithm_mkey)
83 {
84 case SSL_kRSA:
85 return SSL_TXT_RSA;
86 case SSL_kDHr:
87 return SSL_TXT_DH "_" SSL_TXT_RSA;
88
89 case SSL_kDHd:
90 return SSL_TXT_DH "_" SSL_TXT_DSS;
91 case SSL_kEDH:
92 switch (cipher->algorithm_auth)
93 {
94 case SSL_aDSS:
95 return "DHE_" SSL_TXT_DSS;
96 case SSL_aRSA:
97 return "DHE_" SSL_TXT_RSA;
98 case SSL_aNULL:
99 return SSL_TXT_DH "_anon";
100 default:
101 return TCN_UNKNOWN_AUTH_METHOD;
102 }
103 case SSL_kKRB5:
104 return SSL_TXT_KRB5;
105 case SSL_kECDHr:
106 return SSL_TXT_ECDH "_" SSL_TXT_RSA;
107 case SSL_kECDHe:
108 return SSL_TXT_ECDH "_" SSL_TXT_ECDSA;
109 case SSL_kEECDH:
110 switch (cipher->algorithm_auth)
111 {
112 case SSL_aECDSA:
113 return "ECDHE_" SSL_TXT_ECDSA;
114 case SSL_aRSA:
115 return "ECDHE_" SSL_TXT_RSA;
116 case SSL_aNULL:
117 return SSL_TXT_ECDH "_anon";
118 default:
119 return TCN_UNKNOWN_AUTH_METHOD;
120 }
121 default:
122 return TCN_UNKNOWN_AUTH_METHOD;
123 }
124 #else
125 return SSL_CIPHER_get_kx_name(cipher);
126 #endif
127
128 }
129
130 /* we initialize this index at startup time
131 * and never write to it at request time,
132 * so this static is thread safe.
133 * also note that OpenSSL increments at static variable when
134 * SSL_get_ex_new_index() is called, so we _must_ do this at startup.
135 */
136 static int SSL_app_data2_idx = -1;
137 static int SSL_app_data3_idx = -1;
138 static int SSL_app_data4_idx = -1;
SSL_init_app_data_idx()139 void SSL_init_app_data_idx()
140 {
141 int i;
142
143 if (SSL_app_data2_idx == -1) {
144 /* we _do_ need to call this two times */
145 for (i = 0; i <= 1; i++) {
146 SSL_app_data2_idx = SSL_get_ex_new_index(0, "tcn_ssl_ctxt_t*", NULL, NULL, NULL);
147 }
148 }
149
150 if (SSL_app_data3_idx == -1) {
151 SSL_app_data3_idx = SSL_get_ex_new_index(0, "int* handshakeCount", NULL, NULL, NULL);
152 }
153
154 if (SSL_app_data4_idx == -1) {
155 SSL_app_data4_idx = SSL_get_ex_new_index(0, "tcn_ssl_verify_config_t*", NULL, NULL, NULL);
156 }
157 }
158
SSL_get_app_data2(SSL * ssl)159 void *SSL_get_app_data2(SSL *ssl)
160 {
161 return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx);
162 }
163
SSL_set_app_data2(SSL * ssl,void * arg)164 void SSL_set_app_data2(SSL *ssl, void *arg)
165 {
166 SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg);
167 return;
168 }
169
SSL_get_app_data3(SSL * ssl)170 void *SSL_get_app_data3(SSL *ssl)
171 {
172 return SSL_get_ex_data(ssl, SSL_app_data3_idx);
173 }
174
SSL_set_app_data3(SSL * ssl,void * arg)175 void SSL_set_app_data3(SSL *ssl, void *arg)
176 {
177 SSL_set_ex_data(ssl, SSL_app_data3_idx, arg);
178 }
179
SSL_get_app_data4(SSL * ssl)180 void *SSL_get_app_data4(SSL *ssl)
181 {
182 return SSL_get_ex_data(ssl, SSL_app_data4_idx);
183 }
184
SSL_set_app_data4(SSL * ssl,void * arg)185 void SSL_set_app_data4(SSL *ssl, void *arg)
186 {
187 SSL_set_ex_data(ssl, SSL_app_data4_idx, arg);
188 }
189
SSL_password_callback(char * buf,int bufsiz,int verify,void * cb)190 int SSL_password_callback(char *buf, int bufsiz, int verify,
191 void *cb)
192 {
193 char *password = (char *) cb;
194
195 if (buf == NULL || password == NULL)
196 return 0;
197 *buf = '\0';
198
199 if (password[0]) {
200 /* Return already obtained password */
201 strncpy(buf, password, bufsiz);
202 }
203
204 buf[bufsiz - 1] = '\0';
205 return (int)strlen(buf);
206 }
207
208 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(OPENSSL_USE_DEPRECATED) || defined(LIBRESSL_VERSION_NUMBER)
209
210 static unsigned char dh0512_p[]={
211 0xD9,0xBA,0xBF,0xFD,0x69,0x38,0xC9,0x51,0x2D,0x19,0x37,0x39,
212 0xD7,0x7D,0x7E,0x3E,0x25,0x58,0x55,0x94,0x90,0x60,0x93,0x7A,
213 0xF2,0xD5,0x61,0x5F,0x06,0xE8,0x08,0xB4,0x57,0xF4,0xCF,0xB4,
214 0x41,0xCC,0xC4,0xAC,0xD4,0xF0,0x45,0x88,0xC9,0xD1,0x21,0x4C,
215 0xB6,0x72,0x48,0xBD,0x73,0x80,0xE0,0xDD,0x88,0x41,0xA0,0xF1,
216 0xEA,0x4B,0x71,0x13
217 };
218 static unsigned char dh1024_p[]={
219 0xA2,0x95,0x7E,0x7C,0xA9,0xD5,0x55,0x1D,0x7C,0x77,0x11,0xAC,
220 0xFD,0x48,0x8C,0x3B,0x94,0x1B,0xC5,0xC0,0x99,0x93,0xB5,0xDC,
221 0xDC,0x06,0x76,0x9E,0xED,0x1E,0x3D,0xBB,0x9A,0x29,0xD6,0x8B,
222 0x1F,0xF6,0xDA,0xC9,0xDF,0xD5,0x02,0x4F,0x09,0xDE,0xEC,0x2C,
223 0x59,0x1E,0x82,0x32,0x80,0x9B,0xED,0x51,0x68,0xD2,0xFB,0x1E,
224 0x25,0xDB,0xDF,0x9C,0x11,0x70,0xDF,0xCA,0x19,0x03,0x3D,0x3D,
225 0xC1,0xAC,0x28,0x88,0x4F,0x13,0xAF,0x16,0x60,0x6B,0x5B,0x2F,
226 0x56,0xC7,0x5B,0x5D,0xDE,0x8F,0x50,0x08,0xEC,0xB1,0xB9,0x29,
227 0xAA,0x54,0xF4,0x05,0xC9,0xDF,0x95,0x9D,0x79,0xC6,0xEA,0x3F,
228 0xC9,0x70,0x42,0xDA,0x90,0xC7,0xCC,0x12,0xB9,0x87,0x86,0x39,
229 0x1E,0x1A,0xCE,0xF7,0x3F,0x15,0xB5,0x2B
230 };
231 static unsigned char dh2048_p[]={
232 0xF2,0x4A,0xFC,0x7E,0x73,0x48,0x21,0x03,0xD1,0x1D,0xA8,0x16,
233 0x87,0xD0,0xD2,0xDC,0x42,0xA8,0xD2,0x73,0xE3,0xA9,0x21,0x31,
234 0x70,0x5D,0x69,0xC7,0x8F,0x95,0x0C,0x9F,0xB8,0x0E,0x37,0xAE,
235 0xD1,0x6F,0x36,0x1C,0x26,0x63,0x2A,0x36,0xBA,0x0D,0x2A,0xF5,
236 0x1A,0x0F,0xE8,0xC0,0xEA,0xD1,0xB5,0x52,0x47,0x1F,0x9A,0x0C,
237 0x0F,0xED,0x71,0x51,0xED,0xE6,0x62,0xD5,0xF8,0x81,0x93,0x55,
238 0xC1,0x0F,0xB4,0x72,0x64,0xB3,0x73,0xAA,0x90,0x9A,0x81,0xCE,
239 0x03,0xFD,0x6D,0xB1,0x27,0x7D,0xE9,0x90,0x5E,0xE2,0x10,0x74,
240 0x4F,0x94,0xC3,0x05,0x21,0x73,0xA9,0x12,0x06,0x9B,0x0E,0x20,
241 0xD1,0x5F,0xF7,0xC9,0x4C,0x9D,0x4F,0xFA,0xCA,0x4D,0xFD,0xFF,
242 0x6A,0x62,0x9F,0xF0,0x0F,0x3B,0xA9,0x1D,0xF2,0x69,0x29,0x00,
243 0xBD,0xE9,0xB0,0x9D,0x88,0xC7,0x4A,0xAE,0xB0,0x53,0xAC,0xA2,
244 0x27,0x40,0x88,0x58,0x8F,0x26,0xB2,0xC2,0x34,0x7D,0xA2,0xCF,
245 0x92,0x60,0x9B,0x35,0xF6,0xF3,0x3B,0xC3,0xAA,0xD8,0x58,0x9C,
246 0xCF,0x5D,0x9F,0xDB,0x14,0x93,0xFA,0xA3,0xFA,0x44,0xB1,0xB2,
247 0x4B,0x0F,0x08,0x70,0x44,0x71,0x3A,0x73,0x45,0x8E,0x6D,0x9C,
248 0x56,0xBC,0x9A,0xB5,0xB1,0x3D,0x8B,0x1F,0x1E,0x2B,0x0E,0x93,
249 0xC2,0x9B,0x84,0xE2,0xE8,0xFC,0x29,0x85,0x83,0x8D,0x2E,0x5C,
250 0xDD,0x9A,0xBB,0xFD,0xF0,0x87,0xBF,0xAF,0xC4,0xB6,0x1D,0xE7,
251 0xF9,0x46,0x50,0x7F,0xC3,0xAC,0xFD,0xC9,0x8C,0x9D,0x66,0x6B,
252 0x4C,0x6A,0xC9,0x3F,0x0C,0x0A,0x74,0x94,0x41,0x85,0x26,0x8F,
253 0x9F,0xF0,0x7C,0x0B
254 };
255 static unsigned char dh4096_p[] = {
256 0x8D,0xD3,0x8F,0x77,0x6F,0x6F,0xB0,0x74,0x3F,0x22,0xE9,0xD1,
257 0x17,0x15,0x69,0xD8,0x24,0x85,0xCD,0xC4,0xE4,0x0E,0xF6,0x52,
258 0x40,0xF7,0x1C,0x34,0xD0,0xA5,0x20,0x77,0xE2,0xFC,0x7D,0xA1,
259 0x82,0xF1,0xF3,0x78,0x95,0x05,0x5B,0xB8,0xDB,0xB3,0xE4,0x17,
260 0x93,0xD6,0x68,0xA7,0x0A,0x0C,0xC5,0xBB,0x9C,0x5E,0x1E,0x83,
261 0x72,0xB3,0x12,0x81,0xA2,0xF5,0xCD,0x44,0x67,0xAA,0xE8,0xAD,
262 0x1E,0x8F,0x26,0x25,0xF2,0x8A,0xA0,0xA5,0xF4,0xFB,0x95,0xAE,
263 0x06,0x50,0x4B,0xD0,0xE7,0x0C,0x55,0x88,0xAA,0xE6,0xB8,0xF6,
264 0xE9,0x2F,0x8D,0xA7,0xAD,0x84,0xBC,0x8D,0x4C,0xFE,0x76,0x60,
265 0xCD,0xC8,0xED,0x7C,0xBF,0xF3,0xC1,0xF8,0x6A,0xED,0xEC,0xE9,
266 0x13,0x7D,0x4E,0x72,0x20,0x77,0x06,0xA4,0x12,0xF8,0xD2,0x34,
267 0x6F,0xDC,0x97,0xAB,0xD3,0xA0,0x45,0x8E,0x7D,0x21,0xA9,0x35,
268 0x6E,0xE4,0xC9,0xC4,0x53,0xFF,0xE5,0xD9,0x72,0x61,0xC4,0x8A,
269 0x75,0x78,0x36,0x97,0x1A,0xAB,0x92,0x85,0x74,0x61,0x7B,0xE0,
270 0x92,0xB8,0xC6,0x12,0xA1,0x72,0xBB,0x5B,0x61,0xAA,0xE6,0x2C,
271 0x2D,0x9F,0x45,0x79,0x9E,0xF4,0x41,0x93,0x93,0xEF,0x8B,0xEF,
272 0xB7,0xBF,0x6D,0xF0,0x91,0x11,0x4F,0x7C,0x71,0x84,0xB5,0x88,
273 0xA3,0x8C,0x1A,0xD5,0xD0,0x81,0x9C,0x50,0xAC,0xA9,0x2B,0xE9,
274 0x92,0x2D,0x73,0x7C,0x0A,0xA3,0xFA,0xD3,0x6C,0x91,0x43,0xA6,
275 0x80,0x7F,0xD7,0xC4,0xD8,0x6F,0x85,0xF8,0x15,0xFD,0x08,0xA6,
276 0xF8,0x7B,0x3A,0xF4,0xD3,0x50,0xB4,0x2F,0x75,0xC8,0x48,0xB8,
277 0xA8,0xFD,0xCA,0x8F,0x62,0xF1,0x4C,0x89,0xB7,0x18,0x67,0xB2,
278 0x93,0x2C,0xC4,0xD4,0x71,0x29,0xA9,0x26,0x20,0xED,0x65,0x37,
279 0x06,0x87,0xFC,0xFB,0x65,0x02,0x1B,0x3C,0x52,0x03,0xA1,0xBB,
280 0xCF,0xE7,0x1B,0xA4,0x1A,0xE3,0x94,0x97,0x66,0x06,0xBF,0xA9,
281 0xCE,0x1B,0x07,0x10,0xBA,0xF8,0xD4,0xD4,0x05,0xCF,0x53,0x47,
282 0x16,0x2C,0xA1,0xFC,0x6B,0xEF,0xF8,0x6C,0x23,0x34,0xEF,0xB7,
283 0xD3,0x3F,0xC2,0x42,0x5C,0x53,0x9A,0x00,0x52,0xCF,0xAC,0x42,
284 0xD3,0x3B,0x2E,0xB6,0x04,0x32,0xE1,0x09,0xED,0x64,0xCD,0x6A,
285 0x63,0x58,0xB8,0x43,0x56,0x5A,0xBE,0xA4,0x9F,0x68,0xD4,0xF7,
286 0xC9,0x04,0xDF,0xCD,0xE5,0x93,0xB0,0x2F,0x06,0x19,0x3E,0xB8,
287 0xAB,0x7E,0xF8,0xE7,0xE7,0xC8,0x53,0xA2,0x06,0xC3,0xC7,0xF9,
288 0x18,0x3B,0x51,0xC3,0x9B,0xFF,0x8F,0x00,0x0E,0x87,0x19,0x68,
289 0x2F,0x40,0xC0,0x68,0xFA,0x12,0xAE,0x57,0xB5,0xF0,0x97,0xCA,
290 0x78,0x23,0x31,0xAB,0x67,0x7B,0x10,0x6B,0x59,0x32,0x9C,0x64,
291 0x20,0x38,0x1F,0xC5,0x07,0x84,0x9E,0xC4,0x49,0xB1,0xDF,0xED,
292 0x7A,0x8A,0xC3,0xE0,0xDD,0x30,0x55,0xFF,0x95,0x45,0xA6,0xEE,
293 0xCB,0xE4,0x26,0xB9,0x8E,0x89,0x37,0x63,0xD4,0x02,0x3D,0x5B,
294 0x4F,0xE5,0x90,0xF6,0x72,0xF8,0x10,0xEE,0x31,0x04,0x54,0x17,
295 0xE3,0xD5,0x63,0x84,0x80,0x62,0x54,0x46,0x85,0x6C,0xD2,0xC1,
296 0x3E,0x19,0xBD,0xE2,0x80,0x11,0x86,0xC7,0x4B,0x7F,0x67,0x86,
297 0x47,0xD2,0x38,0xCD,0x8F,0xFE,0x65,0x3C,0x11,0xCD,0x96,0x99,
298 0x4E,0x45,0xEB,0xEC,0x1D,0x94,0x8C,0x53,
299 };
300 static unsigned char dhxxx2_g[]={
301 0x02
302 };
303
get_dh(int idx)304 static DH *get_dh(int idx)
305 {
306 DH *dh;
307 if ((dh = DH_new()) == NULL)
308 return NULL;
309 switch (idx) {
310 case SSL_TMP_KEY_DH_512:
311 dh->p = BN_bin2bn(dh0512_p, sizeof(dh0512_p), NULL);
312 break;
313 case SSL_TMP_KEY_DH_1024:
314 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
315 break;
316 case SSL_TMP_KEY_DH_2048:
317 dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
318 break;
319 case SSL_TMP_KEY_DH_4096:
320 dh->p = BN_bin2bn(dh4096_p, sizeof(dh2048_p), NULL);
321 break;
322 }
323 dh->g = BN_bin2bn(dhxxx2_g, sizeof(dhxxx2_g), NULL);
324 if ((dh->p == NULL) || (dh->g == NULL)) {
325 DH_free(dh);
326 return NULL;
327 }
328 else
329 return dh;
330 return NULL;
331 }
332 #else
get_dh(int idx)333 static DH *get_dh(int idx)
334 {
335 return NULL;
336 }
337 #endif
338
SSL_dh_get_tmp_param(int key_len)339 DH *SSL_dh_get_tmp_param(int key_len)
340 {
341 DH *dh;
342
343 if (key_len == 512)
344 dh = get_dh(SSL_TMP_KEY_DH_512);
345 else if (key_len == 1024)
346 dh = get_dh(SSL_TMP_KEY_DH_1024);
347 else if (key_len == 2048)
348 dh = get_dh(SSL_TMP_KEY_DH_2048);
349 else if (key_len == 4096)
350 dh = get_dh(SSL_TMP_KEY_DH_4096);
351 else
352 dh = get_dh(SSL_TMP_KEY_DH_1024);
353 return dh;
354 }
355
356 /*
357 * Hand out the already generated DH parameters...
358 */
SSL_callback_tmp_DH(SSL * ssl,int export,int keylen)359 DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen)
360 {
361 int idx;
362 switch (keylen) {
363 case 512:
364 idx = SSL_TMP_KEY_DH_512;
365 break;
366 case 2048:
367 idx = SSL_TMP_KEY_DH_2048;
368 break;
369 case 4096:
370 idx = SSL_TMP_KEY_DH_4096;
371 break;
372 case 1024:
373 default:
374 idx = SSL_TMP_KEY_DH_1024;
375 break;
376 }
377 return (DH *)SSL_temp_keys[idx];
378 }
379
SSL_callback_tmp_DH_512(SSL * ssl,int export,int keylen)380 DH *SSL_callback_tmp_DH_512(SSL *ssl, int export, int keylen)
381 {
382 return (DH *)SSL_temp_keys[SSL_TMP_KEY_DH_512];
383 }
384
SSL_callback_tmp_DH_1024(SSL * ssl,int export,int keylen)385 DH *SSL_callback_tmp_DH_1024(SSL *ssl, int export, int keylen)
386 {
387 return (DH *)SSL_temp_keys[SSL_TMP_KEY_DH_1024];
388 }
389
SSL_callback_tmp_DH_2048(SSL * ssl,int export,int keylen)390 DH *SSL_callback_tmp_DH_2048(SSL *ssl, int export, int keylen)
391 {
392 return (DH *)SSL_temp_keys[SSL_TMP_KEY_DH_2048];
393 }
394
SSL_callback_tmp_DH_4096(SSL * ssl,int export,int keylen)395 DH *SSL_callback_tmp_DH_4096(SSL *ssl, int export, int keylen)
396 {
397 return (DH *)SSL_temp_keys[SSL_TMP_KEY_DH_4096];
398 }
399
400 /*
401 * Read a file that optionally contains the server certificate in PEM
402 * format, possibly followed by a sequence of CA certificates that
403 * should be sent to the peer in the SSL Certificate message.
404 */
SSL_CTX_use_certificate_chain(SSL_CTX * ctx,const char * file,bool skipfirst)405 int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, const char *file, bool skipfirst)
406 {
407 BIO *bio;
408 int n;
409
410 if ((bio = BIO_new(BIO_s_file())) == NULL)
411 return -1;
412 if (BIO_read_filename(bio, file) <= 0) {
413 BIO_free(bio);
414 return -1;
415 }
416 n = SSL_CTX_use_certificate_chain_bio(ctx, bio, skipfirst);
417 BIO_free(bio);
418 return n;
419 }
420
SSL_CTX_setup_certs(SSL_CTX * ctx,BIO * bio,bool skipfirst,bool ca)421 static int SSL_CTX_setup_certs(SSL_CTX *ctx, BIO *bio, bool skipfirst, bool ca)
422 {
423 X509 *x509;
424 unsigned long err;
425 int n;
426
427 /* optionally skip a leading server certificate */
428 if (skipfirst) {
429 if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {
430 return -1;
431 }
432 X509_free(x509);
433 }
434
435 n = 0;
436 if (ca) {
437 while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
438 if (SSL_CTX_add_client_CA(ctx, x509) != 1) {
439 X509_free(x509);
440 return -1;
441 }
442 // SSL_CTX_add_client_CA does not take ownership of the x509. It just calls X509_get_subject_name
443 // and make a duplicate of this value. So we should always free the x509 after this call.
444 // See https://github.com/netty/netty/issues/6249.
445 X509_free(x509);
446 n++;
447 }
448 } else {
449 /* free a perhaps already configured extra chain */
450 SSL_CTX_clear_extra_chain_certs(ctx);
451
452 /* create new extra chain by loading the certs */
453 while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
454 // SSL_CTX_add_extra_chain_cert transfers ownership of the x509 certificate if the method succeeds.
455 if (SSL_CTX_add_extra_chain_cert(ctx, x509) != 1) {
456 X509_free(x509);
457 return -1;
458 }
459 n++;
460 }
461 }
462
463 /* Make sure that only the error is just an EOF */
464 if ((err = ERR_peek_error()) > 0) {
465 if (!( ERR_GET_LIB(err) == ERR_LIB_PEM
466 && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
467 return -1;
468 }
469 ERR_clear_error();
470 }
471 return n;
472 }
473
SSL_CTX_use_certificate_chain_bio(SSL_CTX * ctx,BIO * bio,bool skipfirst)474 int SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO *bio, bool skipfirst)
475 {
476 return SSL_CTX_setup_certs(ctx, bio, skipfirst, false);
477 }
478
479
SSL_CTX_use_client_CA_bio(SSL_CTX * ctx,BIO * bio)480 int SSL_CTX_use_client_CA_bio(SSL_CTX *ctx, BIO *bio)
481 {
482 return SSL_CTX_setup_certs(ctx, bio, false, true);
483 }
484
SSL_use_certificate_chain_bio(SSL * ssl,BIO * bio,bool skipfirst)485 int SSL_use_certificate_chain_bio(SSL *ssl, BIO *bio, bool skipfirst)
486 {
487 #if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER)
488 // Only supported on openssl 1.0.2+
489 return -1;
490 #else
491 X509 *x509;
492 unsigned long err;
493 int n;
494
495 /* optionally skip a leading server certificate */
496 if (skipfirst) {
497 if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {
498 return -1;
499 }
500 X509_free(x509);
501 }
502
503 /* create new extra chain by loading the certs */
504 n = 0;
505
506 while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
507 if (SSL_add0_chain_cert(ssl, x509) != 1) {
508 X509_free(x509);
509 return -1;
510 }
511 n++;
512 }
513 /* Make sure that only the error is just an EOF */
514 if ((err = ERR_peek_error()) > 0) {
515 if (!( ERR_GET_LIB(err) == ERR_LIB_PEM
516 && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
517 return -1;
518 }
519 ERR_clear_error();
520 }
521 return n;
522 #endif
523 }
524
load_pem_cert_bio(const char * password,const BIO * bio)525 X509 *load_pem_cert_bio(const char *password, const BIO *bio)
526 {
527 X509 *cert = PEM_read_bio_X509_AUX((BIO*) bio, NULL,
528 (pem_password_cb *)SSL_password_callback,
529 (void *)password);
530 if (cert == NULL &&
531 (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE)) {
532 ERR_clear_error();
533 BIO_ctrl((BIO*) bio, BIO_CTRL_RESET, 0, NULL);
534 cert = d2i_X509_bio((BIO*) bio, NULL);
535 }
536 return cert;
537 }
538
load_pem_key_bio(const char * password,const BIO * bio)539 EVP_PKEY *load_pem_key_bio(const char *password, const BIO *bio)
540 {
541 EVP_PKEY *key = PEM_read_bio_PrivateKey((BIO*) bio, NULL,
542 (pem_password_cb *)SSL_password_callback,
543 (void *)password);
544
545 BIO_ctrl((BIO*) bio, BIO_CTRL_RESET, 0, NULL);
546 return key;
547 }
548
tcn_EVP_PKEY_up_ref(EVP_PKEY * pkey)549 int tcn_EVP_PKEY_up_ref(EVP_PKEY* pkey) {
550 #if defined(OPENSSL_IS_BORINGSSL)
551 // Workaround for https://bugs.chromium.org/p/boringssl/issues/detail?id=89#
552 EVP_PKEY_up_ref(pkey);
553 return 1;
554 #elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
555 return CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
556 #else
557 return EVP_PKEY_up_ref(pkey);
558 #endif
559 }
560
tcn_X509_up_ref(X509 * cert)561 int tcn_X509_up_ref(X509* cert) {
562 #if defined(OPENSSL_IS_BORINGSSL)
563 // Workaround for https://bugs.chromium.org/p/boringssl/issues/detail?id=89#
564 X509_up_ref(cert);
565 return 1;
566 #elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
567 return CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
568 #else
569 return X509_up_ref(cert);
570 #endif
571 }
572
tcn_set_verify_config(tcn_ssl_verify_config_t * c,jint tcn_mode,jint depth)573 int tcn_set_verify_config(tcn_ssl_verify_config_t* c, jint tcn_mode, jint depth) {
574 if (depth >= 0) {
575 c->verify_depth = depth;
576 }
577
578 switch (tcn_mode) {
579 case SSL_CVERIFY_IGNORED:
580 switch (c->verify_mode) {
581 case SSL_CVERIFY_NONE:
582 return SSL_VERIFY_NONE;
583 case SSL_CVERIFY_OPTIONAL:
584 return SSL_VERIFY_PEER;
585 default:
586 return (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
587 }
588 case SSL_CVERIFY_NONE:
589 c->verify_mode = SSL_CVERIFY_NONE;
590 return SSL_VERIFY_NONE;
591 case SSL_CVERIFY_OPTIONAL:
592 c->verify_mode = SSL_CVERIFY_OPTIONAL;
593 return SSL_VERIFY_PEER;
594 default:
595 c->verify_mode = SSL_CVERIFY_REQUIRED;
596 return SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
597 }
598 }
599
SSL_callback_next_protos(SSL * ssl,const unsigned char ** data,unsigned int * len,void * arg)600 int SSL_callback_next_protos(SSL *ssl, const unsigned char **data,
601 unsigned int *len, void *arg)
602 {
603 tcn_ssl_ctxt_t *ssl_ctxt = arg;
604
605 *data = ssl_ctxt->next_proto_data;
606 *len = ssl_ctxt->next_proto_len;
607
608 return SSL_TLSEXT_ERR_OK;
609 }
610
611 /* The code here is inspired by nghttp2
612 *
613 * See https://github.com/tatsuhiro-t/nghttp2/blob/ae0100a9abfcf3149b8d9e62aae216e946b517fb/src/shrpx_ssl.cc#L244 */
select_next_proto(SSL * ssl,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,unsigned char * supported_protos,unsigned int supported_protos_len,int failure_behavior)614 int select_next_proto(SSL *ssl, const unsigned char **out, unsigned char *outlen,
615 const unsigned char *in, unsigned int inlen, unsigned char *supported_protos,
616 unsigned int supported_protos_len, int failure_behavior) {
617
618 unsigned int i = 0;
619 unsigned char target_proto_len;
620 unsigned char *p;
621 const unsigned char *end;
622 unsigned char *proto;
623 unsigned char proto_len;
624
625 while (i < supported_protos_len) {
626 target_proto_len = *supported_protos;
627 ++supported_protos;
628
629 p = (unsigned char*) in;
630 end = p + inlen;
631
632 while (p < end) {
633 proto_len = *p;
634 proto = ++p;
635
636 if (proto + proto_len <= end && target_proto_len == proto_len &&
637 memcmp(supported_protos, proto, proto_len) == 0) {
638
639 // We found a match, so set the output and return with OK!
640 *out = proto;
641 *outlen = proto_len;
642
643 return SSL_TLSEXT_ERR_OK;
644 }
645 // Move on to the next protocol.
646 p += proto_len;
647 }
648
649 // increment len and pointers.
650 i += target_proto_len;
651 supported_protos += target_proto_len;
652 }
653
654 if (failure_behavior == SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL) {
655 // There were no match but we just select our last protocol and hope the other peer support it.
656 //
657 // decrement the pointer again so the pointer points to the start of the protocol.
658 p -= proto_len;
659 *out = p;
660 *outlen = proto_len;
661 return SSL_TLSEXT_ERR_OK;
662 }
663 // TODO: OpenSSL currently not support to fail with fatal error. Once this changes we can also support it here.
664 // Issue https://github.com/openssl/openssl/issues/188 has been created for this.
665 // Nothing matched so not select anything and just accept.
666 return SSL_TLSEXT_ERR_NOACK;
667 }
668
SSL_callback_select_next_proto(SSL * ssl,unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)669 int SSL_callback_select_next_proto(SSL *ssl, unsigned char **out, unsigned char *outlen,
670 const unsigned char *in, unsigned int inlen,
671 void *arg) {
672 tcn_ssl_ctxt_t *ssl_ctxt = arg;
673 return select_next_proto(ssl, (const unsigned char**) out, outlen, in, inlen, ssl_ctxt->next_proto_data, ssl_ctxt->next_proto_len, ssl_ctxt->next_selector_failure_behavior);
674 }
675
SSL_callback_alpn_select_proto(SSL * ssl,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)676 int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char **out, unsigned char *outlen,
677 const unsigned char *in, unsigned int inlen, void *arg) {
678 tcn_ssl_ctxt_t *ssl_ctxt = arg;
679 return select_next_proto(ssl, out, outlen, in, inlen, ssl_ctxt->alpn_proto_data, ssl_ctxt->alpn_proto_len, ssl_ctxt->alpn_selector_failure_behavior);
680 }
681