1 /*
2 ** Copyright 2000-2009 Double Precision, Inc.
3 ** See COPYING for distribution information.
4 */
5 #include	"config.h"
6 #include	"argparse.h"
7 #include	"spipe.h"
8 #define COURIERTCPD_EXPOSE_OPENSSL 1
9 #include	"libcouriertls.h"
10 #include	<openssl/rand.h>
11 #include	<openssl/x509.h>
12 #include	"tlscache.h"
13 #include	"rfc1035/rfc1035.h"
14 #include	"soxwrap/soxwrap.h"
15 #include	"random128/random128.h"
16 #ifdef  getc
17 #undef  getc
18 #endif
19 #include	<stdio.h>
20 #include	<string.h>
21 #include	<stdlib.h>
22 #include	<ctype.h>
23 #include	<netdb.h>
24 #if HAVE_DIRENT_H
25 #include <dirent.h>
26 #define NAMLEN(dirent) strlen((dirent)->d_name)
27 #else
28 #define dirent direct
29 #define NAMLEN(dirent) (dirent)->d_namlen
30 #if HAVE_SYS_NDIR_H
31 #include <sys/ndir.h>
32 #endif
33 #if HAVE_SYS_DIR_H
34 #include <sys/dir.h>
35 #endif
36 #if HAVE_NDIR_H
37 #include <ndir.h>
38 #endif
39 #endif
40 #if	HAVE_UNISTD_H
41 #include	<unistd.h>
42 #endif
43 #if	HAVE_FCNTL_H
44 #include	<fcntl.h>
45 #endif
46 #include	<errno.h>
47 #if	HAVE_SYS_TYPES_H
48 #include	<sys/types.h>
49 #endif
50 #if	HAVE_SYS_STAT_H
51 #include	<sys/stat.h>
52 #endif
53 #include	<sys/socket.h>
54 #include	<arpa/inet.h>
55 
56 #include	<sys/time.h>
57 
58 /***** TODO *****/
59 
60 /* #define TLSCACHEDEBUG */
61 
safe_getenv(const struct tls_info * info,const char * n)62 static const char *safe_getenv(const struct tls_info *info, const char *n)
63 {
64 	const char *v=(*info->getconfigvar)(n, info->app_data);
65 
66 	if (!v)	v="";
67 	return (v);
68 }
69 
get_peer_verify_level(const struct tls_info * info)70 static int get_peer_verify_level(const struct tls_info *info)
71 {
72 	int peer_verify_level=SSL_VERIFY_PEER;
73 		/* SSL_VERIFY_NONE */
74 		/* SSL_VERIFY_PEER */
75 		/* SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT */
76 	const char *s=safe_getenv(info, "TLS_VERIFYPEER");
77 
78 	if (info->peer_verify_domain)
79 		return SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
80 
81 	switch (*s)	{
82 	case 'n':
83 	case 'N':		/* NONE */
84 		peer_verify_level=SSL_VERIFY_NONE;
85 		break;
86 	case 'p':
87 	case 'P':		/* PEER */
88 		peer_verify_level=SSL_VERIFY_PEER;
89 		break;
90 	case 'r':
91 	case 'R':		/* REQUIREPEER */
92 		peer_verify_level=
93 			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
94 		break;
95 	}
96 	return (peer_verify_level);
97 }
98 
ssl_verify_callback(int goodcert,X509_STORE_CTX * x509)99 static int ssl_verify_callback(int goodcert, X509_STORE_CTX *x509)
100 {
101 	SSL *ssl=
102 		X509_STORE_CTX_get_ex_data(x509,
103 					   SSL_get_ex_data_X509_STORE_CTX_idx()
104 					   );
105 	struct tls_info *info=SSL_get_app_data(ssl);
106 
107 	if (info->peer_verify_domain || get_peer_verify_level(info))
108 	{
109 		if (!goodcert)
110 			return (0);
111 
112 		info->certificate_verified=1;
113 	}
114 
115 	return (1);
116 }
117 
verifypeer(const struct tls_info * info,SSL * ssl)118 static int verifypeer(const struct tls_info *info, SSL *ssl)
119 {
120 	X509 *x=NULL;
121 	X509_NAME *subj=NULL;
122 	int nentries, j;
123 	char domain[256];
124 	char *p;
125 	char errmsg[1000];
126 
127 	if (!info->peer_verify_domain)
128 		return (1);
129 
130 	if (info->isserver)
131 	{
132 		x=SSL_get_peer_certificate(ssl);
133 
134 		if (x)
135 			subj=X509_get_subject_name(x);
136 	}
137 	else
138 	{
139 		STACK_OF(X509) *peer_cert_chain=SSL_get_peer_cert_chain(ssl);
140 
141 		if (peer_cert_chain && peer_cert_chain->stack.num > 0)
142 		{
143 			X509 *xx=(X509 *)peer_cert_chain->stack.data[0];
144 
145 			if (xx)
146 				subj=X509_get_subject_name(xx);
147 		}
148 	}
149 
150 
151 	nentries=0;
152 	if (subj)
153 		nentries=X509_NAME_entry_count(subj);
154 
155 	domain[0]=0;
156 	for (j=0; j<nentries; j++)
157 	{
158 		const char *obj_name;
159 		X509_NAME_ENTRY *e;
160 		ASN1_OBJECT *o;
161 		ASN1_STRING *d;
162 
163 		int dlen;
164 		unsigned char *ddata;
165 
166 		e=X509_NAME_get_entry(subj, j);
167 		if (!e)
168 			continue;
169 
170 		o=X509_NAME_ENTRY_get_object(e);
171 		d=X509_NAME_ENTRY_get_data(e);
172 
173 		if (!o || !d)
174 			continue;
175 
176 		obj_name=OBJ_nid2sn(OBJ_obj2nid(o));
177 
178 		dlen=ASN1_STRING_length(d);
179 		ddata=ASN1_STRING_data(d);
180 
181 		if (strcasecmp(obj_name, "CN") == 0)
182 		{
183 			if (dlen >= sizeof(domain)-1)
184 				dlen=sizeof(domain)-1;
185 
186 			memcpy(domain, ddata, dlen);
187 			domain[dlen]=0;
188 		}
189 	}
190 
191 	if (x)
192 		X509_free(x);
193 	p=domain;
194 
195 	if (*p == '*')
196 	{
197 		int	pl, l;
198 
199 		pl=strlen(++p);
200 		l=strlen(info->peer_verify_domain);
201 
202 		if (*p == '.' && pl <= l &&
203 		    strcasecmp(info->peer_verify_domain+l-pl, p) == 0)
204 			return (1);
205 	}
206 	else if (strcasecmp(info->peer_verify_domain, p) == 0)
207 		return (1);
208 
209 	strcpy(errmsg, "couriertls: Mismatched SSL certificate: CN=");
210 	strcat(errmsg, domain);
211 	strcat(errmsg, " (expected ");
212 	strncat(errmsg, info->peer_verify_domain, 256);
213 	strcat(errmsg, ")");
214 	(*info->tls_err_msg)(errmsg, info->app_data);
215 	return (0);
216 }
217 
218 #ifndef NO_RSA
219 
rsa_callback(SSL * s,int export,int keylength)220 static RSA *rsa_callback(SSL *s, int export, int keylength)
221 {
222 	return (RSA_generate_key(keylength,RSA_F4,NULL,NULL));
223 }
224 
225 #endif
226 
nonsslerror(const struct tls_info * info,const char * pfix)227 static void nonsslerror(const struct tls_info *info, const char *pfix)
228 {
229 	char errmsg[256];
230 
231 	strcpy(errmsg, "couriertls: ");
232 	strncat(errmsg, pfix, 200);
233 	strcat(errmsg, ": ");
234 	strncat(errmsg, strerror(errno), 255 - strlen(errmsg));
235 
236 	(*info->tls_err_msg)(errmsg, info->app_data);
237 }
238 
sslerror(const struct tls_info * info,const char * pfix,int rc)239 static void sslerror(const struct tls_info *info, const char *pfix, int rc)
240 {
241 	char errmsg[256];
242 	char errmsgbuf2[300];
243 	int errnum=ERR_get_error();
244 
245 	if (errnum == 0)
246 	{
247 		if (rc == 0)
248 		{
249 			(*info->tls_err_msg)("DEBUG: Unexpected SSL connection shutdown.",
250 					     info->app_data);
251 			return;
252 		}
253 
254 		nonsslerror(info, pfix);
255 		return;
256 	}
257 
258 	ERR_error_string_n(errnum, errmsg, sizeof(errmsg)-1);
259 
260 	errmsg[sizeof(errmsg)-1]=0;
261 
262 	strcpy(errmsgbuf2, "couriertls: ");
263 	strncat(errmsgbuf2, pfix, 200);
264 	strcat(errmsgbuf2, ": ");
265 	strncat(errmsgbuf2, errmsg, 299 - strlen(errmsgbuf2));
266 
267 	(*info->tls_err_msg)(errmsgbuf2, info->app_data);
268 }
269 
270 static void init_session_cache(struct tls_info *, SSL_CTX *);
271 
process_rsacertfile(SSL_CTX * ctx,const char * filename)272 static int process_rsacertfile(SSL_CTX *ctx, const char *filename)
273 {
274 #ifndef	NO_RSA
275 
276 	const struct tls_info *info=SSL_CTX_get_app_data(ctx);
277 
278 	SSL_CTX_set_tmp_rsa_callback(ctx, rsa_callback);
279 
280 	if(!SSL_CTX_use_certificate_chain_file(ctx, filename))
281 	{
282 		sslerror(info, filename, -1);
283 		return (0);
284 	}
285 
286 	if(!SSL_CTX_use_RSAPrivateKey_file(ctx, filename, SSL_FILETYPE_PEM))
287 	{
288 		sslerror(info, filename, -1);
289 		return (0);
290 	}
291 #endif
292 	return (1);
293 }
294 
295 
process_dhcertfile(SSL_CTX * ctx,const char * filename)296 static int process_dhcertfile(SSL_CTX *ctx, const char *filename)
297 {
298 #ifndef	NO_DH
299 
300 	const struct tls_info *info=SSL_CTX_get_app_data(ctx);
301 	BIO	*bio;
302 	DH	*dh;
303 	int	cert_done=0;
304 
305 	if(!SSL_CTX_use_certificate_chain_file(ctx, filename))
306 	{
307 		sslerror(info, filename, -1);
308 		return (0);
309 	}
310 
311 	if ((bio=BIO_new_file(filename, "r")) != 0)
312 	{
313 		if ((dh=PEM_read_bio_DHparams(bio, NULL, NULL, NULL)) != 0)
314 		{
315 			SSL_CTX_set_tmp_dh(ctx, dh);
316 			cert_done=1;
317 			DH_free(dh);
318 		}
319 		else
320 			sslerror(info, filename, -1);
321 		BIO_free(bio);
322 	}
323 	else
324 		sslerror(info, filename, -1);
325 
326 	if (!cert_done)
327 	{
328 		(*info->tls_err_msg)("couriertls: DH init failed!",
329 				     info->app_data);
330 
331 		return (0);
332 	}
333 
334 	if(!SSL_CTX_use_PrivateKey_file(ctx, filename, SSL_FILETYPE_PEM))
335 	{
336 		sslerror(info, filename, -1);
337 		return (0);
338 	}
339 #endif
340 	return (1);
341 }
342 
process_certfile(SSL_CTX * ctx,const char * certfile,const char * ip,int (* func)(SSL_CTX *,const char *))343 static int process_certfile(SSL_CTX *ctx, const char *certfile, const char *ip,
344 			    int (*func)(SSL_CTX *, const char *))
345 {
346 	if (ip && *ip)
347 	{
348 		char *test_file;
349 
350 		if (strncmp(ip, "::ffff:", 7) == 0 && strchr(ip, '.'))
351 			return (process_certfile(ctx, certfile, ip+7, func));
352 
353 		test_file= malloc(strlen(certfile)+strlen(ip)+2);
354 
355 		strcpy(test_file, certfile);
356 		strcat(test_file, ".");
357 		strcat(test_file, ip);
358 
359 		if (access(test_file, R_OK) == 0)
360 		{
361 			int rc= (*func)(ctx, test_file);
362 
363 			free(test_file);
364 			return rc;
365 		}
366 		free(test_file);
367 	}
368 
369 	return (*func)(ctx, certfile);
370 }
371 
client_cert_cb(ssl_handle ssl,X509 ** x509,EVP_PKEY ** pkey)372 static int client_cert_cb(ssl_handle ssl, X509 **x509, EVP_PKEY **pkey)
373 {
374 	struct tls_info *info=(struct tls_info *)SSL_get_app_data(ssl);
375 	int i;
376 	const char *pem_cert;
377 	size_t pem_cert_size;
378 	STACK_OF(X509_NAME) *client_cas;
379 	int cert_num=0;
380 	int rc;
381 
382 	if (info->getpemclientcert4ca == NULL)
383 		return 0;
384 
385 	rc=0;
386 	client_cas=SSL_get_client_CA_list(ssl);
387 
388 	if (info->loadpemclientcert4ca)
389 		(*info->loadpemclientcert4ca)(info->app_data);
390 
391 	for (cert_num=0; (*info->getpemclientcert4ca)(cert_num, &pem_cert,
392 						      &pem_cert_size,
393 						      info->app_data);
394 	     ++cert_num)
395 	{
396 		BIO *certbio;
397 		int err;
398 		X509 *x;
399 
400 		ERR_clear_error();
401 
402 		certbio=BIO_new_mem_buf((void *)pem_cert, pem_cert_size);
403 
404 		if (!certbio)
405 		{
406 			rc= -1;
407 			break;
408 		}
409 
410 		x=PEM_read_bio_X509(certbio, x509, NULL, NULL);
411 
412 		if (!x)
413 		{
414 			BIO_free(certbio);
415 			continue;
416 		}
417 
418 		for (i=0; client_cas && i<client_cas->stack.num; i++)
419 		{
420 			X509_NAME *cert=(X509_NAME *)client_cas->stack.data[i];
421 
422 			if (X509_NAME_cmp(cert,
423 					  x->cert_info->issuer) == 0)
424 				break;
425 		}
426 
427 		if (!client_cas || i >= client_cas->stack.num)
428 		{
429 			BIO_free(certbio);
430 			continue;
431 		}
432 
433 		while ((x=PEM_read_bio_X509(certbio, NULL,
434 					    NULL, 0)) != NULL)
435 		{
436 			if (SSL_CTX_add_extra_chain_cert(SSL_get_SSL_CTX(ssl),
437 							 x)
438 			    != 1)
439 			{
440 				X509_free(x);
441 				rc= -1;
442 				break;
443 			}
444 		}
445 
446 		err = ERR_peek_last_error();
447 		if (rc || ERR_GET_LIB(err) != ERR_LIB_PEM ||
448 		    ERR_GET_REASON(err) != PEM_R_NO_START_LINE)
449 		{
450 			BIO_free(certbio);
451 			continue;
452 		}
453 		BIO_free(certbio);
454 
455 		ERR_clear_error();
456 
457 		certbio=BIO_new_mem_buf((void *)pem_cert, pem_cert_size);
458 
459 		if (!certbio)
460 		{
461 			rc= -1;
462 			break;
463 		}
464 
465 		if (!PEM_read_bio_PrivateKey(certbio, pkey, NULL, NULL))
466 		{
467 			BIO_free(certbio);
468 			continue;
469 		}
470 
471 		BIO_free(certbio);
472 		rc=1;
473 		break;
474 	}
475 	ERR_clear_error();
476 	(*info->releasepemclientcert4ca)(info->app_data);
477 	return rc;
478 }
479 
tls_create(int isserver,const struct tls_info * info)480 SSL_CTX *tls_create(int isserver, const struct tls_info *info)
481 {
482 	SSL_CTX *ctx;
483 	const char *protocol=safe_getenv(info, "TLS_PROTOCOL");
484 	const char *ssl_cipher_list=safe_getenv(info, "TLS_CIPHER_LIST");
485 	int session_timeout=atoi(safe_getenv(info, "TLS_TIMEOUT"));
486 	const char *dhcertfile=safe_getenv(info, "TLS_DHCERTFILE");
487 	const char *certfile=safe_getenv(info, "TLS_CERTFILE");
488 	const char *s;
489 	struct stat stat_buf;
490 	const char *peer_cert_dir=NULL;
491 	const char *peer_cert_file=NULL;
492 	int n;
493 	struct tls_info *info_copy;
494 
495 	if (!*ssl_cipher_list)
496 		ssl_cipher_list=NULL;
497 
498 	if (!*dhcertfile)
499 		dhcertfile=NULL;
500 
501 	if (!*certfile)
502 		certfile=NULL;
503 
504 	s=safe_getenv(info, "TLS_TRUSTCERTS");
505 	if (s && stat(s, &stat_buf) == 0)
506 	{
507 		if (S_ISDIR(stat_buf.st_mode))
508 			peer_cert_dir=s;
509 		else
510 			peer_cert_file=s;
511 	}
512 	else if (info->peer_verify_domain)
513 	{
514 		errno=ENOENT;
515 		nonsslerror(info, "TLS_TRUSTCERTS not set");
516 		return (NULL);
517 	}
518 
519 	{
520 		static int first=1;
521 
522 		if (first)
523 		{
524 			first=0;
525 			SSL_load_error_strings();
526 			SSLeay_add_ssl_algorithms();
527 
528 			while (RAND_status() != 1)
529 			{
530 				const char *p=random128();
531 				size_t l=strlen(p);
532 
533 				RAND_add(p, l, l/16);
534 			}
535 		}
536 	}
537 
538 
539 	info_copy=malloc(sizeof(struct tls_info));
540 
541 	if (info_copy == NULL)
542 	{
543 		nonsslerror(info, "malloc");
544 		return (NULL);
545 	}
546 
547 	memcpy(info_copy, info, sizeof(*info_copy));
548 	info_copy->isserver=isserver;
549 	info_copy->certificate_verified=0;
550 
551 	if (!protocol || !*protocol)
552 		protocol="SSL23";
553 
554 	ctx=SSL_CTX_new(
555 #ifndef OPENSSL_NO_SSL2
556 		protocol && strcmp(protocol, "SSL2") == 0 ? SSLv2_method():
557 #endif
558 #ifndef OPENSSL_NO_SSL3
559 		protocol && strcmp(protocol, "SSL3") == 0 ? SSLv3_method():
560 #endif
561 		protocol && strcmp(protocol, "SSL23") == 0 ? SSLv23_method():
562 		TLSv1_method());
563 
564 	if (!ctx)
565 	{
566 		free(info_copy);
567 		nonsslerror(info, "SSL_CTX_NEW");
568 		return (0);
569 	}
570 	SSL_CTX_set_app_data(ctx, info_copy);
571 	SSL_CTX_set_options(ctx, SSL_OP_ALL);
572 
573 	if (!ssl_cipher_list)
574 		ssl_cipher_list="SSLv3:TLSv1:!SSLv2:HIGH:!LOW:!MEDIUM:!EXP:!NULL:!aNULL@STRENGTH";
575 
576 	SSL_CTX_set_cipher_list(ctx, ssl_cipher_list);
577 	SSL_CTX_set_timeout(ctx, session_timeout);
578 
579 	info_copy->tlscache=NULL;
580 	init_session_cache(info_copy, ctx);
581 
582 
583 	s = safe_getenv(info, "TCPLOCALIP");
584 
585 	if (certfile && !process_certfile(ctx, certfile, s,
586 					  process_rsacertfile))
587 	{
588 		tls_destroy(ctx);
589 		return (NULL);
590 	}
591 
592 	if (dhcertfile && !process_certfile(ctx, dhcertfile, s,
593 					    process_dhcertfile))
594 	{
595 		tls_destroy(ctx);
596 		return (NULL);
597 	}
598 
599 	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
600 
601 	n=atoi(safe_getenv(info, "TLS_INTCACHESIZE"));
602 
603 	if (n > 0)
604 		SSL_CTX_sess_set_cache_size(ctx, n);
605 
606 	if (peer_cert_dir || peer_cert_file)
607 	{
608 		if ((!SSL_CTX_set_default_verify_paths(ctx))
609 			|| (!SSL_CTX_load_verify_locations(ctx, peer_cert_file,
610 				peer_cert_dir)))
611 		{
612 			sslerror(info, peer_cert_file ?
613 				 peer_cert_file:peer_cert_dir, -1);
614 			tls_destroy(ctx);
615 			return (0);
616 		}
617 
618 		if (isserver && peer_cert_file)
619 		{
620 			SSL_CTX_set_client_CA_list(ctx,
621 						   SSL_load_client_CA_file
622 						   (peer_cert_file));
623 		}
624 
625 		if (isserver && peer_cert_dir)
626 		{
627 			DIR *dirp;
628 			struct dirent *de;
629 			X509 *x;
630 
631 			dirp=opendir(peer_cert_dir);
632 			while (dirp && (de=readdir(dirp)) != NULL)
633 			{
634 				const char *p;
635 				char *q;
636 				FILE *fp;
637 
638 				p=strrchr(de->d_name, '.');
639 				if (!p || !p[1])
640 					continue;
641 				while (*++p)
642 				{
643 					if (strchr("0123456789", *p) == NULL)
644 						break;
645 				}
646 				if (*p)
647 					continue;
648 
649 				q=malloc(strlen(peer_cert_dir)
650 					 +strlen(de->d_name) + 4);
651 				if (!q)
652 				{
653 					nonsslerror(info, "malloc");
654 					exit(1);
655 				}
656 
657 				strcat(strcat(strcpy(q, peer_cert_dir),
658 					      "/"), de->d_name);
659 
660 				fp=fopen(q, "r");
661 				if (!fp)
662 				{
663 					nonsslerror(info, q);
664 					exit(1);
665 				}
666 				free(q);
667 
668 				while ((x=PEM_read_X509(fp, NULL, NULL, NULL)))
669 				{
670 					SSL_CTX_add_client_CA(ctx,x);
671 					X509_free(x);
672 				}
673 				fclose(fp);
674 			}
675 			if (dirp)
676 				closedir(dirp);
677                 }
678 	}
679 	SSL_CTX_set_verify(ctx, get_peer_verify_level(info),
680 			   ssl_verify_callback);
681 	if (!isserver)
682 		SSL_CTX_set_client_cert_cb(ctx, client_cert_cb);
683 	return (ctx);
684 }
685 
tls_destroy(SSL_CTX * ctx)686 void tls_destroy(SSL_CTX *ctx)
687 {
688 	struct tls_info *info=SSL_CTX_get_app_data(ctx);
689 
690 	SSL_CTX_flush_sessions(ctx, 0); /* OpenSSL bug, 2002-08-07 */
691 
692 	SSL_CTX_free(ctx);
693 
694 	if (info->tlscache)
695 	{
696 		tls_cache_close(info->tlscache);
697 		info->tlscache=NULL;
698 	}
699 	free(info);
700 }
701 
702 static int cache_add(SSL *ssl, SSL_SESSION *sess);
703 
704 static SSL_SESSION *cache_get(SSL *ssl, unsigned char *id, int id_len,
705 			      int *copyflag);
706 static void cache_del(SSL_CTX *ctx, SSL_SESSION *ssl);
707 
init_session_cache(struct tls_info * info,SSL_CTX * ctx)708 static void init_session_cache(struct tls_info *info, SSL_CTX *ctx)
709 {
710 	const char *filename=safe_getenv(info, "TLS_CACHEFILE");
711 	const char *cachesize=safe_getenv(info, "TLS_CACHESIZE");
712 	off_t cachesize_l;
713 
714 	if (!filename || !*filename)
715 	{
716 		SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
717 		return;
718 	}
719 
720 	if (info->tlscache == NULL)
721 	{
722 		cachesize_l= cachesize ? (off_t)atol(cachesize):0;
723 
724 		if (cachesize_l <= 0)
725 			cachesize_l=512L * 1024;
726 		if ((info->tlscache=tls_cache_open(filename, cachesize_l))
727 		    == NULL)
728 		{
729 			nonsslerror(info, filename);
730 			return;
731 		}
732 	}
733 
734         SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
735 	SSL_CTX_sess_set_new_cb(ctx, cache_add);
736 	SSL_CTX_sess_set_get_cb(ctx, cache_get);
737 	SSL_CTX_sess_set_remove_cb(ctx, cache_del);
738 }
739 
cache_add(SSL * ssl,SSL_SESSION * sess)740 static int cache_add(SSL *ssl, SSL_SESSION *sess)
741 {
742 	struct tls_info *info=SSL_get_app_data(ssl);
743 	unsigned char buffer[BUFSIZ];
744 	unsigned char *ucp;
745 	time_t timeout= (time_t)SSL_SESSION_get_time(sess)
746 		+ SSL_SESSION_get_timeout(sess);
747 	void *session_id=(void *)sess->session_id;
748 	size_t session_id_len=sess->session_id_length;
749 	size_t sess_len=i2d_SSL_SESSION(sess, NULL);
750 
751 	if (sizeof(timeout) + sizeof(session_id_len) + session_id_len +
752 	    sess_len > sizeof(buffer))
753 	{
754 		fprintf(stderr, "WARN: starttls.c: buffer not big enough to cache SSL_SESSION\n");
755 		return (0);	/* Too big */
756 	}
757 
758 	memcpy(buffer, &timeout, sizeof(timeout));
759 	memcpy(buffer+sizeof(timeout), &session_id_len,
760 	       sizeof(session_id_len));
761 	memcpy(buffer+sizeof(timeout)+sizeof(session_id_len),
762 	       session_id, session_id_len);
763 	ucp=buffer+sizeof(timeout)+
764 		sizeof(session_id_len)+session_id_len;
765 
766 	i2d_SSL_SESSION(sess, &ucp);
767 	if (tls_cache_add(info->tlscache, (char *)buffer,
768 			  (size_t)(sizeof(timeout) +
769 				   sizeof(session_id_len) +
770 				   session_id_len + sess_len)))
771 		perror("ALERT: tls_cache_add: ");
772 
773 #ifdef TLSCACHEDEBUG
774 	fprintf(stderr, "INFO: TLSCACHE: added\n");
775 #endif
776 	return 0;
777 }
778 
779 struct walk_info {
780 	unsigned char *id;
781 	int id_len;
782 	int *copyflag;
783 	SSL_SESSION *ret;
784 	time_t now;
785 };
786 
787 static int get_func(void *rec, size_t recsize,
788 		    int *doupdate, void *arg);
789 
cache_get(SSL * ssl,unsigned char * id,int id_len,int * copyflag)790 static SSL_SESSION *cache_get(SSL *ssl, unsigned char *id, int id_len,
791 			      int *copyflag)
792 {
793 	const struct tls_info *info=SSL_get_app_data(ssl);
794 	struct walk_info wi;
795 
796 	wi.id=id;
797 	wi.id_len=id_len;
798 	wi.copyflag=copyflag;
799 	wi.ret=NULL;
800 	time(&wi.now);
801 	if (tls_cache_walk(info->tlscache, get_func, &wi) < 0)
802 		perror("ALERT: tls_cache_walk: ");
803 
804 #ifdef TLSCACHEDEBUG
805 	fprintf(stderr, "INFO: TLSCACHE: session %s\n",
806 		wi.ret ? "found":"not found");
807 #endif
808 	if (wi.ret)
809 		SSL_set_session_id_context(ssl, id, id_len);
810 	return wi.ret;
811 }
812 
get_func(void * rec,size_t recsize,int * doupdate,void * arg)813 static int get_func(void *rec, size_t recsize,
814 		    int *doupdate, void *arg)
815 {
816 	unsigned char *recp=(unsigned char *)rec;
817 	struct walk_info *wi=(struct walk_info *)arg;
818 	time_t timeout;
819 	size_t session_id_len;
820 
821 	unsigned char *sess;
822 
823 	if (recsize < sizeof(timeout)+sizeof(session_id_len))
824 		return (0);
825 
826 	memcpy(&timeout, recp, sizeof(timeout));
827 
828 	if (timeout <= wi->now)
829 		return (0);
830 
831 	memcpy(&session_id_len, recp + sizeof(timeout),
832 	       sizeof(session_id_len));
833 
834 	if (session_id_len != (size_t)wi->id_len ||
835 	    memcmp(recp + sizeof(timeout) + sizeof(session_id_len),
836 		   wi->id, session_id_len))
837 		return (0);
838 
839 	sess=recp + sizeof(timeout) + sizeof(session_id_len) + session_id_len;
840 
841 	wi->ret=d2i_SSL_SESSION(NULL, (const unsigned char **)
842 				&sess, recsize - sizeof(timeout) -
843 				sizeof(session_id_len) - session_id_len);
844 
845 	*wi->copyflag=0;
846 	return 1;
847 }
848 
849 static int del_func(void *rec, size_t recsize,
850 		    int *doupdate, void *arg);
851 
cache_del(SSL_CTX * ctx,SSL_SESSION * sess)852 static void cache_del(SSL_CTX *ctx, SSL_SESSION *sess)
853 {
854 	const struct tls_info *info=SSL_CTX_get_app_data(ctx);
855 	struct walk_info wi;
856 
857 	wi.now=0;
858 
859 	wi.id=(unsigned char *)sess->session_id;
860 	wi.id_len=sess->session_id_length;
861 	if (tls_cache_walk(info->tlscache, del_func, &wi) < 0)
862 		perror("ALERT: tls_cache_walk: ");
863 }
864 
del_func(void * rec,size_t recsize,int * doupdate,void * arg)865 static int del_func(void *rec, size_t recsize,
866 		    int *doupdate, void *arg)
867 {
868 	unsigned char *recp=(unsigned char *)rec;
869 	struct walk_info *wi=(struct walk_info *)arg;
870 	time_t timeout;
871 	size_t session_id_len;
872 
873 	if (recsize < sizeof(timeout)+sizeof(session_id_len))
874 		return (0);
875 
876 	memcpy(&timeout, recp, sizeof(timeout));
877 
878 	if (timeout <= wi->now)
879 		return (0);
880 
881 	memcpy(&session_id_len, recp + sizeof(timeout),
882 	       sizeof(session_id_len));
883 
884 	if (session_id_len != (size_t)wi->id_len ||
885 	    memcmp(recp + sizeof(timeout) + sizeof(session_id_len),
886 		   wi->id, session_id_len))
887 		return (0);
888 
889 	timeout=0;
890 	memcpy(recp, &timeout, sizeof(timeout));
891 	*doupdate=1;
892 #ifdef TLSCACHEDEBUG
893 	fprintf(stderr, "INFO: TLSCACHE: deleted\n");
894 #endif
895 	return (1);
896 }
897 
898 
899 /* ----------------------------------------------------------------- */
900 
tls_connect(SSL_CTX * ctx,int fd)901 SSL *tls_connect(SSL_CTX *ctx, int fd)
902 {
903 	struct tls_info *info=SSL_CTX_get_app_data(ctx);
904 	SSL *ssl;
905 	int rc;
906 
907 	/*
908 	**  Initialize a tls_transfer_info object.
909 	*/
910 
911 	if (fcntl(fd, F_SETFL, O_NONBLOCK))
912 	{
913 		nonsslerror(info, "fcntl");
914 		return (NULL);
915 	}
916 
917 #ifdef  SO_KEEPALIVE
918 
919 	{
920 	int	dummy;
921 
922 		dummy=1;
923 
924 		if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
925 			(const char *)&dummy, sizeof(dummy)) < 0)
926                 {
927                         nonsslerror(info, "setsockopt");
928 			return (NULL);
929                 }
930 	}
931 #endif
932 
933 #ifdef  SO_LINGER
934 	{
935 	struct linger l;
936 
937 		l.l_onoff=0;
938 		l.l_linger=0;
939 
940 		if (setsockopt(fd, SOL_SOCKET, SO_LINGER,
941 			(const char *)&l, sizeof(l)) < 0)
942 		{
943 			nonsslerror(info, "setsockopt");
944 			return (NULL);
945 		}
946 	}
947 #endif
948 
949 	if (!(ssl=SSL_new(ctx)))
950 	{
951 		sslerror(info, "SSL_new", -1);
952 		return (NULL);
953 	}
954 
955 	SSL_set_app_data(ssl, info);
956 
957 	SSL_set_fd(ssl, fd);
958 	info->accept_interrupted=0;
959 	info->connect_interrupted=0;
960 
961 	if (info->isserver)
962 	{
963 		SSL_set_accept_state(ssl);
964 		if ((rc=SSL_accept(ssl)) > 0)
965 		{
966 			if (!verifypeer(info, ssl))
967 			{
968 				tls_disconnect(ssl, fd);
969 				return (NULL);
970 			}
971 
972 			if (info->connect_callback != NULL &&
973 			    !(*info->connect_callback)(ssl, info->app_data))
974 			{
975 				tls_disconnect(ssl, fd);
976 				return (NULL);
977 			}
978 
979 			return ssl;
980 		}
981 		info->accept_interrupted=1;
982 	}
983 	else
984 	{
985 		SSL_set_connect_state(ssl);
986 
987 		if ((rc=SSL_connect(ssl)) > 0)
988 		{
989 			if (!verifypeer(info, ssl))
990 			{
991 				tls_disconnect(ssl, fd);
992 				return (NULL);
993 			}
994 
995 			if (info->connect_callback != NULL &&
996 			    !(*info->connect_callback)(ssl, info->app_data))
997 			{
998 				tls_disconnect(ssl, fd);
999 				return (NULL);
1000 			}
1001 			return (ssl);
1002 		}
1003 		info->connect_interrupted=1;
1004 	}
1005 
1006 	switch (SSL_get_error(ssl, rc))	{
1007 	case SSL_ERROR_WANT_WRITE:
1008 	case SSL_ERROR_WANT_READ:
1009 		break;
1010 	default:
1011 		sslerror(info, "connect", rc);
1012 		tls_disconnect(ssl, fd);
1013 		return NULL;
1014 	}
1015 
1016 	return (ssl);
1017 }
1018 
tls_disconnect(SSL * ssl,int fd)1019 void tls_disconnect(SSL *ssl, int fd)
1020 {
1021 	fcntl(fd, F_SETFL, 0);
1022 	SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
1023 	SSL_free(ssl);
1024 	ERR_remove_state(0);
1025 }
1026 
1027 /* --------------------------------------- */
1028 
tls_transfer(struct tls_transfer_info * t,SSL * ssl,int fd,fd_set * r,fd_set * w)1029 int	tls_transfer(struct tls_transfer_info *t, SSL *ssl, int fd,
1030 		     fd_set *r, fd_set *w)
1031 {
1032 	struct tls_info *info=SSL_get_app_data(ssl);
1033 	int n;
1034 
1035 	if (info->connect_interrupted)
1036 	{
1037 		n=SSL_connect(ssl);
1038 
1039 		switch (SSL_get_error(ssl, n))	{
1040 		case SSL_ERROR_NONE:
1041 			info->connect_interrupted=0;
1042 			break;
1043 		case SSL_ERROR_WANT_WRITE:
1044 			FD_SET(fd, w);
1045 			return (1);
1046 		case SSL_ERROR_WANT_READ:
1047 			FD_SET(fd, r);
1048 			return (1);
1049 		default:
1050 			info->connect_interrupted=0;
1051 			t->shutdown=1;
1052 			sslerror(info, "connect", n);
1053 			return (-1);
1054 		}
1055 
1056 		if (!verifypeer(info, ssl))
1057 		{
1058 			info->connect_interrupted=0;
1059 			t->shutdown=1;
1060 			return (-1);
1061 		}
1062 		if (info->connect_callback != NULL &&
1063 		    !(*info->connect_callback)(ssl, info->app_data))
1064 		{
1065 			info->connect_interrupted=0;
1066 			t->shutdown=1;
1067 			return (-1);
1068 		}
1069 	}
1070 	else if (info->accept_interrupted)
1071 	{
1072 		n=SSL_accept(ssl);
1073 
1074 		switch (SSL_get_error(ssl, n))	{
1075 		case SSL_ERROR_NONE:
1076 			info->accept_interrupted=0;
1077 			break;
1078 		case SSL_ERROR_WANT_WRITE:
1079 			FD_SET(fd, w);
1080 			return (1);
1081 		case SSL_ERROR_WANT_READ:
1082 			FD_SET(fd, r);
1083 			return (1);
1084 		default:
1085 			info->accept_interrupted=0;
1086 			t->shutdown=1;
1087 			sslerror(info, "accept", n);
1088 			return (-1);
1089 		}
1090 
1091 		if (!verifypeer(info, ssl))
1092 		{
1093 			info->accept_interrupted=0;
1094 			t->shutdown=1;
1095 			return (-1);
1096 		}
1097 
1098 		if (info->connect_callback != NULL &&
1099 		    !(*info->connect_callback)(ssl, info->app_data))
1100 		{
1101 			info->accept_interrupted=0;
1102 			t->shutdown=1;
1103 			return (-1);
1104 		}
1105 	}
1106 
1107 	if (t->shutdown)
1108 		return -1;
1109 
1110 	if (t->shutdown_interrupted && !t->read_interrupted &&
1111 	    !t->write_interrupted)
1112 	{
1113 		n=SSL_shutdown(ssl);
1114 		if (n > 0)
1115 		{
1116 			t->shutdown_interrupted=0;
1117 			t->shutdown=1;
1118 			return -1;
1119 		}
1120 
1121 		switch (SSL_get_error(ssl, n))	{
1122 		case SSL_ERROR_WANT_WRITE:
1123 			FD_SET(fd, w);
1124 			break;
1125 		case SSL_ERROR_WANT_READ:
1126 			FD_SET(fd, r);
1127 			break;
1128 		default:
1129 			t->shutdown_interrupted=0;
1130 			t->shutdown= -1;
1131 			return -1;
1132 		}
1133 		return 1;
1134 	}
1135 
1136 	if (!t->write_interrupted && t->readleft > 0)
1137 	{
1138 		n=SSL_read(ssl, t->readptr, t->readleft);
1139 
1140 		switch (SSL_get_error(ssl, n))	{
1141 		case SSL_ERROR_NONE:
1142 			break;
1143 		case SSL_ERROR_WANT_WRITE:
1144 			t->read_interrupted=1;
1145 			FD_SET(fd, w);
1146 			return (1);
1147 		case SSL_ERROR_WANT_READ:
1148 			FD_SET(fd, r);
1149 			n=0;
1150 			break;
1151 		case SSL_ERROR_WANT_X509_LOOKUP:
1152 			n=0;
1153 			break;
1154 		case SSL_ERROR_ZERO_RETURN:
1155 			t->shutdown=1;
1156 			return (-1);
1157 		default:
1158 			sslerror(info, "read", n);
1159 			return (-1);
1160 		}
1161 		t->read_interrupted=0;
1162 		t->readptr += n;
1163 		t->readleft -= n;
1164 
1165 		if (n > 0)
1166 			return (0);
1167 	}
1168 
1169 	if (!t->read_interrupted && t->writeleft > 0)
1170 	{
1171 		n=SSL_write(ssl, t->writeptr, t->writeleft);
1172 
1173 		switch (SSL_get_error(ssl, n))	{
1174 		case SSL_ERROR_NONE:
1175 			break;
1176 		case SSL_ERROR_WANT_WRITE:
1177 			FD_SET(fd, w);
1178 			n=0;
1179 			break;
1180 		case SSL_ERROR_WANT_READ:
1181 			t->write_interrupted=1;
1182 			FD_SET(fd, r);
1183 			return (1);
1184 		case SSL_ERROR_ZERO_RETURN:
1185 			t->shutdown=1;
1186 			return (-1);
1187 		case SSL_ERROR_WANT_X509_LOOKUP:
1188 			n=0;
1189 			break;
1190 		default:
1191 			return (-1);
1192 		}
1193 		t->write_interrupted=0;
1194 		t->writeptr += n;
1195 		t->writeleft -= n;
1196 
1197 		if (n > 0)
1198 			return (0);
1199 	}
1200 
1201 	return (1);
1202 }
1203 
tls_connecting(SSL * ssl)1204 int tls_connecting(SSL *ssl)
1205 {
1206 	struct tls_info *info=(struct tls_info *)SSL_get_app_data(ssl);
1207 
1208 	return info->accept_interrupted || info->connect_interrupted;
1209 }
1210 
tls_certificate_verified(ssl_handle ssl)1211 int tls_certificate_verified(ssl_handle ssl)
1212 {
1213 	struct tls_info *info=(struct tls_info *)SSL_get_app_data(ssl);
1214 
1215 	return info->certificate_verified;
1216 }
1217 
1218 #define MAXDOMAINSIZE	256
1219 
asn1toTime(ASN1_TIME * asn1Time)1220 static time_t asn1toTime(ASN1_TIME *asn1Time)
1221 {
1222 	struct tm tm;
1223 	int offset;
1224 
1225 	if (asn1Time == NULL || asn1Time->length < 13)
1226 		return 0;
1227 
1228 	memset(&tm, 0, sizeof(tm));
1229 
1230 #define N2(n)	((asn1Time->data[n]-'0')*10 + asn1Time->data[(n)+1]-'0')
1231 
1232 #define CPY(f,n) (tm.f=N2(n))
1233 
1234 	CPY(tm_year,0);
1235 
1236 	if(tm.tm_year < 50)
1237 		tm.tm_year += 100; /* Sux */
1238 
1239 	CPY(tm_mon, 2);
1240 	--tm.tm_mon;
1241 	CPY(tm_mday, 4);
1242 	CPY(tm_hour, 6);
1243 	CPY(tm_min, 8);
1244 	CPY(tm_sec, 10);
1245 
1246 	offset=0;
1247 
1248 	if (asn1Time->data[12] != 'Z')
1249 	{
1250 		if (asn1Time->length < 17)
1251 			return 0;
1252 
1253 		offset=N2(13)*3600+N2(15)*60;
1254 
1255 		if (asn1Time->data[12] == '-')
1256 			offset= -offset;
1257 	}
1258 
1259 #undef N2
1260 #undef CPY
1261 
1262 	return mktime(&tm)-offset;
1263 }
1264 
1265 
dump_x509(X509 * x509,void (* dump_func)(const char *,int cnt,void *),void * dump_arg)1266 static void dump_x509(X509 *x509,
1267 		      void (*dump_func)(const char *, int cnt, void *),
1268 		      void *dump_arg)
1269 {
1270 	X509_NAME *subj=X509_get_subject_name(x509);
1271 	int nentries, j;
1272 	time_t timestamp;
1273 	static const char gcc_shutup[]="%Y-%m-%d %H:%M:%S";
1274 
1275 	if (!subj)
1276 		return;
1277 
1278 	(*dump_func)("Subject:\n", -1, dump_arg);
1279 
1280 	nentries=X509_NAME_entry_count(subj);
1281 	for (j=0; j<nentries; j++)
1282 	{
1283 		const char *obj_name;
1284 		X509_NAME_ENTRY *e;
1285 		ASN1_OBJECT *o;
1286 		ASN1_STRING *d;
1287 
1288 		int dlen;
1289 		unsigned char *ddata;
1290 
1291 		e=X509_NAME_get_entry(subj, j);
1292 		if (!e)
1293 			continue;
1294 
1295 		o=X509_NAME_ENTRY_get_object(e);
1296 		d=X509_NAME_ENTRY_get_data(e);
1297 
1298 		if (!o || !d)
1299 			continue;
1300 
1301 		obj_name=OBJ_nid2sn(OBJ_obj2nid(o));
1302 
1303 		dlen=ASN1_STRING_length(d);
1304 		ddata=ASN1_STRING_data(d);
1305 
1306 		(*dump_func)("   ", -1, dump_arg);
1307 		(*dump_func)(obj_name, -1, dump_arg);
1308 		(*dump_func)("=", 1, dump_arg);
1309 		(*dump_func)((const char *)ddata, dlen, dump_arg);
1310 		(*dump_func)("\n", 1, dump_arg);
1311 
1312 	}
1313 	(*dump_func)("\n", 1, dump_arg);
1314 
1315 	timestamp=asn1toTime(X509_get_notBefore(x509));
1316 
1317 	if (timestamp)
1318 	{
1319 		struct tm *tm=localtime(&timestamp);
1320 		char buffer[500];
1321 
1322 		buffer[strftime(buffer, sizeof(buffer)-1, gcc_shutup,
1323 				tm)]=0;
1324 
1325 		(*dump_func)("Not-Before: ", -1, dump_arg);
1326 		(*dump_func)(buffer, -1, dump_arg);
1327 		(*dump_func)("\n", 1, dump_arg);
1328 	}
1329 
1330 	timestamp=asn1toTime(X509_get_notAfter(x509));
1331 	if (timestamp)
1332 	{
1333 		struct tm *tm=localtime(&timestamp);
1334 		char buffer[500];
1335 
1336 		buffer[strftime(buffer, sizeof(buffer)-1, gcc_shutup,
1337 				tm)]=0;
1338 
1339 		(*dump_func)("Not-After: ", -1, dump_arg);
1340 		(*dump_func)(buffer, -1, dump_arg);
1341 		(*dump_func)("\n", 1, dump_arg);
1342 	}
1343 }
1344 
tls_dump_connection_info(ssl_handle ssl,int server,void (* dump_func)(const char *,int cnt,void *),void * dump_arg)1345 void tls_dump_connection_info(ssl_handle ssl,
1346 			      int server,
1347 			      void (*dump_func)(const char *, int cnt, void *),
1348 			      void *dump_arg)
1349 {
1350 	const SSL_CIPHER *cipher;
1351 
1352 	{
1353 		STACK_OF(X509) *peer_cert_chain=SSL_get_peer_cert_chain(ssl);
1354 		int i;
1355 
1356 		if (server)
1357 		{
1358 			X509 *x=SSL_get_peer_certificate(ssl);
1359 
1360 			if (x)
1361 			{
1362 				dump_x509(x, dump_func, dump_arg);
1363 				X509_free(x);
1364 			}
1365 		}
1366 
1367 		for (i=0; peer_cert_chain && i<peer_cert_chain->stack.num; i++)
1368 			dump_x509((X509 *)peer_cert_chain->stack.data[i],
1369 				  dump_func, dump_arg);
1370 	}
1371 
1372 	cipher=SSL_get_current_cipher(ssl);
1373 
1374 	if (cipher)
1375 	{
1376 		const char *c;
1377 
1378 		c=SSL_CIPHER_get_version(cipher);
1379 		if (c)
1380 		{
1381 			(*dump_func)("Version: ", -1, dump_arg);
1382 			(*dump_func)(c, -1, dump_arg);
1383 			(*dump_func)("\n", 1, dump_arg);
1384 		}
1385 
1386 		{
1387 			char buf[10];
1388 
1389 			(*dump_func)("Bits: ", -1, dump_arg);
1390 
1391 			snprintf(buf, sizeof(buf), "%d",
1392 				 SSL_CIPHER_get_bits(cipher, NULL));
1393 			buf[sizeof(buf)-1]=0;
1394 
1395 			(*dump_func)(buf, -1, dump_arg);
1396 			(*dump_func)("\n", 1, dump_arg);
1397 		}
1398 
1399 		c=SSL_CIPHER_get_name(cipher);
1400 
1401 		if (c)
1402 		{
1403 			(*dump_func)("Cipher: ", -1, dump_arg);
1404 			(*dump_func)(c, -1, dump_arg);
1405 			(*dump_func)("\n", 1, dump_arg);
1406 		}
1407 	}
1408 }
1409 
tls_get_encryption_desc(ssl_handle ssl)1410 char *tls_get_encryption_desc(ssl_handle ssl)
1411 {
1412 	char protocolbuf[256];
1413 	const SSL_CIPHER *cipher;
1414 	const char *c, *d;
1415 
1416 	cipher=SSL_get_current_cipher(ssl);
1417 
1418 	c=cipher ? SSL_CIPHER_get_version(cipher):NULL;
1419 	d=cipher ? SSL_CIPHER_get_name(cipher):NULL;
1420 
1421 	snprintf(protocolbuf, sizeof(protocolbuf),
1422 		 "%s,%dbits,%s",
1423 		 c ? c:"unknown",
1424 		 cipher ? SSL_CIPHER_get_bits(cipher, NULL):0,
1425 		 d ? d:"unknown");
1426 	protocolbuf[sizeof(protocolbuf)-1]=0;
1427 	return strdup(protocolbuf);
1428 }
1429 
1430 
1431 /* ------------------- */
1432 
tls_validate_pem_cert(const char * buf,size_t buf_size)1433 int tls_validate_pem_cert(const char *buf, size_t buf_size)
1434 {
1435 	int rc;
1436 	BIO *certbio;
1437 	int err;
1438 	EVP_PKEY *pk;
1439 	X509 *x;
1440 
1441 	ERR_clear_error();
1442 
1443 	rc=0;
1444 	certbio=BIO_new_mem_buf((void *)buf, buf_size);
1445 
1446 	if (!certbio)
1447 		return (0);
1448 
1449 	x=PEM_read_bio_X509(certbio, NULL, NULL, NULL);
1450 
1451 	if (x)
1452 	{
1453 		X509_free(x);
1454 
1455 		while ((x=PEM_read_bio_X509(certbio, NULL, NULL, NULL)) != NULL)
1456 			X509_free(x);
1457 
1458 		err = ERR_peek_last_error();
1459                 if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
1460 		    ERR_GET_REASON(err) == PEM_R_NO_START_LINE)
1461 		{
1462 			rc=1;
1463 		}
1464 	}
1465 
1466 	ERR_clear_error();
1467 	BIO_free(certbio);
1468 
1469 	certbio=BIO_new_mem_buf((void *)buf, buf_size);
1470 
1471 	if (!certbio)
1472 		return (0);
1473 
1474 	if (!(pk=PEM_read_bio_PrivateKey(certbio, NULL, NULL, NULL)))
1475 	{
1476 		BIO_free(certbio);
1477 		ERR_clear_error();
1478 		return 0;
1479 	}
1480 
1481 	EVP_PKEY_free(pk);
1482 	return rc;
1483 }
1484 
conv_name_to_rfc2553(const char * p,char * q)1485 static size_t conv_name_to_rfc2553(const char *p, char *q)
1486 {
1487 #define PUTC(c) if (q) *q++=(c); ++n
1488 
1489 	size_t n=0;
1490 	const char *sep="";
1491 
1492 	while (*p)
1493 	{
1494 		if (*p == '/')
1495 		{
1496 			++p;
1497 			continue;
1498 		}
1499 
1500 		while (*sep)
1501 		{
1502 			PUTC(*sep);
1503 			++sep;
1504 		}
1505 		sep=",";
1506 
1507 		while (*p && *p != '/')
1508 		{
1509 			if (*p == '\\' && p[1])
1510 				++p;
1511 			if (*p == '\\' || *p == ',')
1512 			{
1513 				PUTC('\\');
1514 			}
1515 			PUTC(*p);
1516 			++p;
1517 		}
1518 	}
1519 	PUTC(0);
1520 #undef PUTC
1521 
1522 	return n;
1523 }
1524 
tls_cert_name(const char * buf,size_t buf_size)1525 char *tls_cert_name(const char *buf, size_t buf_size)
1526 {
1527 	int rc;
1528 	BIO *certbio;
1529 	char *p, *q;
1530 	X509 *x;
1531 	size_t cnt;
1532 
1533 	rc=0;
1534 	certbio=BIO_new_mem_buf((void *)buf, buf_size);
1535 
1536 	if (!certbio)
1537 	{
1538 		ERR_clear_error();
1539 		return (0);
1540 	}
1541 
1542 	x=PEM_read_bio_X509(certbio, NULL, NULL, NULL);
1543 	p=0;
1544 	q=0;
1545 
1546 	if (x)
1547 	{
1548 		p=X509_NAME_oneline(x->cert_info->subject, NULL, 0);
1549 		X509_free(x);
1550 	}
1551 	ERR_clear_error();
1552 	BIO_free(certbio);
1553 
1554 	if (p)
1555 	{
1556 		cnt=conv_name_to_rfc2553(p, NULL);
1557 
1558 		q=malloc(cnt);
1559 
1560 		if (q)
1561 			conv_name_to_rfc2553(p, q);
1562 		free(p);
1563 	}
1564 
1565 	return q;
1566 }
1567