/*
 * Copyright (c) 2003-2005 Sendmail, Inc. and its suppliers.
 *      All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 *
 *	$Id: tls.h,v 1.23 2006/10/05 04:27:36 ca Exp $
 */

#ifndef SM_TLS_H
#define SM_TLS_H 1
#include "sm/generic.h"
#include "sm/error.h"
#include "sm/log.h"
#include "sm/str.h"

#if MTA_USE_TLS
#include "sm/tlscnf.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#ifndef HAVE_URANDOMDEV
# include <openssl/rand.h>
#endif

typedef struct tlsl_ctx_S tlsl_ctx_T, *tlsl_ctx_P;

struct tlsl_ctx_S
{
	sm_log_ctx_P	 tlsl_lctx;
	sm_logconfig_P	 tlsl_lcfg;
	/* store SSL_CTX here? */
};

#if TLSL_LOG_DEFINES
sm_logcategory_T tlsl_lcats[] =
{
	{ "init",	0 },
	{ "config",	0 },
	{ "io",		0 },
	{ NULL,	0 }
};

sm_logmodule_T tlsl_lmods[] =
{
	{ "config",		0 },
	{ "io",			0 },
	{ NULL,		0 }
};

#else /* TLSL_LOG_DEFINES */

extern sm_logcategory_T tlsl_lcats[];
extern sm_logmodule_T tlsl_lmods[];

#endif /* TLSL_LOG_DEFINES */

#define TL_LCAT_INIT		(&tlsl_lcats[0])
#define TL_LCAT_COMM		(&tlsl_lcats[1])
#define TL_LCAT_IO		(&tlsl_lcats[2])

/* Backwards compatibility. */
#define TL_LCAT_GENERAL		TLGLOGCATEGORY_GENERAL

#define TL_LMOD_CONF		(&tlsl_lmods[0])
#define TL_LMOD_IO		(&tlsl_lmods[1])

void	 tlsl_log_init(sm_log_ctx_P _lctx);
void	 tlsl_log_setcontext(sm_log_ctx_P _lctx);

/* TLS information context */
typedef struct tlsi_ctx_S	tlsi_ctx_T, *tlsi_ctx_P;
struct tlsi_ctx_S
{
	int		 tlsi_vrfy;
	int		 tlsi_cipher_bits;
	int		 tlsi_algs_bits;
	sm_str_P	 tlsi_cipher;
	sm_str_P	 tlsi_version;
	sm_str_P	 tlsi_cert_subject;
	sm_str_P	 tlsi_cert_issuer;
	sm_str_P	 tlsi_cn_subject;
	sm_str_P	 tlsi_cn_issuer;
#if SM_TLSI_CERT_MD5
	sm_str_P	 tlsi_cert_md5;
#endif
};

/* what to do in the TLS initialization */
#define TLS_I_NONE	0x00000000	/* no requirements... */
#define TLS_I_CERT_EX	0x00000001	/* cert must exist */
#define TLS_I_CERT_UNR	0x00000002	/* cert must be g/o unreadable */
#define TLS_I_KEY_EX	0x00000004	/* key must exist */
#define TLS_I_KEY_UNR	0x00000008	/* key must be g/o unreadable */
#define TLS_I_CERTP_EX	0x00000010	/* CA cert path must exist */
#define TLS_I_CERTP_UNR	0x00000020	/* CA cert path must be g/o unreadable */
#define TLS_I_CERTF_EX	0x00000040	/* CA cert file must exist */
#define TLS_I_CERTF_UNR	0x00000080	/* CA cert file must be g/o unreadable */
#define TLS_I_RSA_TMP	0x00000100	/* RSA TMP must be generated */
#define TLS_I_USE_KEY	0x00000200	/* private key must usable */
#define TLS_I_USE_CERT	0x00000400	/* certificate must be usable */
#define TLS_I_VRFY_PATH	0x00000800	/* load verify path must succeed */
#define TLS_I_VRFY_LOC	0x00001000	/* load verify default must succeed */
#define TLS_I_CACHE	0x00002000	/* require cache */
#define TLS_I_TRY_DH	0x00004000	/* try DH certificate */
#define TLS_I_REQ_DH	0x00008000	/* require DH certificate */
#define TLS_I_DHPAR_EX	0x00010000	/* require DH parameters */
#define TLS_I_DHPAR_UNR	0x00020000	/* DH param. must be g/o unreadable */
#define TLS_I_DH512	0x00040000	/* generate 512bit DH param */
#define TLS_I_DH1024	0x00080000	/* generate 1024bit DH param */
#define TLS_I_DH2048	0x00100000	/* generate 2048bit DH param */
#define TLS_I_NO_VRFY	0x00200000	/* do not require authentication */
#define TLS_I_KEY_OUNR	0x00400000	/* Key must be other unreadable */

/* require server cert */
#define TLS_I_SRV_CERT	 (TLS_I_CERT_EX | TLS_I_KEY_EX | \
			  TLS_I_KEY_UNR | TLS_I_KEY_OUNR | \
			  TLS_I_CERTP_EX | TLS_I_CERTF_EX | \
			  TLS_I_USE_KEY | TLS_I_USE_CERT)

/* server requirements */
#define TLS_I_SRV	(TLS_I_SRV_CERT | TLS_I_RSA_TMP | TLS_I_VRFY_PATH | \
			 TLS_I_VRFY_LOC | TLS_I_CACHE)

/* client requirements */
#define TLS_I_CLT	(TLS_I_KEY_UNR | TLS_I_KEY_OUNR)

#define TLS_VRFY_OK	0	/* verification ok */
#define TLS_VRFY_NO	1	/* not verified */
#define TLS_VRFY_NOTR	2	/* verification not requested */
#define TLS_VRFY_FAIL	(-1)	/* verification failed */
#define TLS_VRFY_NONE	(-2)	/* no verification performed so far */

sm_ret_T sm_tls_init_library(tlsl_ctx_P *_ptlsl_ctx);
sm_ret_T sm_tls_init(tlsl_ctx_P _tlsl_ctx, SSL_CTX **_ctx, ulong _req, bool _srv, tls_cnf_P tls_cnf);
sm_ret_T sm_tlsversionprt(sm_file_T *_fp);
sm_ret_T sm_tlsversionok(void);
void	 tlslogerr(tlsl_ctx_P _tlsl_ctx, char *_who);
void	 tls_set_verify(SSL_CTX *_ctx, SSL *_ssl, bool _vrfy);

/* flags for tls_get_info */
#define TLS_F_SRV	0x01	/* this is a server */
#define TLS_F_CERT_REQ	0x02	/* cert has been requested */

sm_ret_T tls_get_info(tlsl_ctx_P _tlsl_ctx, SSL *_ssl, uint _flags, char *_host, tlsi_ctx_P _tlsi_ctx);
int	 endtls(tlsl_ctx_P _tlsl_ctx, SSL *_ssl, char *_side);

sm_ret_T sm_set_tls_log(tlsl_ctx_P _tlsl_ctx, sm_file_T *_fp, int _fd, int _loglevel);

char	*tls_vrfy2txt(int _vrfy);

sm_ret_T tlsi_new(tlsi_ctx_P *_ptlsi_ctx);
sm_ret_T tlsi_free(tlsi_ctx_P _tlsi_ctx);
sm_ret_T tlsi_clr(tlsi_ctx_P _tlsi_ctx);

/* note: this uses a "fixed" error label: enomem */
#define TLS_GEN_PATHS(tls_cnf, strct, sn)		\
	do {						\
	SM_GEN_MAP_PATH((tls_cnf).tlscnf_certfile,	\
		(strct).sn##_cnf_cert_abs, confdir,	\
		(strct).sn##_cnf_cert, SM_MTA_CERT, enomem);	\
	SM_GEN_MAP_PATH((tls_cnf).tlscnf_keyfile,	\
		(strct).sn##_cnf_key_abs, confdir,	\
		(strct).sn##_cnf_key, SM_MTA_KEY, enomem);	\
	SM_GEN_MAP_PATH((tls_cnf).tlscnf_dsa_certfile,	\
		(strct).sn##_cnf_dsa_cert_abs,	\
		confdir, (strct).sn##_cnf_dsa_cert, NULL, enomem);	\
	SM_GEN_MAP_PATH((tls_cnf).tlscnf_dsa_keyfile,	\
		(strct).sn##_cnf_dsa_key_abs,	\
		confdir, (strct).sn##_cnf_dsa_key, NULL, enomem);	\
	SM_GEN_MAP_PATH((tls_cnf).tlscnf_cacertpath,	\
		(strct).sn##_cnf_certpath_abs,	\
		confdir, (strct).sn##_cnf_certpath, SM_MTA_CERTP,	\
		enomem);	\
	SM_GEN_MAP_PATH((tls_cnf).tlscnf_cacertfile,	\
		(strct).sn##_cnf_cacert_abs,	\
		confdir, (strct).sn##_cnf_cacert, SM_MTA_CACERT,	\
		enomem);	\
	} while (0)

#endif /* MTA_USE_TLS */

#endif /* SM_TLS_H */


syntax highlighted by Code2HTML, v. 0.9.1