1 /*
2  * $LynxId: tidy_tls.c,v 1.35 2016/11/24 18:48:02 tom Exp $
3  * Copyright 2008-2015,2016 Thomas E. Dickey
4  * with fix Copyright 2008 by Thomas Viehmann
5  *
6  * Required libraries:
7  *	libgnutls
8  *	libcrypt
9  */
10 #include <HTUtils.h>
11 #include <tidy_tls.h>
12 
13 #include <gnutls/x509.h>
14 #ifdef HAVE_GNUTLS_RND
15 #include <gnutls/crypto.h>
16 #else
17 #include <gcrypt.h>
18 #endif
19 #include <libtasn1.h>		/* ASN1_SUCCESS,etc */
20 #include <string.h>
21 
22 #define typeCalloc(type) (type *) calloc(1, sizeof(type))
23 
24 static int last_error = 0;
25 
26 /* ugly, but hey, we could just use a more sane api, too */
27 #define GetDnByOID(target, oid, thewhat) \
28 	len = sizeof(target); \
29 	if (! thewhat) \
30 	    gnutls_x509_crt_get_dn_by_oid(xcert, oid, 0, 0, target, &len); \
31 	else \
32 	    gnutls_x509_crt_get_issuer_dn_by_oid(xcert, oid, 0, 0, target, &len)
33 
34 /* thewhat: which DN to get 0 = subject, 1 = issuer */
ExtractCertificate(const gnutls_datum_t * cert,X509_NAME * result,int thewhat)35 static int ExtractCertificate(const gnutls_datum_t *cert, X509_NAME * result, int thewhat)
36 {
37     gnutls_x509_crt_t xcert;
38     int rc;
39     size_t len;
40 
41     if ((rc = gnutls_x509_crt_init(&xcert)) >= 0) {
42 	if ((rc = gnutls_x509_crt_import(xcert, cert, GNUTLS_X509_FMT_DER)) >= 0) {
43 	    GetDnByOID(result->country,
44 		       GNUTLS_OID_X520_COUNTRY_NAME, thewhat);
45 	    GetDnByOID(result->organization,
46 		       GNUTLS_OID_X520_ORGANIZATION_NAME, thewhat);
47 	    GetDnByOID(result->organizational_unit_name,
48 		       GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, thewhat);
49 	    GetDnByOID(result->common_name,
50 		       GNUTLS_OID_X520_COMMON_NAME, thewhat);
51 	    GetDnByOID(result->locality_name,
52 		       GNUTLS_OID_X520_LOCALITY_NAME, thewhat);
53 	    GetDnByOID(result->state_or_province_name,
54 		       GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, thewhat);
55 	    GetDnByOID(result->email,
56 		       GNUTLS_OID_PKCS9_EMAIL, thewhat);
57 	    rc = 0;
58 	}
59 	gnutls_x509_crt_deinit(xcert);
60     }
61     return rc;
62 }
63 
64 /*
65  * (stub)
66  * ERR_error_string() generates a human-readable string representing the
67  * error code 'e', and places it at 'buffer', which must be at least 120 bytes
68  * long. If 'buffer' is NULL, the error string is placed in a static buffer.
69  */
ERR_error_string(unsigned long e,char * buffer)70 const char *ERR_error_string(unsigned long e, char *buffer)
71 {
72     (void) buffer;
73     return gnutls_strerror((int) -e);
74 }
75 
76 /*
77  * (stub)
78  * Return the earliest error code from the thread's error queue and remove the
79  * entry.
80  */
ERR_get_error(void)81 unsigned long ERR_get_error(void)
82 {
83     unsigned long rc;
84 
85     rc = (unsigned long) (-last_error);
86     last_error = 0;
87 
88     return rc;
89 }
90 
91 /*
92  * Put 'num' cryptographically strong pseudo-random bytes into 'buffer'.
93  */
RAND_bytes(unsigned char * buffer,int num)94 int RAND_bytes(unsigned char *buffer, int num)
95 {
96     int rc;
97 
98 #ifdef HAVE_GNUTLS_RND
99     rc = gnutls_rnd(GNUTLS_RND_KEY, buffer, (size_t) num);
100 #else
101     gcry_randomize(buffer, num, GCRY_VERY_STRONG_RANDOM);
102     rc = 1;
103 #endif
104     return rc;
105 }
106 
107 /*
108  * (stub)
109  * Generate a default path for the random seed file.  'buffer' points to a
110  * buffer of size 'len' in which to store the filename.
111  */
RAND_file_name(char * buffer,size_t len)112 const char *RAND_file_name(char *buffer, size_t len)
113 {
114     (void) buffer;
115     (void) len;
116     return "";
117 }
118 
119 /*
120  * (stub)
121  * Read a number of bytes from file 'name' and adds them to the PRNG.  If
122  * 'maxbytes' is non-negative, up to to 'maxbytes' are read; if 'maxbytes' is
123  * -1, the complete file is read.
124  */
RAND_load_file(const char * name,long maxbytes)125 int RAND_load_file(const char *name, long maxbytes)
126 {
127     (void) name;
128     return (int) maxbytes;
129 }
130 
131 /*
132  * (stub)
133  * Mix the 'num' bytes at 'buffer' into the PRNG state.
134  */
RAND_seed(const void * buffer,int num)135 void RAND_seed(const void *buffer, int num)
136 {
137     (void) buffer;
138     (void) num;
139 }
140 
141 /*
142  * (stub)
143  * Return 1 if the PRNG has been seeded with enough data, 0 otherwise.
144  */
RAND_status(void)145 int RAND_status(void)
146 {
147     return 1;
148 }
149 
150 /*
151  * (stub)
152  * Write a number of random bytes (currently 1024) to file 'name' which can be
153  * used to initialize the PRNG by calling RAND_load_file() in a later session.
154  */
RAND_write_file(const char * name)155 int RAND_write_file(const char *name)
156 {
157     (void) name;
158     return 0;
159 }
160 
161 /*
162  * Return the number of secret bits used for cipher.  If 'bits' is not NULL, it
163  * contains the number of bits processed by the chosen algorithm.  If cipher is
164  * NULL, 0 is returned.
165  */
SSL_CIPHER_get_bits(SSL_CIPHER * cipher,int * bits)166 int SSL_CIPHER_get_bits(SSL_CIPHER * cipher, int *bits)
167 {
168     int result = 0;
169 
170     if (cipher) {
171 	result = (8 * (int) gnutls_cipher_get_key_size(cipher->encrypts));
172     }
173 
174     if (bits)
175 	*bits = result;
176 
177     return result;
178 }
179 
180 /*
181  * Return a pointer to the name of 'cipher'.  If 'cipher' is NULL the constant
182  * value "NONE" is returned.
183  */
SSL_CIPHER_get_name(SSL_CIPHER * cipher)184 const char *SSL_CIPHER_get_name(SSL_CIPHER * cipher)
185 {
186     const char *result = "NONE";
187 
188     if (cipher) {
189 	result = gnutls_cipher_suite_get_name(cipher->key_xchg,
190 					      cipher->encrypts,
191 					      cipher->msg_code);
192     }
193     return result;
194 }
195 
196 /*
197  * Return the protocol version for cipher, currently "SSLv2", "SSLv3", or
198  * "TLSv1".  If cipher is NULL, "(NONE)" is returned.
199  */
SSL_CIPHER_get_version(SSL_CIPHER * cipher)200 const char *SSL_CIPHER_get_version(SSL_CIPHER * cipher)
201 {
202     const char *result = "NONE";
203 
204     if (cipher) {
205 	if ((result = gnutls_protocol_get_name(cipher->protocol)) == 0)
206 	    result = "unknown";
207     }
208     return result;
209 }
210 
211 /*
212  * Free an allocated SSL_CTX object.
213  */
SSL_CTX_free(SSL_CTX * ctx)214 void SSL_CTX_free(SSL_CTX * ctx)
215 {
216     free(ctx->method);
217     free(ctx);
218 }
219 
220 /*
221  * Create a new SSL_CTX object as framework for TLS/SSL enabled functions.
222  */
SSL_CTX_new(SSL_METHOD * method)223 SSL_CTX *SSL_CTX_new(SSL_METHOD * method)
224 {
225     SSL_CTX *ctx;
226 
227     if ((ctx = typeCalloc(SSL_CTX)) != 0) {
228 	ctx->method = method;
229     }
230 
231     return ctx;
232 }
233 
234 /*
235  * See SSL_CTX_load_verify_locations() - this sets the paths for that and
236  * SSL_CTX_set_verify() to their default values.  GNU TLS does not have a
237  * comparable feature (stub).
238  */
SSL_CTX_set_default_verify_paths(SSL_CTX * ctx)239 int SSL_CTX_set_default_verify_paths(SSL_CTX * ctx)
240 {
241     (void) ctx;
242     return 0;
243 }
244 
245 /*
246  * SSL_CTX_set_options() adds the options set via bitmask in options to
247  * ctx.  Options already set before are not cleared.
248  */
SSL_CTX_set_options(SSL_CTX * ctx,unsigned long options)249 unsigned long SSL_CTX_set_options(SSL_CTX * ctx, unsigned long options)
250 {
251     ctx->options |= options;
252     return ctx->options;
253 }
254 
255 /*
256  * Set peer certificate verification parameters.
257  */
SSL_CTX_set_verify(SSL_CTX * ctx,int verify_mode,int (* verify_callback)(int,X509_STORE_CTX *))258 void SSL_CTX_set_verify(SSL_CTX * ctx, int verify_mode,
259 			int (*verify_callback) (int, X509_STORE_CTX *))
260 {
261     ctx->verify_mode = verify_mode;
262     ctx->verify_callback = verify_callback;
263 }
264 
265 #ifdef HAVE_GNUTLS_PROTOCOL_SET_PRIORITY
RemoveProtocol(SSL * ssl,int protocol)266 static void RemoveProtocol(SSL * ssl, int protocol)
267 {
268     int j, k;
269     int changed = 0;
270     int *protocols = ssl->ctx->method->priority.protocol;
271 
272     for (j = k = 0; j < GNUTLS_MAX_ALGORITHM_NUM;) {
273 	if (protocols[k] == protocol) {
274 	    if (++k >= GNUTLS_MAX_ALGORITHM_NUM)
275 		break;
276 	    changed = 1;
277 	} else {
278 	    protocols[j++] = protocols[k++];
279 	}
280     }
281 
282     if (changed) {
283 	gnutls_protocol_set_priority(ssl->gnutls_state, protocols);
284     }
285 }
286 #endif
287 
288 /*
289  * Initiate the TLS/SSL handshake with an TLS/SSL server.
290  */
SSL_connect(SSL * ssl)291 int SSL_connect(SSL * ssl)
292 {
293     X509_STORE_CTX *store;
294     int rc;
295     gnutls_alert_description_t alert;
296     const char *aname;
297 
298     if (ssl->options & SSL_OP_NO_TLSv1) {
299 #ifdef HAVE_GNUTLS_PROTOCOL_SET_PRIORITY
300 	RemoveProtocol(ssl, GNUTLS_TLS1);
301 #else
302 	gnutls_priority_set_direct(ssl->gnutls_state, "NORMAL:-VERS-TLS1.0", NULL);
303 #endif
304     }
305 
306     while ((rc = gnutls_handshake(ssl->gnutls_state)) < 0 &&
307 	   !gnutls_error_is_fatal(rc)) {
308 	if (rc == GNUTLS_E_WARNING_ALERT_RECEIVED) {
309 	    alert = gnutls_alert_get(ssl->gnutls_state);
310 	    aname = gnutls_alert_get_name(alert);
311 	    CTRACE((tfp, "SSL Alert: %s\n", NonNull(aname)));
312 	    switch (gnutls_alert_get(ssl->gnutls_state)) {
313 	    case GNUTLS_A_UNRECOGNIZED_NAME:
314 		continue;	/* ignore */
315 	    default:
316 		break;
317 	    }
318 	    break;		/* treat all other alerts as fatal */
319 	}
320     }
321     ssl->last_error = rc;
322 
323     if (rc < 0) {
324 	last_error = rc;
325 	return 0;
326     }
327 
328     store = typeCalloc(X509_STORE_CTX);
329     if (store == 0)
330 	outofmem(__FILE__, "SSL_connect");
331 
332     store->ssl = ssl;
333     store->cert_list = SSL_get_peer_certificate(ssl);
334 
335     if (ssl->verify_callback) {
336 	ssl->verify_callback(1, store);
337     }
338     ssl->state = SSL_ST_OK;
339 
340     free(store);
341 
342     /* FIXME: deal with error from callback */
343 
344     return 1;
345 }
346 
347 /*
348  * Free an allocated SSL structure.
349  */
SSL_free(SSL * ssl)350 void SSL_free(SSL * ssl)
351 {
352     gnutls_certificate_free_credentials(ssl->gnutls_cred);
353     gnutls_deinit(ssl->gnutls_state);
354     free(ssl);
355 }
356 
357 /*
358  * Get SSL_CIPHER data of a connection.
359  */
SSL_get_current_cipher(SSL * ssl)360 SSL_CIPHER *SSL_get_current_cipher(SSL * ssl)
361 {
362     SSL_CIPHER *result = 0;
363 
364     if (ssl) {
365 	result = &(ssl->ciphersuite);
366 
367 	result->protocol = gnutls_protocol_get_version(ssl->gnutls_state);
368 	result->encrypts = gnutls_cipher_get(ssl->gnutls_state);
369 	result->key_xchg = gnutls_kx_get(ssl->gnutls_state);
370 	result->msg_code = gnutls_mac_get(ssl->gnutls_state);
371 	result->compress = gnutls_compression_get(ssl->gnutls_state);
372 	result->cert = gnutls_certificate_type_get(ssl->gnutls_state);
373     }
374 
375     return result;
376 }
377 
378 /*
379  * Get the X509 certificate of the peer.
380  */
SSL_get_peer_certificate(SSL * ssl)381 const X509 *SSL_get_peer_certificate(SSL * ssl)
382 {
383     const gnutls_datum_t *result;
384     unsigned list_size = 0;
385 
386     result =
387 	(const gnutls_datum_t *) gnutls_certificate_get_peers(ssl->gnutls_state,
388 							      &list_size);
389 
390     return (const X509 *) result;
391 }
392 
393 /*
394  * Initialize SSL library by registering algorithms.
395  */
SSL_library_init(void)396 int SSL_library_init(void)
397 {
398     gnutls_global_init();
399     return 1;
400 }
401 
402 /*
403  * (stub)
404  * OpenSSL uses this to prepare for ERR_get_error() calls.
405  */
SSL_load_error_strings(void)406 void SSL_load_error_strings(void)
407 {
408 }
409 
410 /*
411  * Create a new SSL structure for a connection.
412  */
SSL_new(SSL_CTX * ctx)413 SSL *SSL_new(SSL_CTX * ctx)
414 {
415     SSL *ssl;
416     int rc;
417 
418     if ((ssl = typeCalloc(SSL)) != 0) {
419 
420 	rc = gnutls_certificate_allocate_credentials(&ssl->gnutls_cred);
421 	if (rc < 0) {
422 	    last_error = rc;
423 	    free(ssl);
424 	    ssl = 0;
425 	} else {
426 	    ssl->ctx = ctx;
427 
428 	    gnutls_init(&ssl->gnutls_state, ctx->method->connend);
429 	    gnutls_set_default_priority(ssl->gnutls_state);
430 
431 	    gnutls_credentials_set(ssl->gnutls_state, GNUTLS_CRD_CERTIFICATE,
432 				   ssl->gnutls_cred);
433 	    if (ctx->certfile)
434 		gnutls_certificate_set_x509_trust_file(ssl->gnutls_cred,
435 						       ctx->certfile,
436 						       ctx->certfile_type);
437 	    if (ctx->client_keyfile)
438 		gnutls_certificate_set_x509_key_file(ssl->gnutls_cred,
439 						     ctx->client_certfile,
440 						     ctx->client_keyfile,
441 						     ctx->client_keyfile_type);
442 	    ssl->verify_mode = ctx->verify_mode;
443 	    ssl->verify_callback = ctx->verify_callback;
444 
445 	    ssl->options = ctx->options;
446 
447 	    ssl->rfd = (gnutls_transport_ptr_t) (-1);
448 	    ssl->wfd = (gnutls_transport_ptr_t) (-1);
449 	    ssl->bytes_sent = 0;
450 	    ssl->sendbuffer = 0;
451 	}
452     }
453 
454     return ssl;
455 }
456 
457 /*
458  * Read 'length' bytes into 'buffer' from the given SSL connection.
459  * Returns the number of bytes read, or zero on error.
460  */
SSL_read(SSL * ssl,void * buffer,int length)461 int SSL_read(SSL * ssl, void *buffer, int length)
462 {
463     int rc;
464 
465     rc = (int) gnutls_record_recv(ssl->gnutls_state, buffer, (size_t) length);
466 
467     if (rc < 0 && gnutls_error_is_fatal(rc) == 0) {
468 	if (rc == GNUTLS_E_REHANDSHAKE) {
469 	    (void) gnutls_handshake(ssl->gnutls_state);
470 	    gnutls_record_send(ssl->gnutls_state, ssl->sendbuffer, (size_t) ssl->bytes_sent);
471 	    rc = (int) gnutls_record_recv(ssl->gnutls_state, buffer, (size_t) length);
472 	}
473     }
474 
475     ssl->last_error = rc;
476 
477     if (rc < 0) {
478 	last_error = rc;
479 	rc = 0;
480     }
481 
482     return rc;
483 }
484 
485 /*
486  * Connect the SSL object with a file descriptor.
487  * This always returns 1 (success) since GNU TLS does not check for errors.
488  */
SSL_set_fd(SSL * ssl,int fd)489 int SSL_set_fd(SSL * ssl, int fd)
490 {
491     gnutls_transport_set_ptr(ssl->gnutls_state,
492 			     (gnutls_transport_ptr_t) (intptr_t) (fd));
493     return 1;
494 }
495 
496 /*
497  * Write 'length' bytes from 'buffer' to the given SSL connection.
498  */
SSL_write(SSL * ssl,const void * buffer,int length)499 int SSL_write(SSL * ssl, const void *buffer, int length)
500 {
501     int rc;
502 
503     rc = (int) gnutls_record_send(ssl->gnutls_state, buffer, (size_t) length);
504     ssl->last_error = rc;
505 
506     if (rc < 0) {
507 	last_error = rc;
508 	rc = 0;
509     } else {
510 	size_t need = (size_t) rc;
511 
512 	free(ssl->sendbuffer);
513 	ssl->sendbuffer = malloc(need);
514 	ssl->bytes_sent = need;
515     }
516 
517     return rc;
518 }
519 
520 /*
521  * Return method-data for SSL verion 3, with the option of rollback to SSL
522  * version 2.
523  */
SSLv23_client_method(void)524 SSL_METHOD *SSLv23_client_method(void)
525 {
526     SSL_METHOD *m;
527 
528     if ((m = typeCalloc(SSL_METHOD)) != 0) {
529 	int n;
530 
531 	/*
532 	 * List the protocols in decreasing order of priority.
533 	 */
534 	n = 0;
535 #if GNUTLS_VERSION_NUMBER >= 0x030000
536 	m->priority.protocol[n++] = GNUTLS_SSL3;
537 	m->priority.protocol[n++] = GNUTLS_TLS1_2;
538 #endif
539 	m->priority.protocol[n++] = GNUTLS_TLS1_1;
540 	m->priority.protocol[n++] = GNUTLS_TLS1_0;
541 	m->priority.protocol[n] = 0;
542 
543 	/*
544 	 * List the cipher algorithms in decreasing order of priority.
545 	 */
546 	n = 0;
547 #if GNUTLS_VERSION_NUMBER >= 0x030000
548 	m->priority.encrypts[n++] = GNUTLS_CIPHER_AES_256_GCM;
549 	m->priority.encrypts[n++] = GNUTLS_CIPHER_AES_128_GCM;
550 #endif
551 	m->priority.encrypts[n++] = GNUTLS_CIPHER_AES_256_CBC;
552 	m->priority.encrypts[n++] = GNUTLS_CIPHER_AES_128_CBC;
553 	m->priority.encrypts[n++] = GNUTLS_CIPHER_CAMELLIA_256_CBC;
554 	m->priority.encrypts[n++] = GNUTLS_CIPHER_CAMELLIA_128_CBC;
555 	m->priority.encrypts[n++] = GNUTLS_CIPHER_3DES_CBC;
556 	m->priority.encrypts[n] = 0;
557 
558 	/*
559 	 * List the compression algorithms in decreasing order of priority.
560 	 */
561 	n = 0;
562 	m->priority.compress[n++] = GNUTLS_COMP_NULL;
563 	m->priority.compress[n] = 0;
564 
565 	/*
566 	 * List the key exchange algorithms in decreasing order of priority.
567 	 */
568 	n = 0;
569 	m->priority.key_xchg[n++] = GNUTLS_KX_DHE_RSA;
570 	m->priority.key_xchg[n++] = GNUTLS_KX_RSA;
571 	m->priority.key_xchg[n++] = GNUTLS_KX_DHE_DSS;
572 	m->priority.key_xchg[n] = 0;
573 
574 	/*
575 	 * List message authentication code (MAC) algorithms in decreasing
576 	 * order of priority to specify via gnutls_mac_set_priority().
577 	 */
578 	n = 0;
579 	m->priority.msg_code[n++] = GNUTLS_MAC_SHA1;
580 	m->priority.msg_code[n++] = GNUTLS_MAC_MD5;
581 	m->priority.msg_code[n] = 0;
582 
583 	/*
584 	 * For gnutls_init, says we're a client.
585 	 */
586 	m->connend = GNUTLS_CLIENT;
587     }
588 
589     return m;
590 }
591 
add_name(char * target,int len,const char * tag,const char * data)592 static int add_name(char *target, int len, const char *tag, const char *data)
593 {
594     if (*data != '\0') {
595 	int need = (int) strlen(tag) + 2;
596 
597 	target += strlen(target);
598 	if (need < len) {
599 	    strcat(target, "/");
600 	    strcat(target, tag);
601 	    strcat(target, "=");
602 	    len -= need;
603 	    target += need;
604 	}
605 	need = (int) strlen(data);
606 	if (need >= len - 1)
607 	    need = len - 1;
608 	strncat(target, data, (size_t) need)[need] = '\0';
609     }
610     return len;
611 }
612 #define ADD_NAME(tag, data) len = add_name(target, len, tag, data);
613 
614 /*
615  * Convert the X509 name 'source' to a string in the given buffer 'target',
616  * whose length is 'len'.  Return a pointer to the buffer.
617  */
X509_NAME_oneline(X509_NAME * source,char * target,int len)618 char *X509_NAME_oneline(X509_NAME * source, char *target, int len)
619 {
620     if (target && (len > 0)) {
621 	*target = '\0';
622 	if (source) {
623 	    ADD_NAME("C", source->country);
624 	    ADD_NAME("ST", source->state_or_province_name);
625 	    ADD_NAME("L", source->locality_name);
626 	    ADD_NAME("O", source->organization);
627 	    ADD_NAME("OU", source->organizational_unit_name);
628 	    ADD_NAME("CN", source->common_name);
629 	    ADD_NAME("Email", source->email);
630 	}
631     }
632     return target;
633 }
634 
635 /*
636  * Extract the certificate's issuer-name data.
637  */
X509_get_issuer_name(const X509 * cert)638 X509_NAME *X509_get_issuer_name(const X509 * cert)
639 {
640     static X509_NAME *result;
641 
642     free(result);
643     if ((result = typeCalloc(X509_NAME)) != 0) {
644 	if (ExtractCertificate(cert, result, 1) < 0) {
645 	    free(result);
646 	    result = 0;
647 	}
648     }
649     return result;
650 }
651 
652 /*
653  * Extract the certificate's subject-name data.
654  */
X509_get_subject_name(const X509 * cert)655 X509_NAME *X509_get_subject_name(const X509 * cert)
656 {
657     static X509_NAME *result;
658 
659     free(result);
660     if ((result = typeCalloc(X509_NAME)) != 0) {
661 	if (ExtractCertificate(cert, result, 0) < 0) {
662 	    free(result);
663 	    result = 0;
664 	}
665     }
666     return result;
667 }
668