/*
**  Copyright (c) 2004-2009 Sendmail, Inc. and its suppliers.
**    All rights reserved.
** 
**  $Id: dk.h,v 1.57 2009/02/04 17:45:32 msk Exp $
*/

#ifndef _SMI_DK_H_
#define _SMI_DK_H_

#ifndef lint
static char dk_h_id[] = "@(#)$Id: dk.h,v 1.57 2009/02/04 17:45:32 msk Exp $";
#endif /* !lint */

/* system includes */
#include <sys/types.h>

/* libsm includes */
#include <sm/cdefs.h>

/*
**  version -- 0xrrMMmmpp
**  
**  	rr == release number
**  	MM == major revision number
**  	mm == minor revision number
**  	pp == patch number
*/

#define	DK_LIB_VERSION		0x01000200

#define DK_DNSNAME		"_domainkey"
					/* common DNS label */

/* limits, macros, etc. */
#define MAXADDRESS		256	/* biggest user@host we accept */
#define MAXCNAMEDEPTH		3	/* max. CNAME recursion we allow */
#define MAXHDRCNT		64	/* max. headers signed */
#define MAXHEADER		1000	/* buffer for caching one header */
#define MAXHEADERS		32768	/* buffer for caching headers */

/* headers */
#define	DK_SIGNHEADER		"DomainKey-Signature"
					/* DomainKeys signature header */

/*
**  DK_STAT -- status code type
*/

typedef int DK_STAT;

#define	DK_STAT_OK		0	/* function completed successfully */
#define	DK_STAT_BADSIG		1	/* signature available but failed */
#define	DK_STAT_NOSIG		2	/* no signature available */
#define	DK_STAT_NOKEY		3	/* public key not found */
#define	DK_STAT_CANTVRFY	4	/* can't get domain key to verify */
#define	DK_STAT_SYNTAX		5	/* message is not valid syntax */
#define	DK_STAT_NORESOURCE	6	/* resource unavailable */
#define	DK_STAT_INTERNAL	7	/* internal error */
#define	DK_STAT_REVOKED		8	/* key found, but revoked */
#define	DK_STAT_INVALID		9	/* invalid argument */

/*
**  DK_CANON -- canonicalization method
*/

typedef int dk_canon_t;

#define DK_CANON_UNKNOWN	-1	/* unknown method */
#define DK_CANON_SIMPLE		0	/* as specified in DomainKeys draft */
#define DK_CANON_NOFWS		1	/* as specified in DomainKeys draft */

#define DK_CANON_DEFAULT	DK_CANON_SIMPLE

/*
**  DK_SIGN -- signing method
*/

typedef int dk_alg_t;

#define	DK_SIGN_UNKNOWN		-1	/* unknown method */
#define DK_SIGN_RSASHA1		0	/* an RSA-signed SHA1 digest */

#define DK_SIGN_DEFAULT		DK_SIGN_RSASHA1

/*
**  DK_QUERY -- query method
*/

typedef int dk_query_t;

#define DK_QUERY_UNKNOWN	-1	/* unknown method */
#define DK_QUERY_DNS		0	/* DNS query method (per the draft) */
#define DK_QUERY_FILE		1	/* text file method (for testing) */

#define DK_QUERY_DEFAULT	DK_QUERY_DNS

/*
**  DK_PARAM -- known parameters
*/

#define DK_PARAM_SIGNATURE	0
#define DK_PARAM_SIGNALG	1
#define DK_PARAM_DOMAIN		2
#define DK_PARAM_CANONALG	3
#define DK_PARAM_QUERYMETHOD	4
#define DK_PARAM_SELECTOR	5
#define DK_PARAM_HDRLIST	6

/*
**  DK_FLAGS -- flags
*/

typedef int DK_FLAGS;

#define	DK_FLAG_TESTING		0x01
#define	DK_FLAG_SIGNSALL	0x02
#define	DK_FLAG_HDRLIST		0x04

/*
**  DK_OPTS -- options
*/

typedef int dk_opt_t;

#define DK_OP_GETOPT		0
#define	DK_OP_SETOPT		1

typedef int dk_opts_t;

#define	DK_OPTS_FLAGS		0
#define	DK_OPTS_TMPDIR		1
#define	DK_OPTS_QUERYMETHOD	2
#define	DK_OPTS_QUERYINFO	3

#define	DK_LIBFLAGS_NONE	0x00
#define	DK_LIBFLAGS_TMPFILES	0x01
#define	DK_LIBFLAGS_HDRLIST	0x02
#define	DK_LIBFLAGS_KEEPFILES	0x04

#define	DK_LIBFLAGS_DEFAULT	DK_LIBFLAGS_NONE

/*
**  DK -- DomainKeys context
*/

struct dk;
typedef struct dk DK;

/*
**  DK_SIG_T -- key data
*/

typedef unsigned char * dk_sigkey_t;

/*
**  DK_LIB -- library handle
*/

struct dk_lib;
typedef struct dk_lib DK_LIB;

/*
**  PROTOTYPES
*/

/*
**  DK_INIT -- initialize the DomainKeys package
**
**  Parameters:
**  	None.
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_LIB *dk_init __P((void *(*mallocf)(void *closure, size_t nbytes),
                            void (*freef)(void *closure, void *p)));

/*
**  DK_CLOSE -- shut down the DK package
**
**  Parameters:
**  	lib -- DK_LIB handle to shut down
**
**  Return value:
**  	None.
*/

extern void dk_close __P((DK_LIB *lib));

/*
**  DK_SIGN -- make a new DomainKeys context for signing
**
**  Parameters:
**  	libhandle -- library handle, returned by dk_init()
**  	id -- an opaque printable string for identifying this message, suitable
**  	      for use in logging or debug output; may not be NULL
**  	memclosure -- memory closure, for use by user-provided malloc/free
**  	secretkey -- pointer to secret key data to use; if NULL, it will be
**  	             obtained from disk
**  	canon_alg -- canonicalization algorithm to use; one of the DK_CANON_*
**  	             macros, or -1 for default
**  	sign_alg -- signing algorithm to use; one of the DK_SIGN_* macros,
**  	            or -1 for default
**  	statp -- pointer to a DK_STAT which is updated by this call
**
**  Return value:
**  	A newly-allocated DK handle, or NULL on failure.  "statp" will be
**  	updated.
*/

extern DK *dk_sign __P((DK_LIB *libhandle, const char *id, void *memclosure,
                        const dk_sigkey_t *secretkey, dk_canon_t canon_alg,
                        dk_alg_t sign_alg, DK_STAT *statp));

/*
**  DK_VERIFY -- make a new DomainKeys context for verifying
**
**  Parameters:
**  	libhandle -- library handle, returned by dk_init()
**  	id -- an opaque printable string for identifying this message, suitable
**  	      for use in logging or debug output; may not be NULL
**  	memclosure -- memory closure, for use by user-provided malloc/free
**  	statp -- pointer to a DK_STAT which is updated by this call
**
**  Return value:
**  	A newly-allocated DK handle, or NULL on failure.  "statp" will be
**  	updated.
*/

extern DK *dk_verify __P((DK_LIB *libhandle, const char *id, void *memclosure,
                          DK_STAT *statp));

/*
**  DK_HEADER -- process a header
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**  	hdr -- the header to be processed, in canonical format
**  	len -- number of bytes to process starting at "hdr"
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_STAT dk_header __P((DK *dk, u_char *hdr, size_t len));

/*
**  DK_EOH -- identify end of headers
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**
**  Return value:
**  	A DK_STAT value.  DK_STAT_NOSIG will be returned if we're validating
**  	a signature but no DomainKeys signature was found in the headers.
*/

extern DK_STAT dk_eoh __P((DK *dk));

/*
**  DK_BODY -- process a body chunk
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**  	buf -- the body chunk to be processed, in canonical format
**  	len -- number of bytes to process starting at "hdr"
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_STAT dk_body __P((DK *dk, u_char *buf, size_t len));

/*
**  DK_EOM -- identify end of body
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**  	flags -- pointer to a DK_FLAGS that receives flag bits
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_STAT dk_eom __P((DK *dk, DK_FLAGS *flags));

/*
**  DK_GETSIG -- compute and return a signature for a message
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**  	buf -- buffer into which to write the signature
**  	len -- number of bytes available at "sig"
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_STAT dk_getsig __P((DK *dk, u_char *buf, size_t len));

/*
**  DK_GETHDRS -- report which headers were included in calculation of
**                the signature
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**  	hcnt -- pointer to an int that will receive the header count
**  	buf -- buffer into which to write the signature
**  	len -- number of bytes available at "sig"
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_STAT dk_gethdrs __P((DK *dk, int *hcnt, u_char *buf, size_t buflen));

/*
**  DK_REPORTINFO -- return info needed to generate failure report
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**  	fd -- pointer to receive temporary file descriptor
**   	raddr -- buffer to receive report address
**  	rlen -- bytes available at raddr
**
**  Return vlalue:
**  	A DK_STAT value.
*/

extern DK_STAT dk_reportinfo __P((DK *dk, int *fd, char *raddr, size_t rlen));

/*
**  DK_OPTIONS -- set/get options
**
**  Parameters:
**  	dklib -- DK library handle
**  	op -- operation (DK_OPT_GET or DK_OPT_SET)
**  	opt -- which option (a DK_OPTS_* constant)
**  	ptr -- value (in or out)
**  	len -- bytes available at "ptr"
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_STAT dk_options __P((DK_LIB *dklib, int op, dk_opts_t opt,
                               void *ptr, size_t len));

/*
**  DK_GETIDENTITY -- retrieve signer's apparent identity
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**  	hname -- buffer to receive name of the header from which identity
**  	         was extracted
**  	hnamelen -- number of bytes available at hname
**  	hval -- buffer to receive decommented value of the header from which
**  	        identity was extracted
**  	hvallen -- number of bytes available at hval
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_STAT dk_getidentity __P((DK *dk, char *hname, size_t hnamelen,
                                   char *hval, size_t hvallen));

/*
**  DK_TIMEOUT -- set/get the current DNS timeout
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**  	new -- new timeout, in seconds (or -1 for no change)
**  	old -- pointer to an int into which to write current timeout
**  	       (or NULL if not needed)
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_STAT dk_timeout __P((DK *dk, int newt, int *oldt));

/*
**  DK_FREE -- release resources associated with a DK handle
**
**  Parameters:
**  	dk -- a DK handle previously returned by dk_new()
**
**  Return value:
**  	A DK_STAT value.
*/

extern DK_STAT dk_free __P((DK *dk));

/*
**  DK_GETERROR -- return any stored error string from within the DK
**                 context handle
**
**  Parameters:
**  	dk -- DK handle from which to retrieve an error string
**
**  Return value:
**  	A pointer to the stored string, or NULL if none was stored.
*/

extern const char *dk_geterror __P((DK *dk));

/*
**  RFC2822_MAILBOX_SPLIT -- extract the userid and host from a structured
**                           header
**
**  Parameters:
**  	addr -- the header to parse; see RFC2822 for format
**  	user -- local-part of the parsed header (returned)
**  	domain -- domain part of the parsed header (returned)
**
**  Return value:
**  	0 on success; other on error (see source)
*/

extern int rfc2822_mailbox_split __P((char *addr, char **user, char **domain));


#endif /* ! _SMI_DK_H_ */
