/* $Id: pgp.h,v 1.18 2015/09/29 13:17:42 onoe Exp $ */

/*-
 * Copyright (c) 1999 Atsushi Onoe
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * constant definitions
 *	obtained from rfc2440 -- OpenPGP Message Format
 */

/* packet tags */
#define	PGP_TAG_PUBENC_SESKEY	1	/* public-key encrypted session */
#define	PGP_TAG_SIGN		2	/* signature */
#define	PGP_TAG_SYMENC_SESKEY	3	/* symmetric-key encrypted session */
#define	PGP_TAG_ONEPASS_SIGN	4	/* one-pass signature */
#define	PGP_TAG_SECRET_KEY	5	/* secret-key */
#define	PGP_TAG_PUBLIC_KEY	6	/* public-key */
#define	PGP_TAG_SECRET_SUBKEY	7	/* secret subkey */
#define	PGP_TAG_COMP_DATA	8	/* compressed data */
#define	PGP_TAG_SYMENC_DATA	9	/* symmetrically encrypted data */
#define	PGP_TAG_MARKER		10	/* marker */
#define	PGP_TAG_LITERAL_DATA	11	/* literal data */
#define	PGP_TAG_TRUST		12	/* trust */
#define	PGP_TAG_USER_ID		13	/* user id */
#define	PGP_TAG_PUBLIC_SUBKEY	14	/* public subkey */
#define	PGP_TAG_USER_ATTR	17	/* user attribute */
#define	PGP_TAG_SYMENC_MDC_DATA	18	/* encrypted data w/ MDC */
#define	PGP_TAG_MDC		19	/* modification detection code */

/* signature subpacket */
#define	PGP_SIGSUB_CRITICAL	0x80	/* critical bit: must not ignore */
#define	PGP_SIGSUB_SIGCREATE	2	/* signature creation time */
#define	PGP_SIGSUB_SIGEXPIRE	3	/* signature expiration time */
#define	PGP_SIGSUB_CERT		4	/* exportable certification */
#define	PGP_SIGSUB_TRUST	5	/* trust signature */
#define	PGP_SIGSUB_REGEX	6	/* regular expression */
#define	PGP_SIGSUB_REVOCABLE	7	/* revocable */
#define	PGP_SIGSUB_KEYEXPIRE	9	/* key expiration time */
#define	PGP_SIGSUB_PREF_SYM	11	/* preferred symmetric algorithms */
#define	PGP_SIGSUB_REV_KEY	12	/* revocation key */
#define	PGP_SIGSUB_ISSUER_ID	16	/* issuer key ID */
#define	PGP_SIGSUB_NOTE		20	/* notation data */ 
#define	PGP_SIGSUB_PREF_HASH	21	/* preferred hash algorithms */
#define	PGP_SIGSUB_PREF_COMP	22	/* preferred compression algorithms */
#define	PGP_SIGSUB_KSERV_PREF	23	/* key server preferences */
#define	PGP_SIGSUB_PREF_KSERV	24	/* preferred key server */
#define	PGP_SIGSUB_PRIM_USERID	25	/* primary user id */
#define	PGP_SIGSUB_POLICY_URL	26	/* policy URL */
#define	PGP_SIGSUB_KEY_FLAGS	27	/* key flags */
#define	PGP_SIGSUB_SIGN_USERID	28	/* signer's user id */
#define	PGP_SIGSUB_REASON_REV	29	/* reason for revocation */

/* signature type */
#define	PGP_SIG_BINDOC		0x00	 /* Signature of a binary document */
#define	PGP_SIG_TEXT		0x01	 /* Signature of a canonical text
					    document */
#define	PGP_SIG_STANDALONE	0x02	 /* Standalone signature */
#define	PGP_SIG_GEN_CERT	0x10	 /* Generic certification of a User ID
					    and Public Key packet */
#define	PGP_SIG_PERSONA_CERT	0x11	 /* Persona certification of a User ID
					    and Public Key packet */
#define	PGP_SIG_CASUAL_CERT	0x12	 /* Casual certification of a User ID
					    and Public Key packet */
#define	PGP_SIG_POSITIVE_CERT	0x13	 /* Positive certification of a User ID
					    and Public Key packet */
#define	PGP_SIG_SUBKEY_BIND	0x18	 /* Subkey Binding Signature */
#define	PGP_SIG_ONKEY		0x1f	 /* Signature directly on a key */
#define	PGP_SIG_REVOKE_KEY	0x20	 /* Key revocation signature */
#define	PGP_SIG_REVOKE_SUBKEY	0x28	 /* Subkey revocation signature */
#define	PGP_SIG_REVOKE_CERT	0x30	 /* Certification revocation signature*/
#define	PGP_SIG_STAMP		0x40	 /* Timestamp signature */

/* public key algorithms */
#define	PGP_PUB_RSA		1	/* RSA (Encrypt or Sign) */
#define	PGP_PUB_RSA_ENC		2	/* RSA Encrypt-Only */
#define	PGP_PUB_RSA_SIG		3	/* RSA Sign-Only */
#define	PGP_PUB_ELGAMAL_ENC	16	/* Elgamal (Encrypt-Only) */
#define	PGP_PUB_DSA		17	/* DSA */
#define	PGP_PUB_E_CURVE		18	/* Elliptic Curve */
#define	PGP_PUB_ECDSA		19	/* ECDSA */
#define	PGP_PUB_ELGAMAL		20	/* Elgamal (Encrypt or Sign) */
#define	PGP_PUB_DIFFIE_HELLMAN	21	/* Diffie-Hellman */

/* symmetric key algorithms */
#define	PGP_SYM_PLAIN		0	/* Plaintext or unencrypted data */
#define	PGP_SYM_IDEA		1	/* IDEA */
#define	PGP_SYM_DES3		2	/* Triple-DES (DES-EDE, as per spec -
					   168 bit key derived from 192) */
#define	PGP_SYM_CAST5		3	/* CAST5 (128 bit key, as per RFC2144)*/
#define	PGP_SYM_BLOWFISH	4	/* Blowfish (128 bit key, 16 rounds) */
#define	PGP_SYM_SAFER_SK128	5	/* SAFER-SK128 (13 rounds) */
#define	PGP_SYM_DES_SK		6	/* Reserved for DES/SK */
#define	PGP_SYM_AES_128		7	/* Reserved for AES with 128-bit key */
#define	PGP_SYM_AES_192		8	/* Reserved for AES with 192-bit key */
#define	PGP_SYM_AES_256		9	/* Reserved for AES with 256-bit key */

/* compression algorithms */
#define	PGP_COMP_NONE		0	/* Uncompressed */
#define	PGP_COMP_ZIP		1	/* ZIP (RFC 1951) */
#define	PGP_COMP_ZLIB		2	/* ZLIB (RFC 1950) */

/* hash algorighms */
#define	PGP_HASH_MD5		1	/* MD5 */
#define	PGP_HASH_SHA1		2	/* SHA-1 */
#define	PGP_HASH_RIPEMD160	3	/* RIPE-MD/160 */
#define	PGP_HASH_DWSHA		4	/* Reserved for double-width SHA
					   (experimental) */
#define	PGP_HASH_MD2		5	/* MD2 */
#define	PGP_HASH_TIGER192	6	/* Reserved for TIGER/192 */
#define	PGP_HASH_HAVAL_5_160	7	/* Reserved for HAVAL (5 pass,160-bit)*/

#define	PGP_S2K_SALT		0x01	/* Salted S2K */
#define	PGP_S2K_ITER		0x02	/* Iterated S2K */

#define	PGP_FLAG_NEW		0x0001	/* new format */
#define	PGP_FLAG_DECRYPTED	0x0002	/* secret key is decrypted */

/* pgp packet structure */
struct pgp_pkt_pubses {		/* PGP_TAG_PUBENC_SESKEY */
	int	ver;
	u_char	keyid[8];
	int	pubalg;
	int	symalg;
	u_char	*seskey;
	int	seslen;
	struct pgp_pkt	*ref_pubkey;
	struct pgp_pkt	*ref_symdat;
};

struct pgp_pkt_sign {		/* PGP_TAG_SIGN */
	int	ver;
	int	type;
	time_t	ctime;
	time_t	exptime;
	u_char	keyid[8];
	int	pubalg;
	int	hashalg;
	int	hash;
	u_char	*mdbuf;
	int	mdlen;
	const u_char	*hdbuf;		/* data to hash calculation (no alloc) */
	u_char	hdlen;
	void	*hctx;		/* context in signing */
	struct pgp_pkt	*ref_sign;
	struct pgp_pkt	*pkt;
};

struct pgp_pkt_opsign {		/* PGP_TAG_ONEPASS_SIGN */
	int	ver;
	int	type;
	int	hashalg;
	int	pubalg;
	u_char	keyid[8];
	int	nestflg;
};

struct pgp_pkt_pubkey {		/* PGP_TAG_PUBLIC_KEY, PGP_TAG_SECRET_KEY */
	int	ver;
	int	tstamp;
	int	expire;
	int	pubalg;
	u_char	keyid[8];
	void	*key;
	struct pgp_pkt	*ref_sign;
	struct pgp_pkt	*ref_user;
	struct pgp_pkt	*ref_subkey;
			/* belows are secret (sub)key only */
	int	symalg;
	u_char	iv[8];
	int	s2k;
	int	hashalg;
	u_char	salt[8];
	int	count;
	int	sha1sum;
};

struct pgp_pkt_compdat {	/* PGP_TAG_COMP_DATA */
	int	compalg;
	u_char	*decbuf;
	int	declen;
	struct pgp_pkt *pkt;
};

struct pgp_pkt_symdat {		/* PGP_TAG_SYMENC_DATA, PGP_TAG_SYMENC_MDC_DATA */
	int	mdcver;
	u_char	*decbuf;
	int	declen;
	struct pgp_pkt	*pkt;
	struct pgp_pkt	*ref_mdc;
};

struct pgp_pkt_litdat {		/* PGP_TAG_LITERAL_DATA */
	int	type;
	char	*name;
	time_t	mtime;
};

struct pgp_pkt_userid {		/* PGP_TAG_USER_ID */
	char	*user;
	struct pgp_pkt	*ref_user;
	struct pgp_pkt	*ref_sign;
};

struct pgp_pkt {
	struct	pgp_pkt *next;
	struct	pgp_pkt *prev;
	int	tag;
	int	flags;
	u_char	*pbuf;			/* allocated for partial len */
	u_char	*dbuf;			/* left unparsed (not allocated) */
	int	dlen;			/* bytes for above */
	union {
		struct pgp_pkt_pubses	pubses;
		struct pgp_pkt_sign	sign;
		struct pgp_pkt_opsign	opsign;
		struct pgp_pkt_pubkey	pubkey;
		struct pgp_pkt_compdat	compdat;
		struct pgp_pkt_litdat	litdat;
		struct pgp_pkt_symdat	symdat;
		struct pgp_pkt_userid	userid;
	}	un;
};

struct pgp_pkt *pgp_parseall(const u_char *p, const u_char *ep);
struct pgp_pkt *pgp_getpkt(struct pgp_pkt *head, int tag);
void pgp_freepkt(struct pgp_pkt *pkt);
int pgp_decrypt_seckey(struct pgp_pkt *pkt, int (*passwd_callback)(char *buf, int size, struct pgp_pkt *pkt));
int pgp_decrypt_seskey(struct pgp_pkt *pkt, struct pgp_pkt *seckey);
int pgp_encrypt_seskey(struct pgp_pkt *pkt, struct pgp_pkt *pubkey);
int pgp_generate_seskey(struct pgp_pkt *pkt);
int pgp_decrypt_symdat(struct pgp_pkt *pkt, struct pgp_pkt *seskey);
int pgp_encrypt_symdat(struct pgp_pkt *pkt, struct pgp_pkt *seskey);
int pgp_decomp_data(struct pgp_pkt *pkt);
int pgp_comp_data(struct pgp_pkt *pkt);
int pgp_verify_sign(struct pgp_pkt *pkt, struct pgp_pkt *pubkey);
int pgp_sign_sign(struct pgp_pkt *pkt, struct pgp_pkt *pubkey);
int pgp_hash_data_init(struct pgp_pkt *sign);
int pgp_hash_data_update(const char *p, const char *ep, struct pgp_pkt *sign, int legacy);
int pgp_hash_data_final(struct pgp_pkt *sign);
int pgp_armor_all(FILE *fp, struct pgp_pkt *pkt, char *header);

#ifdef PGP_DEBUG
void pgp_showpkt(struct pgp_pkt *pkt);
#endif /* PGP_DEBUG */

extern u_char	pgp_nullkeyid[];
