xref: /freebsd/contrib/sendmail/src/tls.c (revision 2ef40764f06885f97d380ee8de0ced64930423db)
1 /*
2  * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers.
3  *	All rights reserved.
4  *
5  * By using this file, you agree to the terms and conditions set
6  * forth in the LICENSE file which can be found at the top level of
7  * the sendmail distribution.
8  *
9  */
10 
11 #include <sendmail.h>
12 
13 SM_RCSID("@(#)$Id: tls.c,v 8.79.4.1 2002/09/03 17:31:45 gshapiro Exp $")
14 
15 #if STARTTLS
16 #  include <openssl/err.h>
17 #  include <openssl/bio.h>
18 #  include <openssl/pem.h>
19 #  ifndef HASURANDOMDEV
20 #   include <openssl/rand.h>
21 #  endif /* ! HASURANDOMDEV */
22 #  if SM_CONF_SHM
23 #   include <sm/shm.h>
24 #  endif /* SM_CONF_SHM */
25 # if !TLS_NO_RSA
26 static RSA *rsa_tmp = NULL;	/* temporary RSA key */
27 static RSA *tmp_rsa_key __P((SSL *, int, int));
28 # endif /* !TLS_NO_RSA */
29 #  if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
30 static int	tls_verify_cb __P((X509_STORE_CTX *));
31 #  else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
32 static int	tls_verify_cb __P((X509_STORE_CTX *, void *));
33 #  endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
34 
35 # if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
36 #  define CONST097
37 # else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
38 #  define CONST097 const
39 # endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
40 static void	apps_ssl_info_cb __P((CONST097 SSL *, int , int));
41 
42 # if !NO_DH
43 static DH *get_dh512 __P((void));
44 
45 static unsigned char dh512_p[] =
46 {
47 	0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75,
48 	0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F,
49 	0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3,
50 	0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12,
51 	0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C,
52 	0x47,0x74,0xE8,0x33
53 };
54 static unsigned char dh512_g[] =
55 {
56 	0x02
57 };
58 
59 static DH *
60 get_dh512()
61 {
62 	DH *dh = NULL;
63 
64 	if ((dh = DH_new()) == NULL)
65 		return NULL;
66 	dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
67 	dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
68 	if ((dh->p == NULL) || (dh->g == NULL))
69 		return NULL;
70 	return dh;
71 }
72 # endif /* !NO_DH */
73 
74 
75 /*
76 **  TLS_RAND_INIT -- initialize STARTTLS random generator
77 **
78 **	Parameters:
79 **		randfile -- name of file with random data
80 **		logl -- loglevel
81 **
82 **	Returns:
83 **		success/failure
84 **
85 **	Side Effects:
86 **		initializes PRNG for tls library.
87 */
88 
89 # define MIN_RAND_BYTES	128	/* 1024 bits */
90 
91 # define RF_OK		0	/* randfile OK */
92 # define RF_MISS	1	/* randfile == NULL || *randfile == '\0' */
93 # define RF_UNKNOWN	2	/* unknown prefix for randfile */
94 
95 # define RI_NONE	0	/* no init yet */
96 # define RI_SUCCESS	1	/* init was successful */
97 # define RI_FAIL	2	/* init failed */
98 
99 static bool	tls_rand_init __P((char *, int));
100 
101 static bool
102 tls_rand_init(randfile, logl)
103 	char *randfile;
104 	int logl;
105 {
106 # ifndef HASURANDOMDEV
107 	/* not required if /dev/urandom exists, OpenSSL does it internally */
108 
109 	bool ok;
110 	int randdef;
111 	static int done = RI_NONE;
112 
113 	/*
114 	**  initialize PRNG
115 	*/
116 
117 	/* did we try this before? if yes: return old value */
118 	if (done != RI_NONE)
119 		return done == RI_SUCCESS;
120 
121 	/* set default values */
122 	ok = false;
123 	done = RI_FAIL;
124 	randdef = (randfile == NULL || *randfile == '\0') ? RF_MISS : RF_OK;
125 #   if EGD
126 	if (randdef == RF_OK && sm_strncasecmp(randfile, "egd:", 4) == 0)
127 	{
128 		randfile += 4;
129 		if (RAND_egd(randfile) < 0)
130 		{
131 			sm_syslog(LOG_WARNING, NOQID,
132 				  "STARTTLS: RAND_egd(%s) failed: random number generator not seeded",
133 				   randfile);
134 		}
135 		else
136 			ok = true;
137 	}
138 	else
139 #   endif /* EGD */
140 	if (randdef == RF_OK && sm_strncasecmp(randfile, "file:", 5) == 0)
141 	{
142 		int fd;
143 		long sff;
144 		struct stat st;
145 
146 		randfile += 5;
147 		sff = SFF_SAFEDIRPATH | SFF_NOWLINK
148 		      | SFF_NOGWFILES | SFF_NOWWFILES
149 		      | SFF_NOGRFILES | SFF_NOWRFILES
150 		      | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
151 		if (DontLockReadFiles)
152 			sff |= SFF_NOLOCK;
153 		if ((fd = safeopen(randfile, O_RDONLY, 0, sff)) >= 0)
154 		{
155 			if (fstat(fd, &st) < 0)
156 			{
157 				if (LogLevel > logl)
158 					sm_syslog(LOG_ERR, NOQID,
159 						  "STARTTLS: can't fstat(%s)",
160 						  randfile);
161 			}
162 			else
163 			{
164 				bool use, problem;
165 
166 				use = true;
167 				problem = false;
168 
169 				/* max. age of file: 10 minutes */
170 				if (st.st_mtime + 600 < curtime())
171 				{
172 					use = bitnset(DBS_INSUFFICIENTENTROPY,
173 						      DontBlameSendmail);
174 					problem = true;
175 					if (LogLevel > logl)
176 						sm_syslog(LOG_ERR, NOQID,
177 							  "STARTTLS: RandFile %s too old: %s",
178 							  randfile,
179 							  use ? "unsafe" :
180 								"unusable");
181 				}
182 				if (use && st.st_size < MIN_RAND_BYTES)
183 				{
184 					use = bitnset(DBS_INSUFFICIENTENTROPY,
185 						      DontBlameSendmail);
186 					problem = true;
187 					if (LogLevel > logl)
188 						sm_syslog(LOG_ERR, NOQID,
189 							  "STARTTLS: size(%s) < %d: %s",
190 							  randfile,
191 							  MIN_RAND_BYTES,
192 							  use ? "unsafe" :
193 								"unusable");
194 				}
195 				if (use)
196 					ok = RAND_load_file(randfile, -1) >=
197 					     MIN_RAND_BYTES;
198 				if (use && !ok)
199 				{
200 					if (LogLevel > logl)
201 						sm_syslog(LOG_WARNING, NOQID,
202 							  "STARTTLS: RAND_load_file(%s) failed: random number generator not seeded",
203 							  randfile);
204 				}
205 				if (problem)
206 					ok = false;
207 			}
208 			if (ok || bitnset(DBS_INSUFFICIENTENTROPY,
209 					  DontBlameSendmail))
210 			{
211 				/* add this even if fstat() failed */
212 				RAND_seed((void *) &st, sizeof st);
213 			}
214 			(void) close(fd);
215 		}
216 		else
217 		{
218 			if (LogLevel > logl)
219 				sm_syslog(LOG_WARNING, NOQID,
220 					  "STARTTLS: Warning: safeopen(%s) failed",
221 					  randfile);
222 		}
223 	}
224 	else if (randdef == RF_OK)
225 	{
226 		if (LogLevel > logl)
227 			sm_syslog(LOG_WARNING, NOQID,
228 				  "STARTTLS: Error: no proper random file definition %s",
229 				  randfile);
230 		randdef = RF_UNKNOWN;
231 	}
232 	if (randdef == RF_MISS)
233 	{
234 		if (LogLevel > logl)
235 			sm_syslog(LOG_WARNING, NOQID,
236 				  "STARTTLS: Error: missing random file definition");
237 	}
238 	if (!ok && bitnset(DBS_INSUFFICIENTENTROPY, DontBlameSendmail))
239 	{
240 		int i;
241 		long r;
242 		unsigned char buf[MIN_RAND_BYTES];
243 
244 		/* assert((MIN_RAND_BYTES % sizeof(long)) == 0); */
245 		for (i = 0; i <= sizeof(buf) - sizeof(long); i += sizeof(long))
246 		{
247 			r = get_random();
248 			(void) memcpy(buf + i, (void *) &r, sizeof(long));
249 		}
250 		RAND_seed(buf, sizeof buf);
251 		if (LogLevel > logl)
252 			sm_syslog(LOG_WARNING, NOQID,
253 				  "STARTTLS: Warning: random number generator not properly seeded");
254 		ok = true;
255 	}
256 	done = ok ? RI_SUCCESS : RI_FAIL;
257 	return ok;
258 # else /* ! HASURANDOMDEV */
259 	return true;
260 # endif /* ! HASURANDOMDEV */
261 }
262 /*
263 **  INIT_TLS_LIBRARY -- Calls functions which setup TLS library for global use.
264 **
265 **	Parameters:
266 **		none.
267 **
268 **	Returns:
269 **		succeeded?
270 */
271 
272 bool
273 init_tls_library()
274 {
275 	/* basic TLS initialization, ignore result for now */
276 	SSL_library_init();
277 	SSL_load_error_strings();
278 # if 0
279 	/* this is currently a macro for SSL_library_init */
280 	SSLeay_add_ssl_algorithms();
281 # endif /* 0 */
282 
283 	return tls_rand_init(RandFile, 7);
284 }
285 /*
286 **  TLS_SET_VERIFY -- request client certificate?
287 **
288 **	Parameters:
289 **		ctx -- TLS context
290 **		ssl -- TLS structure
291 **		vrfy -- require certificate?
292 **
293 **	Returns:
294 **		none.
295 **
296 **	Side Effects:
297 **		Sets verification state for TLS
298 **
299 # if TLS_VRFY_PER_CTX
300 **	Notice:
301 **		This is per TLS context, not per TLS structure;
302 **		the former is global, the latter per connection.
303 **		It would be nice to do this per connection, but this
304 **		doesn't work in the current TLS libraries :-(
305 # endif * TLS_VRFY_PER_CTX *
306 */
307 
308 void
309 tls_set_verify(ctx, ssl, vrfy)
310 	SSL_CTX *ctx;
311 	SSL *ssl;
312 	bool vrfy;
313 {
314 # if !TLS_VRFY_PER_CTX
315 	SSL_set_verify(ssl, vrfy ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
316 # else /* !TLS_VRFY_PER_CTX */
317 	SSL_CTX_set_verify(ctx, vrfy ? SSL_VERIFY_PEER : SSL_VERIFY_NONE,
318 			NULL);
319 # endif /* !TLS_VRFY_PER_CTX */
320 }
321 
322 /*
323 **  status in initialization
324 **  these flags keep track of the status of the initialization
325 **  i.e., whether a file exists (_EX) and whether it can be used (_OK)
326 **  [due to permissions]
327 */
328 
329 # define TLS_S_NONE	0x00000000	/* none yet */
330 # define TLS_S_CERT_EX	0x00000001	/* cert file exists */
331 # define TLS_S_CERT_OK	0x00000002	/* cert file is ok */
332 # define TLS_S_KEY_EX	0x00000004	/* key file exists */
333 # define TLS_S_KEY_OK	0x00000008	/* key file is ok */
334 # define TLS_S_CERTP_EX	0x00000010	/* CA cert path exists */
335 # define TLS_S_CERTP_OK	0x00000020	/* CA cert path is ok */
336 # define TLS_S_CERTF_EX	0x00000040	/* CA cert file exists */
337 # define TLS_S_CERTF_OK	0x00000080	/* CA cert file is ok */
338 
339 # if _FFR_TLS_1
340 #  define TLS_S_CERT2_EX	0x00001000	/* 2nd cert file exists */
341 #  define TLS_S_CERT2_OK	0x00002000	/* 2nd cert file is ok */
342 #  define TLS_S_KEY2_EX	0x00004000	/* 2nd key file exists */
343 #  define TLS_S_KEY2_OK	0x00008000	/* 2nd key file is ok */
344 # endif /* _FFR_TLS_1 */
345 
346 # define TLS_S_DH_OK	0x00200000	/* DH cert is ok */
347 # define TLS_S_DHPAR_EX	0x00400000	/* DH param file exists */
348 # define TLS_S_DHPAR_OK	0x00800000	/* DH param file is ok to use */
349 
350 /*
351 **  TLS_OK_F -- can var be an absolute filename?
352 **
353 **	Parameters:
354 **		var -- filename
355 **		fn -- what is the filename used for?
356 **		srv -- server side?
357 **
358 **	Returns:
359 **		ok?
360 */
361 
362 static bool
363 tls_ok_f(var, fn, srv)
364 	char *var;
365 	char *fn;
366 	bool srv;
367 {
368 	/* must be absolute pathname */
369 	if (var != NULL && *var == '/')
370 		return true;
371 	if (LogLevel > 12)
372 		sm_syslog(LOG_WARNING, NOQID, "STARTTLS: %s%s missing",
373 			  srv ? "Server" : "Client", fn);
374 	return false;
375 }
376 /*
377 **  TLS_SAFE_F -- is a file safe to use?
378 **
379 **	Parameters:
380 **		var -- filename
381 **		sff -- flags for safefile()
382 **		srv -- server side?
383 **
384 **	Returns:
385 **		ok?
386 */
387 
388 static bool
389 tls_safe_f(var, sff, srv)
390 	char *var;
391 	long sff;
392 	bool srv;
393 {
394 	int ret;
395 
396 	if ((ret = safefile(var, RunAsUid, RunAsGid, RunAsUserName, sff,
397 			    S_IRUSR, NULL)) == 0)
398 		return true;
399 	if (LogLevel > 7)
400 		sm_syslog(LOG_WARNING, NOQID, "STARTTLS=%s: file %s unsafe: %s",
401 			  srv ? "server" : "client", var, sm_errstring(ret));
402 	return false;
403 }
404 
405 /*
406 **  TLS_OK_F -- macro to simplify calls to tls_ok_f
407 **
408 **	Parameters:
409 **		var -- filename
410 **		fn -- what is the filename used for?
411 **		req -- is the file required?
412 **		st -- status bit to set if ok
413 **		srv -- server side?
414 **
415 **	Side Effects:
416 **		uses r, ok; may change ok and status.
417 **
418 */
419 
420 # define TLS_OK_F(var, fn, req, st, srv) if (ok) \
421 	{ \
422 		r = tls_ok_f(var, fn, srv); \
423 		if (r) \
424 			status |= st; \
425 		else if (req) \
426 			ok = false; \
427 	}
428 
429 /*
430 **  TLS_UNR -- macro to return whether a file should be unreadable
431 **
432 **	Parameters:
433 **		bit -- flag to test
434 **		req -- flags
435 **
436 **	Returns:
437 **		0/SFF_NORFILES
438 */
439 # define TLS_UNR(bit, req)	(bitset(bit, req) ? SFF_NORFILES : 0)
440 # define TLS_OUNR(bit, req)	(bitset(bit, req) ? SFF_NOWRFILES : 0)
441 # define TLS_KEYSFF(req)	\
442 	(bitnset(DBS_GROUPREADABLEKEYFILE, DontBlameSendmail) ?	\
443 		TLS_OUNR(TLS_I_KEY_OUNR, req) :			\
444 		TLS_UNR(TLS_I_KEY_UNR, req))
445 
446 /*
447 **  TLS_SAFE_F -- macro to simplify calls to tls_safe_f
448 **
449 **	Parameters:
450 **		var -- filename
451 **		sff -- flags for safefile()
452 **		req -- is the file required?
453 **		ex -- does the file exist?
454 **		st -- status bit to set if ok
455 **		srv -- server side?
456 **
457 **	Side Effects:
458 **		uses r, ok, ex; may change ok and status.
459 **
460 */
461 
462 # define TLS_SAFE_F(var, sff, req, ex, st, srv) if (ex && ok) \
463 	{ \
464 		r = tls_safe_f(var, sff, srv); \
465 		if (r) \
466 			status |= st;	\
467 		else if (req) \
468 			ok = false;	\
469 	}
470 
471 /*
472 **  INITTLS -- initialize TLS
473 **
474 **	Parameters:
475 **		ctx -- pointer to context
476 **		req -- requirements for initialization (see sendmail.h)
477 **		srv -- server side?
478 **		certfile -- filename of certificate
479 **		keyfile -- filename of private key
480 **		cacertpath -- path to CAs
481 **		cacertfile -- file with CA(s)
482 **		dhparam -- parameters for DH
483 **
484 **	Returns:
485 **		succeeded?
486 */
487 
488 bool
489 inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
490 	SSL_CTX **ctx;
491 	unsigned long req;
492 	bool srv;
493 	char *certfile, *keyfile, *cacertpath, *cacertfile, *dhparam;
494 {
495 # if !NO_DH
496 	static DH *dh = NULL;
497 # endif /* !NO_DH */
498 	int r;
499 	bool ok;
500 	long sff, status;
501 	char *who;
502 # if _FFR_TLS_1
503 	char *cf2, *kf2;
504 # endif /* _FFR_TLS_1 */
505 #  if SM_CONF_SHM
506 	extern int ShmId;
507 #  endif /* SM_CONF_SHM */
508 
509 	status = TLS_S_NONE;
510 	who = srv ? "server" : "client";
511 	if (ctx == NULL)
512 		syserr("STARTTLS=%s, inittls: ctx == NULL", who);
513 
514 	/* already initialized? (we could re-init...) */
515 	if (*ctx != NULL)
516 		return true;
517 	ok = true;
518 
519 # if _FFR_TLS_1
520 	/*
521 	**  look for a second filename: it must be separated by a ','
522 	**  no blanks allowed (they won't be skipped).
523 	**  we change a global variable here! this change will be undone
524 	**  before return from the function but only if it returns true.
525 	**  this isn't a problem since in a failure case this function
526 	**  won't be called again with the same (overwritten) values.
527 	**  otherwise each return must be replaced with a goto endinittls.
528 	*/
529 
530 	cf2 = NULL;
531 	kf2 = NULL;
532 	if (certfile != NULL && (cf2 = strchr(certfile, ',')) != NULL)
533 	{
534 		*cf2++ = '\0';
535 		if (keyfile != NULL && (kf2 = strchr(keyfile, ',')) != NULL)
536 			*kf2++ = '\0';
537 	}
538 # endif /* _FFR_TLS_1 */
539 
540 	/*
541 	**  Check whether files/paths are defined
542 	*/
543 
544 	TLS_OK_F(certfile, "CertFile", bitset(TLS_I_CERT_EX, req),
545 		 TLS_S_CERT_EX, srv);
546 	TLS_OK_F(keyfile, "KeyFile", bitset(TLS_I_KEY_EX, req),
547 		 TLS_S_KEY_EX, srv);
548 	TLS_OK_F(cacertpath, "CACertPath", bitset(TLS_I_CERTP_EX, req),
549 		 TLS_S_CERTP_EX, srv);
550 	TLS_OK_F(cacertfile, "CACertFile", bitset(TLS_I_CERTF_EX, req),
551 		 TLS_S_CERTF_EX, srv);
552 
553 # if _FFR_TLS_1
554 	/*
555 	**  if the second file is specified it must exist
556 	**  XXX: it is possible here to define only one of those files
557 	*/
558 
559 	if (cf2 != NULL)
560 	{
561 		TLS_OK_F(cf2, "CertFile", bitset(TLS_I_CERT_EX, req),
562 			 TLS_S_CERT2_EX, srv);
563 	}
564 	if (kf2 != NULL)
565 	{
566 		TLS_OK_F(kf2, "KeyFile", bitset(TLS_I_KEY_EX, req),
567 			 TLS_S_KEY2_EX, srv);
568 	}
569 # endif /* _FFR_TLS_1 */
570 
571 	/*
572 	**  valid values for dhparam are (only the first char is checked)
573 	**  none	no parameters: don't use DH
574 	**  512		generate 512 bit parameters (fixed)
575 	**  1024	generate 1024 bit parameters
576 	**  /file/name	read parameters from /file/name
577 	**  default is: 1024 for server, 512 for client (OK? XXX)
578 	*/
579 
580 	if (bitset(TLS_I_TRY_DH, req))
581 	{
582 		if (dhparam != NULL)
583 		{
584 			char c = *dhparam;
585 
586 			if (c == '1')
587 				req |= TLS_I_DH1024;
588 			else if (c == '5')
589 				req |= TLS_I_DH512;
590 			else if (c != 'n' && c != 'N' && c != '/')
591 			{
592 				if (LogLevel > 12)
593 					sm_syslog(LOG_WARNING, NOQID,
594 						  "STARTTLS=%s, error: illegal value '%s' for DHParam",
595 						  who, dhparam);
596 				dhparam = NULL;
597 			}
598 		}
599 		if (dhparam == NULL)
600 			dhparam = srv ? "1" : "5";
601 		else if (*dhparam == '/')
602 		{
603 			TLS_OK_F(dhparam, "DHParameters",
604 				 bitset(TLS_I_DHPAR_EX, req),
605 				 TLS_S_DHPAR_EX, srv);
606 		}
607 	}
608 	if (!ok)
609 		return ok;
610 
611 	/* certfile etc. must be "safe". */
612 	sff = SFF_REGONLY | SFF_SAFEDIRPATH | SFF_NOWLINK
613 	     | SFF_NOGWFILES | SFF_NOWWFILES
614 	     | SFF_MUSTOWN | SFF_ROOTOK | SFF_OPENASROOT;
615 	if (DontLockReadFiles)
616 		sff |= SFF_NOLOCK;
617 
618 	TLS_SAFE_F(certfile, sff | TLS_UNR(TLS_I_CERT_UNR, req),
619 		   bitset(TLS_I_CERT_EX, req),
620 		   bitset(TLS_S_CERT_EX, status), TLS_S_CERT_OK, srv);
621 	TLS_SAFE_F(keyfile, sff | TLS_KEYSFF(req),
622 		   bitset(TLS_I_KEY_EX, req),
623 		   bitset(TLS_S_KEY_EX, status), TLS_S_KEY_OK, srv);
624 	TLS_SAFE_F(cacertfile, sff | TLS_UNR(TLS_I_CERTF_UNR, req),
625 		   bitset(TLS_I_CERTF_EX, req),
626 		   bitset(TLS_S_CERTF_EX, status), TLS_S_CERTF_OK, srv);
627 	TLS_SAFE_F(dhparam, sff | TLS_UNR(TLS_I_DHPAR_UNR, req),
628 		   bitset(TLS_I_DHPAR_EX, req),
629 		   bitset(TLS_S_DHPAR_EX, status), TLS_S_DHPAR_OK, srv);
630 	if (!ok)
631 		return ok;
632 # if _FFR_TLS_1
633 	if (cf2 != NULL)
634 	{
635 		TLS_SAFE_F(cf2, sff | TLS_UNR(TLS_I_CERT_UNR, req),
636 			   bitset(TLS_I_CERT_EX, req),
637 			   bitset(TLS_S_CERT2_EX, status), TLS_S_CERT2_OK, srv);
638 	}
639 	if (kf2 != NULL)
640 	{
641 		TLS_SAFE_F(kf2, sff | TLS_KEYSFF(req),
642 			   bitset(TLS_I_KEY_EX, req),
643 			   bitset(TLS_S_KEY2_EX, status), TLS_S_KEY2_OK, srv);
644 	}
645 # endif /* _FFR_TLS_1 */
646 
647 	/* create a method and a new context */
648 	if ((*ctx = SSL_CTX_new(srv ? SSLv23_server_method() :
649 				      SSLv23_client_method())) == NULL)
650 	{
651 		if (LogLevel > 7)
652 			sm_syslog(LOG_WARNING, NOQID,
653 				  "STARTTLS=%s, error: SSL_CTX_new(SSLv23_%s_method()) failed",
654 				  who, who);
655 		if (LogLevel > 9)
656 			tlslogerr(who);
657 		return false;
658 	}
659 
660 # if TLS_NO_RSA
661 	/* turn off backward compatibility, required for no-rsa */
662 	SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2);
663 # endif /* TLS_NO_RSA */
664 
665 
666 # if !TLS_NO_RSA
667 	/*
668 	**  Create a temporary RSA key
669 	**  XXX  Maybe we shouldn't create this always (even though it
670 	**  is only at startup).
671 	**  It is a time-consuming operation and it is not always necessary.
672 	**  maybe we should do it only on demand...
673 	*/
674 
675 	if (bitset(TLS_I_RSA_TMP, req)
676 #   if SM_CONF_SHM
677 	    && ShmId != SM_SHM_NO_ID &&
678 	    (rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL,
679 					NULL)) == NULL
680 #   else /* SM_CONF_SHM */
681 	    && 0	/* no shared memory: no need to generate key now */
682 #   endif /* SM_CONF_SHM */
683 	   )
684 	{
685 		if (LogLevel > 7)
686 		{
687 			sm_syslog(LOG_WARNING, NOQID,
688 				  "STARTTLS=%s, error: RSA_generate_key failed",
689 				  who);
690 			if (LogLevel > 9)
691 				tlslogerr(who);
692 		}
693 		return false;
694 	}
695 # endif /* !TLS_NO_RSA */
696 
697 	/*
698 	**  load private key
699 	**  XXX change this for DSA-only version
700 	*/
701 
702 	if (bitset(TLS_S_KEY_OK, status) &&
703 	    SSL_CTX_use_PrivateKey_file(*ctx, keyfile,
704 					 SSL_FILETYPE_PEM) <= 0)
705 	{
706 		if (LogLevel > 7)
707 		{
708 			sm_syslog(LOG_WARNING, NOQID,
709 				  "STARTTLS=%s, error: SSL_CTX_use_PrivateKey_file(%s) failed",
710 				  who, keyfile);
711 			if (LogLevel > 9)
712 				tlslogerr(who);
713 		}
714 		if (bitset(TLS_I_USE_KEY, req))
715 			return false;
716 	}
717 
718 	/* get the certificate file */
719 	if (bitset(TLS_S_CERT_OK, status) &&
720 	    SSL_CTX_use_certificate_file(*ctx, certfile,
721 					 SSL_FILETYPE_PEM) <= 0)
722 	{
723 		if (LogLevel > 7)
724 		{
725 			sm_syslog(LOG_WARNING, NOQID,
726 				  "STARTTLS=%s, error: SSL_CTX_use_certificate_file(%s) failed",
727 				  who, certfile);
728 			if (LogLevel > 9)
729 				tlslogerr(who);
730 		}
731 		if (bitset(TLS_I_USE_CERT, req))
732 			return false;
733 	}
734 
735 	/* check the private key */
736 	if (bitset(TLS_S_KEY_OK, status) &&
737 	    (r = SSL_CTX_check_private_key(*ctx)) <= 0)
738 	{
739 		/* Private key does not match the certificate public key */
740 		if (LogLevel > 5)
741 		{
742 			sm_syslog(LOG_WARNING, NOQID,
743 				  "STARTTLS=%s, error: SSL_CTX_check_private_key failed(%s): %d",
744 				  who, keyfile, r);
745 			if (LogLevel > 9)
746 				tlslogerr(who);
747 		}
748 		if (bitset(TLS_I_USE_KEY, req))
749 			return false;
750 	}
751 
752 # if _FFR_TLS_1
753 	/* XXX this code is pretty much duplicated from above! */
754 
755 	/* load private key */
756 	if (bitset(TLS_S_KEY2_OK, status) &&
757 	    SSL_CTX_use_PrivateKey_file(*ctx, kf2, SSL_FILETYPE_PEM) <= 0)
758 	{
759 		if (LogLevel > 7)
760 		{
761 			sm_syslog(LOG_WARNING, NOQID,
762 				  "STARTTLS=%s, error: SSL_CTX_use_PrivateKey_file(%s) failed",
763 				  who, kf2);
764 			if (LogLevel > 9)
765 				tlslogerr(who);
766 		}
767 	}
768 
769 	/* get the certificate file */
770 	if (bitset(TLS_S_CERT2_OK, status) &&
771 	    SSL_CTX_use_certificate_file(*ctx, cf2, SSL_FILETYPE_PEM) <= 0)
772 	{
773 		if (LogLevel > 7)
774 		{
775 			sm_syslog(LOG_WARNING, NOQID,
776 				  "STARTTLS=%s, error: SSL_CTX_use_certificate_file(%s) failed",
777 				  who, cf2);
778 			if (LogLevel > 9)
779 				tlslogerr(who);
780 		}
781 	}
782 
783 	/* also check the private key */
784 	if (bitset(TLS_S_KEY2_OK, status) &&
785 	    (r = SSL_CTX_check_private_key(*ctx)) <= 0)
786 	{
787 		/* Private key does not match the certificate public key */
788 		if (LogLevel > 5)
789 		{
790 			sm_syslog(LOG_WARNING, NOQID,
791 				  "STARTTLS=%s, error: SSL_CTX_check_private_key 2 failed: %d",
792 				  who, r);
793 			if (LogLevel > 9)
794 				tlslogerr(who);
795 		}
796 	}
797 # endif /* _FFR_TLS_1 */
798 
799 	/* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */
800 	SSL_CTX_set_options(*ctx, SSL_OP_ALL);	/* XXX bug compatibility? */
801 
802 # if !NO_DH
803 	/* Diffie-Hellman initialization */
804 	if (bitset(TLS_I_TRY_DH, req))
805 	{
806 		if (bitset(TLS_S_DHPAR_OK, status))
807 		{
808 			BIO *bio;
809 
810 			if ((bio = BIO_new_file(dhparam, "r")) != NULL)
811 			{
812 				dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
813 				BIO_free(bio);
814 				if (dh == NULL && LogLevel > 7)
815 				{
816 					unsigned long err;
817 
818 					err = ERR_get_error();
819 					sm_syslog(LOG_WARNING, NOQID,
820 						  "STARTTLS=%s, error: cannot read DH parameters(%s): %s",
821 						  who, dhparam,
822 						  ERR_error_string(err, NULL));
823 					if (LogLevel > 9)
824 						tlslogerr(who);
825 				}
826 			}
827 			else
828 			{
829 				if (LogLevel > 5)
830 				{
831 					sm_syslog(LOG_WARNING, NOQID,
832 						  "STARTTLS=%s, error: BIO_new_file(%s) failed",
833 						  who, dhparam);
834 					if (LogLevel > 9)
835 						tlslogerr(who);
836 				}
837 			}
838 		}
839 		if (dh == NULL && bitset(TLS_I_DH1024, req))
840 		{
841 			DSA *dsa;
842 
843 			/* this takes a while! (7-130s on a 450MHz AMD K6-2) */
844 			dsa = DSA_generate_parameters(1024, NULL, 0, NULL,
845 						      NULL, 0, NULL);
846 			dh = DSA_dup_DH(dsa);
847 			DSA_free(dsa);
848 		}
849 		else
850 		if (dh == NULL && bitset(TLS_I_DH512, req))
851 			dh = get_dh512();
852 
853 		if (dh == NULL)
854 		{
855 			if (LogLevel > 9)
856 			{
857 				unsigned long err;
858 
859 				err = ERR_get_error();
860 				sm_syslog(LOG_WARNING, NOQID,
861 					  "STARTTLS=%s, error: cannot read or set DH parameters(%s): %s",
862 					  who, dhparam,
863 					  ERR_error_string(err, NULL));
864 			}
865 			if (bitset(TLS_I_REQ_DH, req))
866 				return false;
867 		}
868 		else
869 		{
870 			SSL_CTX_set_tmp_dh(*ctx, dh);
871 
872 			/* important to avoid small subgroup attacks */
873 			SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_DH_USE);
874 			if (LogLevel > 13)
875 				sm_syslog(LOG_INFO, NOQID,
876 					  "STARTTLS=%s, Diffie-Hellman init, key=%d bit (%c)",
877 					  who, 8 * DH_size(dh), *dhparam);
878 			DH_free(dh);
879 		}
880 	}
881 # endif /* !NO_DH */
882 
883 
884 	/* XXX do we need this cache here? */
885 	if (bitset(TLS_I_CACHE, req))
886 		SSL_CTX_sess_set_cache_size(*ctx, 128);
887 	/* timeout? SSL_CTX_set_timeout(*ctx, TimeOut...); */
888 
889 	/* load certificate locations and default CA paths */
890 	if (bitset(TLS_S_CERTP_EX, status) && bitset(TLS_S_CERTF_EX, status))
891 	{
892 		if ((r = SSL_CTX_load_verify_locations(*ctx, cacertfile,
893 						       cacertpath)) == 1)
894 		{
895 # if !TLS_NO_RSA
896 			if (bitset(TLS_I_RSA_TMP, req))
897 				SSL_CTX_set_tmp_rsa_callback(*ctx, tmp_rsa_key);
898 # endif /* !TLS_NO_RSA */
899 
900 			/*
901 			**  We have to install our own verify callback:
902 			**  SSL_VERIFY_PEER requests a client cert but even
903 			**  though *FAIL_IF* isn't set, the connection
904 			**  will be aborted if the client presents a cert
905 			**  that is not "liked" (can't be verified?) by
906 			**  the TLS library :-(
907 			*/
908 
909 			/*
910 			**  XXX currently we could call tls_set_verify()
911 			**  but we hope that that function will later on
912 			**  only set the mode per connection.
913 			*/
914 			SSL_CTX_set_verify(*ctx,
915 				bitset(TLS_I_NO_VRFY, req) ? SSL_VERIFY_NONE
916 							   : SSL_VERIFY_PEER,
917 				NULL);
918 
919 			/* install verify callback */
920 			SSL_CTX_set_cert_verify_callback(*ctx, tls_verify_cb,
921 							 NULL);
922 			SSL_CTX_set_client_CA_list(*ctx,
923 				SSL_load_client_CA_file(cacertfile));
924 		}
925 		else
926 		{
927 			/*
928 			**  can't load CA data; do we care?
929 			**  the data is necessary to authenticate the client,
930 			**  which in turn would be necessary
931 			**  if we want to allow relaying based on it.
932 			*/
933 			if (LogLevel > 5)
934 			{
935 				sm_syslog(LOG_WARNING, NOQID,
936 					  "STARTTLS=%s, error: load verify locs %s, %s failed: %d",
937 					  who, cacertpath, cacertfile, r);
938 				if (LogLevel > 9)
939 					tlslogerr(who);
940 			}
941 			if (bitset(TLS_I_VRFY_LOC, req))
942 				return false;
943 		}
944 	}
945 
946 	/* XXX: make this dependent on an option? */
947 	if (tTd(96, 9))
948 		SSL_CTX_set_info_callback(*ctx, apps_ssl_info_cb);
949 
950 # if _FFR_TLS_1
951 	/* install our own cipher list */
952 	if (CipherList != NULL && *CipherList != '\0')
953 	{
954 		if (SSL_CTX_set_cipher_list(*ctx, CipherList) <= 0)
955 		{
956 			if (LogLevel > 7)
957 			{
958 				sm_syslog(LOG_WARNING, NOQID,
959 					  "STARTTLS=%s, error: SSL_CTX_set_cipher_list(%s) failed, list ignored",
960 					  who, CipherList);
961 
962 				if (LogLevel > 9)
963 					tlslogerr(who);
964 			}
965 			/* failure if setting to this list is required? */
966 		}
967 	}
968 # endif /* _FFR_TLS_1 */
969 	if (LogLevel > 12)
970 		sm_syslog(LOG_INFO, NOQID, "STARTTLS=%s, init=%d", who, ok);
971 
972 # if _FFR_TLS_1
973 #  if 0
974 	/*
975 	**  this label is required if we want to have a "clean" exit
976 	**  see the comments above at the initialization of cf2
977 	*/
978 
979     endinittls:
980 #  endif /* 0 */
981 
982 	/* undo damage to global variables */
983 	if (cf2 != NULL)
984 		*--cf2 = ',';
985 	if (kf2 != NULL)
986 		*--kf2 = ',';
987 # endif /* _FFR_TLS_1 */
988 
989 	return ok;
990 }
991 /*
992 **  TLS_GET_INFO -- get information about TLS connection
993 **
994 **	Parameters:
995 **		ssl -- TLS connection structure
996 **		srv -- server or client
997 **		host -- hostname of other side
998 **		mac -- macro storage
999 **		certreq -- did we ask for a cert?
1000 **
1001 **	Returns:
1002 **		result of authentication.
1003 **
1004 **	Side Effects:
1005 **		sets macros: {cipher}, {tls_version}, {verify},
1006 **		{cipher_bits}, {alg_bits}, {cert}, {cert_subject},
1007 **		{cert_issuer}, {cn_subject}, {cn_issuer}
1008 */
1009 
1010 int
1011 tls_get_info(ssl, srv, host, mac, certreq)
1012 	SSL *ssl;
1013 	bool srv;
1014 	char *host;
1015 	MACROS_T *mac;
1016 	bool certreq;
1017 {
1018 	SSL_CIPHER *c;
1019 	int b, r;
1020 	char *s, *who;
1021 	char bitstr[16];
1022 	X509 *cert;
1023 
1024 	c = SSL_get_current_cipher(ssl);
1025 
1026 	/* cast is just workaround for compiler warning */
1027 	macdefine(mac, A_TEMP, macid("{cipher}"),
1028 		  (char *) SSL_CIPHER_get_name(c));
1029 	b = SSL_CIPHER_get_bits(c, &r);
1030 	(void) sm_snprintf(bitstr, sizeof bitstr, "%d", b);
1031 	macdefine(mac, A_TEMP, macid("{cipher_bits}"), bitstr);
1032 	(void) sm_snprintf(bitstr, sizeof bitstr, "%d", r);
1033 	macdefine(mac, A_TEMP, macid("{alg_bits}"), bitstr);
1034 	s = SSL_CIPHER_get_version(c);
1035 	if (s == NULL)
1036 		s = "UNKNOWN";
1037 	macdefine(mac, A_TEMP, macid("{tls_version}"), s);
1038 
1039 	who = srv ? "server" : "client";
1040 	cert = SSL_get_peer_certificate(ssl);
1041 	if (LogLevel > 14)
1042 		sm_syslog(LOG_INFO, NOQID,
1043 			  "STARTTLS=%s, get_verify: %ld get_peer: 0x%lx",
1044 			  who, SSL_get_verify_result(ssl),
1045 			  (unsigned long) cert);
1046 	if (cert != NULL)
1047 	{
1048 		unsigned int n;
1049 		unsigned char md[EVP_MAX_MD_SIZE];
1050 		char buf[MAXNAME];
1051 
1052 		X509_NAME_oneline(X509_get_subject_name(cert),
1053 				  buf, sizeof buf);
1054 		macdefine(mac, A_TEMP, macid("{cert_subject}"),
1055 			 xtextify(buf, "<>\")"));
1056 		X509_NAME_oneline(X509_get_issuer_name(cert),
1057 				  buf, sizeof buf);
1058 		macdefine(mac, A_TEMP, macid("{cert_issuer}"),
1059 			 xtextify(buf, "<>\")"));
1060 		X509_NAME_get_text_by_NID(X509_get_subject_name(cert),
1061 					  NID_commonName, buf, sizeof buf);
1062 		macdefine(mac, A_TEMP, macid("{cn_subject}"),
1063 			 xtextify(buf, "<>\")"));
1064 		X509_NAME_get_text_by_NID(X509_get_issuer_name(cert),
1065 					  NID_commonName, buf, sizeof buf);
1066 		macdefine(mac, A_TEMP, macid("{cn_issuer}"),
1067 			 xtextify(buf, "<>\")"));
1068 		if (X509_digest(cert, EVP_md5(), md, &n))
1069 		{
1070 			char md5h[EVP_MAX_MD_SIZE * 3];
1071 			static const char hexcodes[] = "0123456789ABCDEF";
1072 
1073 			SM_ASSERT((n * 3) + 2 < sizeof(md5h));
1074 			for (r = 0; r < (int) n; r++)
1075 			{
1076 				md5h[r * 3] = hexcodes[(md[r] & 0xf0) >> 4];
1077 				md5h[(r * 3) + 1] = hexcodes[(md[r] & 0x0f)];
1078 				md5h[(r * 3) + 2] = ':';
1079 			}
1080 			md5h[(n * 3) - 1] = '\0';
1081 			macdefine(mac, A_TEMP, macid("{cert_md5}"), md5h);
1082 		}
1083 		else
1084 			macdefine(mac, A_TEMP, macid("{cert_md5}"), "");
1085 	}
1086 	else
1087 	{
1088 		macdefine(mac, A_PERM, macid("{cert_subject}"), "");
1089 		macdefine(mac, A_PERM, macid("{cert_issuer}"), "");
1090 		macdefine(mac, A_PERM, macid("{cn_subject}"), "");
1091 		macdefine(mac, A_PERM, macid("{cn_issuer}"), "");
1092 		macdefine(mac, A_TEMP, macid("{cert_md5}"), "");
1093 	}
1094 	switch (SSL_get_verify_result(ssl))
1095 	{
1096 	  case X509_V_OK:
1097 		if (cert != NULL)
1098 		{
1099 			s = "OK";
1100 			r = TLS_AUTH_OK;
1101 		}
1102 		else
1103 		{
1104 			s = certreq ? "NO" : "NOT",
1105 			r = TLS_AUTH_NO;
1106 		}
1107 		break;
1108 	  default:
1109 		s = "FAIL";
1110 		r = TLS_AUTH_FAIL;
1111 		break;
1112 	}
1113 	macdefine(mac, A_PERM, macid("{verify}"), s);
1114 	if (cert != NULL)
1115 		X509_free(cert);
1116 
1117 	/* do some logging */
1118 	if (LogLevel > 8)
1119 	{
1120 		char *vers, *s1, *s2, *cbits, *algbits;
1121 
1122 		vers = macget(mac, macid("{tls_version}"));
1123 		cbits = macget(mac, macid("{cipher_bits}"));
1124 		algbits = macget(mac, macid("{alg_bits}"));
1125 		s1 = macget(mac, macid("{verify}"));
1126 		s2 = macget(mac, macid("{cipher}"));
1127 
1128 		/* XXX: maybe cut off ident info? */
1129 		sm_syslog(LOG_INFO, NOQID,
1130 			  "STARTTLS=%s, relay=%.100s, version=%.16s, verify=%.16s, cipher=%.64s, bits=%.6s/%.6s",
1131 			  who,
1132 			  host == NULL ? "local" : host,
1133 			  vers, s1, s2, /* sm_snprintf() can deal with NULL */
1134 			  algbits == NULL ? "0" : algbits,
1135 			  cbits == NULL ? "0" : cbits);
1136 		if (LogLevel > 11)
1137 		{
1138 			/*
1139 			**  Maybe run xuntextify on the strings?
1140 			**  That is easier to read but makes it maybe a bit
1141 			**  more complicated to figure out the right values
1142 			**  for the access map...
1143 			*/
1144 
1145 			s1 = macget(mac, macid("{cert_subject}"));
1146 			s2 = macget(mac, macid("{cert_issuer}"));
1147 			sm_syslog(LOG_INFO, NOQID,
1148 				  "STARTTLS=%s, cert-subject=%.128s, cert-issuer=%.128s",
1149 				  who, s1, s2);
1150 		}
1151 	}
1152 	return r;
1153 }
1154 /*
1155 **  ENDTLS -- shutdown secure connection
1156 **
1157 **	Parameters:
1158 **		ssl -- SSL connection information.
1159 **		side -- server/client (for logging).
1160 **
1161 **	Returns:
1162 **		success? (EX_* code)
1163 */
1164 
1165 int
1166 endtls(ssl, side)
1167 	SSL *ssl;
1168 	char *side;
1169 {
1170 	int ret = EX_OK;
1171 
1172 	if (ssl != NULL)
1173 	{
1174 		int r;
1175 
1176 		if ((r = SSL_shutdown(ssl)) < 0)
1177 		{
1178 			if (LogLevel > 11)
1179 			{
1180 				sm_syslog(LOG_WARNING, NOQID,
1181 					  "STARTTLS=%s, SSL_shutdown failed: %d",
1182 					  side, r);
1183 				tlslogerr(side);
1184 			}
1185 			ret = EX_SOFTWARE;
1186 		}
1187 # if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL
1188 
1189 		/*
1190 		**  Bug in OpenSSL (at least up to 0.9.6b):
1191 		**  From: Lutz.Jaenicke@aet.TU-Cottbus.DE
1192 		**  Message-ID: <20010723152244.A13122@serv01.aet.tu-cottbus.de>
1193 		**  To: openssl-users@openssl.org
1194 		**  Subject: Re: SSL_shutdown() woes (fwd)
1195 		**
1196 		**  The side sending the shutdown alert first will
1197 		**  not care about the answer of the peer but will
1198 		**  immediately return with a return value of "0"
1199 		**  (ssl/s3_lib.c:ssl3_shutdown()). SSL_get_error will evaluate
1200 		**  the value of "0" and as the shutdown alert of the peer was
1201 		**  not received (actually, the program did not even wait for
1202 		**  the answer), an SSL_ERROR_SYSCALL is flagged, because this
1203 		**  is the default rule in case everything else does not apply.
1204 		**
1205 		**  For your server the problem is different, because it
1206 		**  receives the shutdown first (setting SSL_RECEIVED_SHUTDOWN),
1207 		**  then sends its response (SSL_SENT_SHUTDOWN), so for the
1208 		**  server the shutdown was successfull.
1209 		**
1210 		**  As is by know, you would have to call SSL_shutdown() once
1211 		**  and ignore an SSL_ERROR_SYSCALL returned. Then call
1212 		**  SSL_shutdown() again to actually get the server's response.
1213 		**
1214 		**  In the last discussion, Bodo Moeller concluded that a
1215 		**  rewrite of the shutdown code would be necessary, but
1216 		**  probably with another API, as the change would not be
1217 		**  compatible to the way it is now.  Things do not become
1218 		**  easier as other programs do not follow the shutdown
1219 		**  guidelines anyway, so that a lot error conditions and
1220 		**  compitibility issues would have to be caught.
1221 		**
1222 		**  For now the recommondation is to ignore the error message.
1223 		*/
1224 
1225 		else if (r == 0)
1226 		{
1227 			if (LogLevel > 15)
1228 			{
1229 				sm_syslog(LOG_WARNING, NOQID,
1230 					  "STARTTLS=%s, SSL_shutdown not done",
1231 					  side);
1232 				tlslogerr(side);
1233 			}
1234 			ret = EX_SOFTWARE;
1235 		}
1236 # endif /* !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL */
1237 		SSL_free(ssl);
1238 		ssl = NULL;
1239 	}
1240 	return ret;
1241 }
1242 
1243 # if !TLS_NO_RSA
1244 /*
1245 **  TMP_RSA_KEY -- return temporary RSA key
1246 **
1247 **	Parameters:
1248 **		s -- TLS connection structure
1249 **		export --
1250 **		keylength --
1251 **
1252 **	Returns:
1253 **		temporary RSA key.
1254 */
1255 
1256 #   ifndef MAX_RSA_TMP_CNT
1257 #    define MAX_RSA_TMP_CNT	1000	/* XXX better value? */
1258 #   endif /* ! MAX_RSA_TMP_CNT */
1259 
1260 /* ARGUSED0 */
1261 static RSA *
1262 tmp_rsa_key(s, export, keylength)
1263 	SSL *s;
1264 	int export;
1265 	int keylength;
1266 {
1267 #   if SM_CONF_SHM
1268 	extern int ShmId;
1269 	extern int *PRSATmpCnt;
1270 
1271 	if (ShmId != SM_SHM_NO_ID && rsa_tmp != NULL &&
1272 	    ++(*PRSATmpCnt) < MAX_RSA_TMP_CNT)
1273 		return rsa_tmp;
1274 #   endif /* SM_CONF_SHM */
1275 
1276 	if (rsa_tmp != NULL)
1277 		RSA_free(rsa_tmp);
1278 	rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL, NULL);
1279 	if (rsa_tmp == NULL)
1280 	{
1281 		if (LogLevel > 0)
1282 			sm_syslog(LOG_ERR, NOQID,
1283 				  "STARTTLS=server, tmp_rsa_key: RSA_generate_key failed!");
1284 	}
1285 	else
1286 	{
1287 #   if SM_CONF_SHM
1288 #    if 0
1289 		/*
1290 		**  XXX we can't (yet) share the new key...
1291 		**	The RSA structure contains pointers hence it can't be
1292 		**	easily kept in shared memory.  It must be transformed
1293 		**	into a continous memory region first, then stored,
1294 		**	and later read out again (each time re-transformed).
1295 		*/
1296 
1297 		if (ShmId != SM_SHM_NO_ID)
1298 			*PRSATmpCnt = 0;
1299 #    endif /* 0 */
1300 #   endif /* SM_CONF_SHM */
1301 		if (LogLevel > 9)
1302 			sm_syslog(LOG_ERR, NOQID,
1303 				  "STARTTLS=server, tmp_rsa_key: new temp RSA key");
1304 	}
1305 	return rsa_tmp;
1306 }
1307 # endif /* !TLS_NO_RSA */
1308 /*
1309 **  APPS_SSL_INFO_CB -- info callback for TLS connections
1310 **
1311 **	Parameters:
1312 **		s -- TLS connection structure
1313 **		where -- state in handshake
1314 **		ret -- return code of last operation
1315 **
1316 **	Returns:
1317 **		none.
1318 */
1319 
1320 static void
1321 apps_ssl_info_cb(s, where, ret)
1322 	CONST097 SSL *s;
1323 	int where;
1324 	int ret;
1325 {
1326 	int w;
1327 	char *str;
1328 	BIO *bio_err = NULL;
1329 
1330 	if (LogLevel > 14)
1331 		sm_syslog(LOG_INFO, NOQID,
1332 			  "STARTTLS: info_callback where=0x%x, ret=%d",
1333 			  where, ret);
1334 
1335 	w = where & ~SSL_ST_MASK;
1336 	if (bio_err == NULL)
1337 		bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
1338 
1339 	if (bitset(SSL_ST_CONNECT, w))
1340 		str = "SSL_connect";
1341 	else if (bitset(SSL_ST_ACCEPT, w))
1342 		str = "SSL_accept";
1343 	else
1344 		str = "undefined";
1345 
1346 	if (bitset(SSL_CB_LOOP, where))
1347 	{
1348 		if (LogLevel > 12)
1349 			sm_syslog(LOG_NOTICE, NOQID,
1350 				"STARTTLS: %s:%s",
1351 				str, SSL_state_string_long(s));
1352 	}
1353 	else if (bitset(SSL_CB_ALERT, where))
1354 	{
1355 		str = bitset(SSL_CB_READ, where) ? "read" : "write";
1356 		if (LogLevel > 12)
1357 			sm_syslog(LOG_NOTICE, NOQID,
1358 				"STARTTLS: SSL3 alert %s:%s:%s",
1359 				str, SSL_alert_type_string_long(ret),
1360 				SSL_alert_desc_string_long(ret));
1361 	}
1362 	else if (bitset(SSL_CB_EXIT, where))
1363 	{
1364 		if (ret == 0)
1365 		{
1366 			if (LogLevel > 7)
1367 				sm_syslog(LOG_WARNING, NOQID,
1368 					"STARTTLS: %s:failed in %s",
1369 					str, SSL_state_string_long(s));
1370 		}
1371 		else if (ret < 0)
1372 		{
1373 			if (LogLevel > 7)
1374 				sm_syslog(LOG_WARNING, NOQID,
1375 					"STARTTLS: %s:error in %s",
1376 					str, SSL_state_string_long(s));
1377 		}
1378 	}
1379 }
1380 /*
1381 **  TLS_VERIFY_LOG -- log verify error for TLS certificates
1382 **
1383 **	Parameters:
1384 **		ok -- verify ok?
1385 **		ctx -- x509 context
1386 **
1387 **	Returns:
1388 **		0 -- fatal error
1389 **		1 -- ok
1390 */
1391 
1392 static int
1393 tls_verify_log(ok, ctx)
1394 	int ok;
1395 	X509_STORE_CTX *ctx;
1396 {
1397 	SSL *ssl;
1398 	X509 *cert;
1399 	int reason, depth;
1400 	char buf[512];
1401 
1402 	cert = X509_STORE_CTX_get_current_cert(ctx);
1403 	reason = X509_STORE_CTX_get_error(ctx);
1404 	depth = X509_STORE_CTX_get_error_depth(ctx);
1405 	ssl = (SSL *) X509_STORE_CTX_get_ex_data(ctx,
1406 			SSL_get_ex_data_X509_STORE_CTX_idx());
1407 
1408 	if (ssl == NULL)
1409 	{
1410 		/* internal error */
1411 		sm_syslog(LOG_ERR, NOQID,
1412 			  "STARTTLS: internal error: tls_verify_cb: ssl == NULL");
1413 		return 0;
1414 	}
1415 
1416 	X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof buf);
1417 	sm_syslog(LOG_INFO, NOQID,
1418 		  "STARTTLS: cert verify: depth=%d %s, state=%d, reason=%s",
1419 		  depth, buf, ok, X509_verify_cert_error_string(reason));
1420 	return 1;
1421 }
1422 /*
1423 **  TLS_VERIFY_CB -- verify callback for TLS certificates
1424 **
1425 **	Parameters:
1426 **		ctx -- x509 context
1427 **
1428 **	Returns:
1429 **		accept connection?
1430 **		currently: always yes.
1431 */
1432 
1433 static int
1434 #  if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
1435 tls_verify_cb(ctx)
1436 	X509_STORE_CTX *ctx;
1437 #  else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
1438 tls_verify_cb(ctx, unused)
1439 	X509_STORE_CTX *ctx;
1440 	void *unused;
1441 #  endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
1442 {
1443 	int ok;
1444 
1445 	ok = X509_verify_cert(ctx);
1446 	if (ok == 0)
1447 	{
1448 		if (LogLevel > 13)
1449 			return tls_verify_log(ok, ctx);
1450 		return 1;	/* override it */
1451 	}
1452 	return ok;
1453 }
1454 /*
1455 **  TLSLOGERR -- log the errors from the TLS error stack
1456 **
1457 **	Parameters:
1458 **		who -- server/client (for logging).
1459 **
1460 **	Returns:
1461 **		none.
1462 */
1463 
1464 void
1465 tlslogerr(who)
1466 	char *who;
1467 {
1468 	unsigned long l;
1469 	int line, flags;
1470 	unsigned long es;
1471 	char *file, *data;
1472 	char buf[256];
1473 #  define CP (const char **)
1474 
1475 	es = CRYPTO_thread_id();
1476 	while ((l = ERR_get_error_line_data(CP &file, &line, CP &data, &flags))
1477 		!= 0)
1478 	{
1479 		sm_syslog(LOG_WARNING, NOQID,
1480 			  "STARTTLS=%s: %lu:%s:%s:%d:%s", who, es,
1481 			  ERR_error_string(l, buf),
1482 			  file, line,
1483 			  bitset(ERR_TXT_STRING, flags) ? data : "");
1484 	}
1485 }
1486 #endif /* STARTTLS */
1487