1 /*
2 * Copyright (c) 2002-2006 Tomas Svensson <ts@codepix.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #ifdef WIN32
33 #include <Winsock2.h>
34 #define snprintf _snprintf
35 #define strcasecmp _stricmp
36 #else
37 #include <unistd.h>
38 #include <syslog.h>
39 #include <arpa/ftp.h>
40 #include <sys/time.h>
41 #include <netinet/in.h>
42 #include <pwd.h>
43 #endif
44 #include <ctype.h>
45 #include <openssl/ssl.h>
46 #include <openssl/rand.h>
47 #include <openssl/err.h>
48 #include <openssl/x509v3.h>
49 #include <fcntl.h>
50
51 #include "tlswrap.h"
52 #include "tls.h"
53 #include "misc.h"
54
55 extern int debug;
56 /* extern int sec_mode;
57
58 int global_user_cert;
59 X509_STORE *ca_store; */
60
tls_init(char * egd_sock)61 void tls_init(char *egd_sock) {
62
63 if (!SSL_library_init())
64 sys_err("OpenSSL initialization failed");
65
66 SSL_load_error_strings(); /* load readable error messages */
67 /*
68 if (!(tls_ctx = SSL_CTX_new(SSLv23_method()))) {
69 printf("SSL_CTX_new() %s\r\n",(char *)ERR_error_string(ERR_get_error(), NULL));
70 exit(1);
71 }*/
72 if (debug)
73 printf("egd_sock is %s\n", egd_sock);
74 #ifdef HAVE_RAND_STATUS
75 if (RAND_status() != 1) {
76 #ifdef HAVE_RAND_EGD
77 if ( RAND_egd(egd_sock) == -1 ) {
78 fprintf(stderr, "egd_sock is %s\n", egd_sock);
79 sys_err("RAND_egd failed\n");
80 }
81 #endif
82 if (RAND_status() != 1)
83 sys_err("ssl_init: System without /dev/urandom, PRNG seeding must be done manually.\r\n");
84 }
85 #endif
86 /*
87 SSL_CTX_set_options(tls_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
88 SSL_CTX_set_default_verify_paths(tls_ctx);
89 */
90 // global_user_cert = 0;
91
92 /*
93 if (sec_mode > 0) {
94 if (SSL_CTX_use_certificate_chain_file(tls_ctx, "usercert.pem") == 1) {
95 if (SSL_CTX_use_PrivateKey_file(tls_ctx, "usercert.pem", SSL_FILETYPE_PEM) != 1)
96 sys_err("Unable to load private key from file.");
97 else
98 global_user_cert = 1;
99 if (debug)
100 printf("Global user certificate chain loaded.\n");
101 } else {
102 if (debug)
103 printf("No global user certificate loaded.\n");
104 }
105 */
106
107 /*
108 if (cafile[0] != '\0') { // CA verifications.
109 if (SSL_CTX_load_verify_locations(tls_ctx, cafile, NULL) != 1)
110 sys_err("could not load certificates from CA file.");
111 else if (debug)
112 printf("Loaded CA file.\n");
113 ca_store = SSL_CTX_get_cert_store(tls_ctx);
114 } else
115 ca_store = NULL;
116
117 SSL_CTX_set_cert_store(tls_ctx, NULL);
118 SSL_CTX_free(tls_ctx);
119 */
120 if (debug)
121 printf("TLS initialization successful.\n");
122
123 }
124
125 void
tls_auth(struct user_data * ud,int data,char * ucertspath,char * cafile)126 tls_auth(struct user_data *ud, int data, char *ucertspath, char *cafile)
127 {
128 SSL *ssl;
129 char fn[NI_MAXHOST];
130
131 #ifdef WIN32
132 char sep = '\\';
133 #else
134 char sep = '/';
135 #endif
136
137 if (!data) {
138 if ((ud->ssl_ctx = SSL_CTX_new(SSLv23_method())) == NULL) {
139 printf("SSL_CTX_new() %s\n",(char *)ERR_error_string(ERR_get_error(), NULL));
140 exit(1);
141 }
142 if (cafile[0] != '\0') { // CA verifications.
143 if (SSL_CTX_load_verify_locations(ud->ssl_ctx, cafile, NULL) != 1)
144 sys_err("could not load certificates from CA file.");
145 else if (debug)
146 printf("Loaded CA file.\n");
147 }
148 SSL_CTX_set_options(ud->ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
149 SSL_CTX_set_default_verify_paths(ud->ssl_ctx);
150
151 if (ucertspath[0] != '\0') { /* Try to load user certificate chain */
152 if (ucertspath[strlen(ucertspath)] == sep)
153 snprintf(fn, sizeof(fn), "%s%s.pem",ucertspath, ud->serv_dns.hostname);
154 else
155 snprintf(fn, sizeof(fn), "%s%c%s.pem",ucertspath, sep, ud->serv_dns.hostname);
156 if (SSL_CTX_use_certificate_chain_file(ud->ssl_ctx, fn) != 1) {
157 if (debug)
158 printf("failed to load %s\n", fn);
159 } else {
160 if (debug)
161 printf("loaded %s\n", fn);
162 }
163 }
164 }
165
166 ssl = SSL_new(ud->ssl_ctx);
167
168 if (ssl == NULL) {
169 printf("SSL_new() %s\r\n",(char *)ERR_error_string(ERR_get_error(), NULL));
170 exit(1);
171 }
172
173 if (data)
174 ud->ssl_data = ssl;
175 else
176 ud->ssl_ctrl = ssl;
177 if (debug)
178 printf("tls_auth: ciphers: %s\n", cfg_tlsciphers);
179
180 SSL_set_cipher_list(ssl, cfg_tlsciphers);
181
182 /* if (sec_mode >= 3)
183 SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); */
184
185 if (data) {
186 if (SSL_set_fd(ssl, ud->serv_data_fd) != 1)
187 printf("SSL_set_fd_error\n");
188 if (ud->ssl_sess) { /* There is a cached SSL session */
189 SSL_set_session(ssl, ud->ssl_sess);
190 SSL_SESSION_free(ud->ssl_sess);
191 ud->ssl_sess = NULL;
192 }
193 } else {
194 if (SSL_set_fd(ssl, ud->serv_fd) != 1)
195 printf("SSL_set_fd_error\n");
196 }
197
198 SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
199 tls_auth_cont(ud, data);
200 }
201
tls_cert(struct user_data * ud,int data)202 int tls_cert(struct user_data *ud, int data) /* save new key or verify saved key */
203 {
204 X509 *x509_peer, *x509_stored;
205 FILE *fp;
206 char filename[1024];
207 int cert_ok;
208
209 cert_ok = 0;
210 x509_stored = NULL;
211
212 if (debug)
213 printf("tls_cert\n");
214
215 if ((x509_peer = SSL_get_peer_certificate((data) ? ud->ssl_data : ud->ssl_ctrl)) == NULL)
216 return 0; /* SSL_get_peer* can only be NULL on 'anonymous DH connections' so shouldn't happen. */
217
218 snprintf(filename, sizeof(filename), "%s-%s.pem", (data && !ud->epsv) ? ud->serv_data_host : ud->serv_dns.hostname,
219 (data) ? "data" : "ctrl");
220 if ( (fp = fopen(filename, "r")) == NULL) { /* key doesn't exist, store it */
221 if (debug)
222 printf("key %s doesn't exist, store it\n", filename);
223 if (ud->sec_level == 2) { /* don't add new certs */
224 X509_free(x509_peer);
225 return 0;
226 }
227 if ( (fp = fopen(filename, "w")) == NULL) {
228 X509_free(x509_peer);
229 sys_err(filename);
230 } else {
231 PEM_write_X509(fp, x509_peer);
232 cert_ok = 1;
233 }
234 } else { /* KEY already exists, verify it */
235 if (debug)
236 printf("key %s exists, verifying it\n", filename);
237 if((x509_stored = PEM_read_X509(fp, NULL, 0, NULL)) == NULL)
238 sys_err("can't read certificate");
239 if (X509_cmp(x509_peer, x509_stored) == 0)
240 cert_ok = 1;
241 else {
242 if (debug)
243 printf("X509_cmp failed\n");
244 }
245
246 if (debug && cert_ok)
247 printf("verified cert ok\n");
248 }
249
250 fclose(fp);
251
252 X509_free(x509_peer);
253 if (x509_stored != NULL)
254 X509_free(x509_stored);
255 return cert_ok;
256 }
257
tls_cert2(struct user_data * ud,int data)258 long tls_cert2(struct user_data *ud, int data) /* save new key or verify saved key */
259 {
260 X509 *x509_peer;
261 X509_NAME *x509_subj;
262 X509_EXTENSION *x509_ext;
263 const X509V3_EXT_METHOD *x509_meth;
264 int ok, extcount, i, j;
265 char *extstr;
266 SSL *ssl;
267 #if (OPENSSL_VERSION_NUMBER > 0x00908000L)
268 unsigned char const *data1;
269 #else
270 unsigned char *data1;
271 #endif
272 char data2[256];
273 STACK_OF(CONF_VALUE) *val;
274 CONF_VALUE *nval;
275 void *ext_str = NULL;
276 int subjectaltname;
277
278 ok = subjectaltname = 0;
279 ssl = (data) ? ud->ssl_data : ud->ssl_ctrl;
280
281 if (debug)
282 printf("tls_cert2\n");
283
284 if ((x509_peer = SSL_get_peer_certificate(ssl)) == NULL)
285 return X509_V_ERR_APPLICATION_VERIFICATION; /* SSL_get_peer* can only be NULL on 'anonymous DH connections' so shouldn't happen. */
286
287 if (ud->sec_level == 3) {
288 X509_free(x509_peer);
289 return SSL_get_verify_result(ssl);
290 }
291
292 if ((extcount = X509_get_ext_count(x509_peer)) > 0) {
293 if (debug) printf("extcount = %d\n", extcount);
294 for (i = 0; i < extcount; i++) {
295 x509_ext = X509_get_ext(x509_peer, i);
296 extstr = (char*)OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(x509_ext)));
297 if (debug) printf("extstr = %s\n", extstr);
298 if (!strcmp(extstr, "subjectAltName")) {
299 ASN1_OCTET_STRING *x509_ext_data;
300 subjectaltname = 1;
301 if (!(x509_meth = X509V3_EXT_get(x509_ext)))
302 break;
303 x509_ext_data = X509_EXTENSION_get_data(x509_ext);
304 data1 = x509_ext_data->data;
305 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
306 if (x509_meth->it)
307 ext_str = ASN1_item_d2i(NULL, &data1, x509_ext_data->length, ASN1_ITEM_ptr(x509_meth->it));
308 else
309 ext_str = x509_meth->d2i(NULL, &data1, x509_ext_data->length);
310 #else
311 ext_str = x509_meth->d2i(NULL, &data1, x509_ext->value->length);
312 #endif
313 val = x509_meth->i2v(x509_meth, ext_str, NULL);
314 for (j = 0; j < sk_CONF_VALUE_num(val); j++) {
315 nval = sk_CONF_VALUE_value(val, j);
316 if (debug)
317 printf("X509 extension : %s - %s\n", nval->name, nval->value);
318 if (!strcmp(nval->name, "DNS") && !strcasecmp(nval->value, ud->serv_host)) {
319 ok = 1;
320 break;
321 } else if (!strcmp(nval->name, "IP Address") &&
322 ( (data == 0 && !strcmp(nval->value, ud->serv_dns.hostname)) ||
323 (data == 1 && !strcmp(nval->value, ud->serv_data_host)) ) ) {
324 ok = 1;
325 break;
326 }
327 }
328 }
329 if (ok) break;
330 }
331 }
332
333 if (!ok && (x509_subj = X509_get_subject_name(x509_peer)) && X509_NAME_get_text_by_NID(x509_subj, NID_commonName, data2, sizeof(data2)) > 0) {
334 data2[255] = 0;
335 if ((strcasecmp(data2, ud->serv_host) != 0) || subjectaltname) {
336 X509_free(x509_peer);
337 return X509_V_ERR_APPLICATION_VERIFICATION;
338 }
339 }
340 X509_free(x509_peer);
341 return SSL_get_verify_result(ssl);
342 }
343
344 void
tls_auth_cont(struct user_data * ud,int data)345 tls_auth_cont(struct user_data *ud, int data)
346 {
347 int status, sslerr, cert_ok;
348 const SSL_CIPHER *cipher;
349 char cipher_info[128];
350 SSL *ssl;
351
352 if (debug)
353 printf("tls_auth_cont\n");
354 ssl = (data) ? ud->ssl_data : ud->ssl_ctrl;
355
356 if (ssl == NULL) printf("SSL == NULL!\n");
357
358 status = SSL_connect(ssl);
359 sslerr = SSL_get_error(ssl, status);
360 if (data)
361 ud->ssl_data_fd_mode = TLS_NONE;
362 else
363 ud->ssl_ctrl_fd_mode = TLS_NONE;
364
365 /* if ((data) && (status == 1)) {
366 status = -1; sslerr = 1; } */
367
368 if (status == 1) { /* The TLS/SSL handshake was successfully completed */
369 cipher = SSL_get_current_cipher(ssl);
370 SSL_CIPHER_description(cipher, cipher_info, sizeof(cipher_info));
371 if (debug)
372 printf("cipher %s, sec_level %d\n", cipher_info, ud->sec_level);
373 cert_ok = (ud->sec_level == 1 || ud->sec_level == 2) ? tls_cert(ud, data) : (ud->sec_level >= 3) ? tls_cert2(ud, data) == X509_V_OK : 1;
374 if (debug)
375 printf("cert_ok = %d, data = %d\n", cert_ok, data);
376
377 if (data) {
378 ud->tls_status |= TLS_DATA;
379 ud->data_connected = CONN_DATA_OK;
380 } else {
381 ud->serv_status = SERV_TLS_OK;
382 ud->tls_status |= TLS_CTRL;
383 print_to_serv(ud, "PBSZ 0\r\n");
384 if (debug)
385 printf("printed pbsz\n");
386 }
387 if (!cert_ok) {
388 if (!data) {
389 ud->serv_status = SERV_FLOW;
390 print_to_ud(ud, "530 TLSWrap certificate verification failed, disconnecting.\r\n");
391 print_to_serv(ud, "QUIT\r\n");
392 } else {
393 print_to_ud(ud, "425 TLSWrap data certificate verification failed.\r\n");
394 SSL_clear(ud->ssl_data); /* Prevent reuse */
395 data_close(ud);
396 }
397 if (debug)
398 printf("printed that certificate verification failed.\n");
399 //user_close(ud);
400 }
401 } else {
402 switch (sslerr) {
403 case SSL_ERROR_WANT_READ:
404 if (debug)
405 printf("setting TLS_READ\n");
406 if (data)
407 ud->ssl_data_fd_mode = TLS_READ;
408 else
409 ud->ssl_ctrl_fd_mode = TLS_READ;
410 break;
411 case SSL_ERROR_WANT_WRITE:
412 if (debug)
413 printf("setting TLS_WRITE\n");
414 if (data)
415 ud->ssl_data_fd_mode = TLS_WRITE;
416 else
417 ud->ssl_ctrl_fd_mode = TLS_WRITE;
418 break;
419 case SSL_ERROR_SSL:
420 case SSL_ERROR_SYSCALL: // assorted I/O error
421 if (debug)
422 printf("tls_auth_cont got SSL_ERROR_SSL or SSL_ERROR_SYSCALL\n");
423 if (!data) {
424 ud->serv_status = SERV_NONE;
425 print_to_ud(ud, "530 TLSWrap SSL/TLS connection to server failed.\r\n");
426 ud->connected = CONN_NO;
427 } else {
428 /* ud->serv_data_close = CLOSE_READ;
429 ud->user_data_close = CLOSE_READ; */
430 print_to_ud(ud, "230 TLSWrap SSL/TLS DATA connection to server failed.\r\n");
431 SSL_clear(ssl);
432 data_close(ud);
433 }
434 break;
435 default:
436 if (debug)
437 printf("tls_auth_cont failed (%d)\n", sslerr);
438 if (sslerr)
439 perror("tls_auth_cont");
440 if (data) {
441 SSL_clear(ud->ssl_data);
442 data_close(ud);
443 }
444 }
445 }
446 }
447
448 int
tls_write(struct user_data * ud,const void * buf,int num,int data)449 tls_write(struct user_data *ud, const void *buf, int num, int data)
450 {
451 SSL *ssl;
452 int status, sslerr;
453
454 ssl = (data) ? ud->ssl_data : ud->ssl_ctrl;
455
456 status = SSL_write(ssl, buf, num);
457 sslerr = SSL_get_error(ssl, status);
458
459 if (status == -1) {
460 if (data)
461 ud->ssl_data_func = TLS_WRITE;
462 else
463 ud->ssl_ctrl_func = TLS_WRITE;
464 switch (sslerr) {
465 case SSL_ERROR_WANT_READ:
466 if (data)
467 ud->ssl_data_fd_mode = TLS_READ;
468 else
469 ud->ssl_ctrl_fd_mode = TLS_READ;
470 break;
471 case SSL_ERROR_WANT_WRITE:
472 if (data)
473 ud->ssl_data_fd_mode = TLS_WRITE;
474 else
475 ud->ssl_ctrl_fd_mode = TLS_WRITE;
476 break;
477 default:
478 if (debug)
479 printf("tls_write_error\n");
480 return -1;
481 }
482 } else {
483 if (data)
484 ud->ssl_data_fd_mode = TLS_NONE;
485 else
486 ud->ssl_ctrl_fd_mode = TLS_NONE;
487 }
488
489 return status;
490 }
491
492 int
tls_read(struct user_data * ud,void * buf,int num,int data)493 tls_read(struct user_data *ud, void *buf, int num, int data)
494 {
495 SSL *ssl;
496 int status, sslerr;
497
498 ssl = (data) ? ud->ssl_data : ud->ssl_ctrl;
499
500 status = SSL_read(ssl, buf, num);
501 sslerr = SSL_get_error(ssl, status);
502
503 if (status == -1) {
504 if (data)
505 ud->ssl_data_func = TLS_READ;
506 else
507 ud->ssl_ctrl_func = TLS_READ;
508 switch (sslerr) {
509 case SSL_ERROR_WANT_READ:
510 if (data)
511 ud->ssl_data_fd_mode = TLS_READ;
512 else
513 ud->ssl_ctrl_fd_mode = TLS_READ;
514 break;
515 case SSL_ERROR_WANT_WRITE:
516 if (data)
517 ud->ssl_data_fd_mode = TLS_WRITE;
518 else
519 ud->ssl_ctrl_fd_mode = TLS_WRITE;
520 break;
521 default:
522 if (debug)
523 printf("tls_read_error\n");
524 return -2;
525 }
526 } else {
527 if (data)
528 ud->ssl_data_fd_mode = TLS_NONE;
529 else
530 ud->ssl_ctrl_fd_mode = TLS_NONE;
531 }
532
533 return status;
534 }
535