/* opencdk.h - Open Crypto Development Kit (OpenCDK)
 *        Copyright (C) 2001, 2002, 2003 Timo Schulz
 *
 * This file is part of OpenCDK.
 *
 * OpenCDK is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * OpenCDK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with OpenCDK; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef OPENCDK_H
#define OPENCDK_H

#include <stdarg.h>

#define OPENCDK_VERSION "0.4.5"

#ifdef __cplusplus
extern "C" {
#endif
    
/* General contexts */
struct cdk_handle_s;
typedef struct cdk_handle_s *CDK_HD;

struct cdk_string_list_s;
typedef struct cdk_string_list_s *CDK_STRLIST;

struct cdk_sesskey_s;
typedef struct cdk_sesskey_s *CDK_SESSKEY;
    
struct cdk_mpi_s;
typedef struct cdk_mpi_s *CDK_MPI;

struct cdk_dek_s;
typedef struct cdk_dek_s *CDK_DEK;

struct cdk_s2k_hd_s;
typedef struct cdk_s2k_hd_s *CDK_S2K_HD;

struct cdk_stream_context_s;
typedef struct cdk_stream_context_s *CDK_STREAM;

struct cdk_prefitem_s;
typedef struct cdk_prefitem_s *CDK_PREFITEM;

struct cdk_kbnode_s;
typedef struct cdk_kbnode_s *CDK_KBNODE;

struct cdk_keydb_handle_s;
typedef struct cdk_keydb_handle_s *CDK_KEYDB_HD;

struct cdk_keydb_search_s;
typedef struct cdk_keydb_search_s *CDK_DBSEARCH;

struct cdk_key_list_s;
typedef struct cdk_key_list_s *CDK_KEYLIST;

struct cdk_subpkt_s;
typedef struct cdk_subpkt_s *CDK_SUBPKT;

struct cdk_keygen_s;
typedef struct cdk_keygen_s *CDK_KEYGEN_CTX;


typedef enum
{
  CDK_EOF = -1,
  CDK_Success = 0,
  CDK_General_Error = 1,
  CDK_File_Error = 2,
  CDK_Bad_Sig = 3,
  CDK_Inv_Packet = 4,
  CDK_Inv_Algo = 5,
  CDK_Not_Implemented = 6,
  CDK_Gcry_Error = 7,
  CDK_Armor_Error = 8,
  CDK_Armor_CRC_Error = 9,
  CDK_MPI_Error = 10,
  CDK_Inv_Value = 11,
  CDK_Error_No_Key = 12,
  CDK_Chksum_Error = 13,
  CDK_Time_Conflict = 14,
  CDK_Zlib_Error = 15,
  CDK_Weak_Key = 16,
  CDK_Out_Of_Core = 17,
  CDK_Wrong_Seckey = 18,
  CDK_Bad_MDC = 19,
  CDK_Inv_Mode = 20,
  CDK_Error_No_Keyring = 21,
  CDK_Wrong_Format = 22,
  CDK_Inv_Packet_Ver = 23,
  CDK_Too_Short = 24,
  CDK_Unusable_Key = 25,
} cdk_error_t;


enum
{
  CDK_CTLF_SET          =  0,
  CDK_CTLF_GET          =  1,
  CDK_CTL_DIGEST        = 10,
  CDK_CTL_CIPHER        = 11,
  CDK_CTL_ARMOR         = 12,
  CDK_CTL_COMPRESS      = 13,
  CDK_CTL_COMPAT        = 14,
  CDK_CTL_OVERWRITE     = 15,
  CDK_CTL_S2K           = 16,
  CDK_CTL_KEYCACHE_ON   = 17,
  CDK_CTL_KEYCACHE_FREE = 18,
  CDK_CTL_FORCE_DIGEST  = 19,
  CDK_CTL_TRUSTMODEL    = 20
};

enum
{
  CDK_LOG_NONE  = 0,
  CDK_LOG_INFO  = 1,
  CDK_LOG_DEBUG = 2
};

enum
{
  CDK_COMPRESS_NONE = 0,
  CDK_COMPRESS_ZIP  = 1,
  CDK_COMPRESS_ZLIB = 2
};

enum
{
  CDK_PK_RSA   =  1,
  CDK_PK_RSA_E =  2,
  CDK_PK_RSA_S =  3,
  CDK_PK_ELG_E = 16,
  CDK_PK_DSA   = 17,
  CDK_PK_ELG   = 20
};

enum
{
  CDK_MD_NONE    = 0,
  CDK_MD_MD5     = 1,
  CDK_MD_SHA1    = 2,
  CDK_MD_RMD160  = 3,
  CDK_MD_MD2     = 5,
  CDK_MD_TIGER   = 6,
  CDK_MD_SHA256  = 8,
};

enum
{
  CDK_CIPHER_NONE        = 0,
  CDK_CIPHER_IDEA        = 1,
  CDK_CIPHER_3DES        = 2,
  CDK_CIPHER_CAST5       = 3,
  CDK_CIPHER_BLOWFISH    = 4,
  CDK_CIPHER_SAFER_SK128 = 5,
  CDK_CIPHER_DES_SK      = 6,
  CDK_CIPHER_AES         = 7,
  CDK_CIPHER_AES192      = 8,
  CDK_CIPHER_AES256      = 9,
  CDK_CIPHER_TWOFISH     = 10,
};

enum
{
  CDK_PREFTYPE_NONE = 0,
  CDK_PREFTYPE_SYM  = 1,
  CDK_PREFTYPE_HASH = 2,
  CDK_PREFTYPE_ZIP  = 3
};

enum
{
  CDK_REVCOD_NOREASON   = 0x00,
  CDK_REVCOD_SUPERCEDED = 0x01,
  CDK_REVCOD_COMPROMISED= 0x02,
  CDK_REVCOD_NOLONGUSED = 0x03
};

enum
{
  CDK_ARMOR_MESSAGE   = 0,
  CDK_ARMOR_PUBKEY    = 1,
  CDK_ARMOR_SECKEY    = 2,
  CDK_ARMOR_SIGNATURE = 3,
  CDK_ARMOR_CLEARSIG  = 4,
};

enum
{
  CDK_STREAMCTL_RESET   = 1,
  CDK_STREAMCTL_DISABLE = 2,
};

enum
{
  CDK_DBSEARCH_EXACT       =   1,
  CDK_DBSEARCH_SUBSTR      =   2,
  CDK_DBSEARCH_SHORT_KEYID =   3,
  CDK_DBSEARCH_KEYID       =   4,
  CDK_DBSEARCH_FPR         =   5,
  CDK_DBTYPE_PK_KEYRING    = 100,
  CDK_DBTYPE_SK_KEYRING    = 101,
  CDK_DBTYPE_DATA          = 102
};

/* compatibilty */
#define CDK_DBTYPE_ARMORED 100
#define CDK_DBTYPE_KEYRING 100


enum
{
  CDK_CRYPTYPE_NONE    = 0,
  CDK_CRYPTYPE_ENCRYPT = 1,
  CDK_CRYPTYPE_DECRYPT = 2,
  CDK_CRYPTYPE_SIGN    = 3,
  CDK_CRYPTYPE_VERIFY  = 4,
  CDK_CRYPTYPE_EXPORT  = 5,
  CDK_CRYPTYPE_IMPORT  = 6
};

enum
{
  CDK_KEY_VALID   = 0,
  CDK_KEY_INVALID = 1, /* missing or wrong self signature */
  CDK_KEY_EXPIRED = 2,
  CDK_KEY_REVOKED = 4
};

enum
{
  CDK_TRUST_UNKNOWN     =   0,
  CDK_TRUST_EXPIRED     =   1,
  CDK_TRUST_UNDEFINED   =   2,
  CDK_TRUST_NEVER       =   3,
  CDK_TRUST_MARGINAL    =   4,
  CDK_TRUST_FULLY       =   5,
  CDK_TRUST_ULTIMATE    =   6,
  CDK_TFLAG_REVOKED     =  32,
  CDK_TFLAG_SUB_REVOKED =  64,
  CDK_TFLAG_DISABLED    = 128
};


enum
{
  /* signature status */
  CDK_SIGSTAT_NONE  = 0,
  CDK_SIGSTAT_GOOD  = 1,
  CDK_SIGSTAT_BAD   = 2,
  CDK_SIGSTAT_NOKEY = 3,
  /* signature modes */
  CDK_SIGMODE_NORMAL   = 100,
  CDK_SIGMODE_DETACHED = 101,
  CDK_SIGMODE_CLEAR    = 102
};

enum
{
  /* cdk attributes */
  CDK_ATTR_CREATED  = 1,
  CDK_ATTR_EXPIRE   = 2,
  CDK_ATTR_KEYID    = 3,
  CDK_ATTR_STATUS   = 4,
  CDK_ATTR_NOTATION = 5,
  CDK_ATTR_ALGO_PK  = 6,
  CDK_ATTR_ALGO_MD  = 7,
  CDK_ATTR_VERSION  = 8,
  CDK_ATTR_LEN      = 9,
  CDK_ATTR_FLAGS    = 10,
  CDK_ATTR_MPI      = 11,
  /* cdk key flags */
  CDK_FLAG_KEY_REVOKED = 256,
  CDK_FLAG_KEY_EXPIRED = 512,
  CDK_FLAG_SIG_EXPIRED = 1024,  
};


enum
{
  CDK_CB_NONE       = 0,
  CDK_CB_PUBKEY_ENC = 1
};


typedef enum
{
  CDK_PKT_RESERVED      =  0,
  CDK_PKT_PUBKEY_ENC    =  1,
  CDK_PKT_SIGNATURE     =  2,
  CDK_PKT_SYMKEY_ENC    =  3,
  CDK_PKT_ONEPASS_SIG   =  4,
  CDK_PKT_SECRET_KEY    =  5,
  CDK_PKT_PUBLIC_KEY    =  6,
  CDK_PKT_SECRET_SUBKEY =  7,
  CDK_PKT_COMPRESSED    =  8,
  CDK_PKT_ENCRYPTED     =  9,
  CDK_PKT_MARKER        = 10,
  CDK_PKT_PLAINTEXT     = 11,
  CDK_PKT_RING_TRUST    = 12,
  CDK_PKT_USER_ID       = 13,
  CDK_PKT_PUBLIC_SUBKEY = 14,
  CDK_PKT_OLD_COMMENT   = 16,
  CDK_PKT_ATTRIBUTE     = 17,
  CDK_PKT_ENCRYPTED_MDC = 18,
  CDK_PKT_MDC           = 19,
} cdk_packet_types_t;

#define CDK_PKT_IS_ENCRYPTED(pkttype) \
(((pkttype) == CDK_PKT_ENCRYPTED_MDC) || ((pkttype) == CDK_PKT_ENCRYPTED))

typedef struct
{
  unsigned long len;
  unsigned is_primary:1;
  unsigned is_revoked:1;
  unsigned mdc_feature:1;
  CDK_PREFITEM prefs;
  unsigned char * attrib_img; /* Tag 17 if not null */
  size_t attrib_len;
  size_t prefs_size;
  unsigned long created;
  char name[1];
} cdkPKT_user_id;


typedef struct
{
  unsigned char version;
  unsigned char pubkey_algo;
  unsigned long keyid[2];
  unsigned long main_keyid[2];
  unsigned long timestamp;
  unsigned long expiredate;
  CDK_MPI mpi[4];
  unsigned is_revoked:1;
  unsigned is_invalid:1;
  unsigned has_expired:1;
  int pubkey_usage;
  cdkPKT_user_id * uid;
  CDK_PREFITEM prefs;
  size_t prefs_size;
} cdkPKT_public_key;


typedef struct
{
  cdkPKT_public_key * pk;
  unsigned long expiredate;
  int version;
  int pubkey_algo;
  unsigned long keyid[2];
  unsigned long main_keyid[2];
  unsigned char s2k_usage;
  struct
  {
    unsigned char algo;
    unsigned char sha1chk; /* SHA1 is used instead of a 16 bit checksum */
    CDK_S2K_HD s2k;
    unsigned char iv[16];
    unsigned char ivlen;
  } protect;
  unsigned short csum;
  CDK_MPI mpi[4];
  unsigned char * encdata;
  size_t enclen;
  unsigned char is_protected;
  unsigned is_primary:1;
  unsigned has_expired:1;
  unsigned is_revoked:1;
} cdkPKT_secret_key;


typedef struct
{
  unsigned char version;
  unsigned char sig_class;
  unsigned long timestamp;
  unsigned long expiredate;
  unsigned long keyid[2];
  unsigned char pubkey_algo;
  unsigned char digest_algo;
  unsigned char digest_start[2];
  unsigned short hashed_size;
  CDK_SUBPKT hashed;
  unsigned short unhashed_size;
  CDK_SUBPKT unhashed;
  CDK_MPI mpi[2];
  struct
  {
    unsigned exportable:1;
    unsigned revocable:1;
    unsigned policy_url:1;
    unsigned notation:1;
    unsigned expired:1;
    unsigned checked:1;
    unsigned valid:1;
    unsigned missing_key:1;
  } flags;  
  unsigned long key[2]; /* only valid for key signatures */
} cdkPKT_signature;


typedef struct
{
  unsigned char version;
  unsigned long keyid[2];
  unsigned char sig_class;
  unsigned char digest_algo;
  unsigned char pubkey_algo;
  unsigned char last;
} cdkPKT_onepass_sig;


typedef struct
{
  unsigned char version;
  unsigned long keyid[2];
  int throw_keyid;
  unsigned char pubkey_algo;
  CDK_MPI mpi[2];
} cdkPKT_pubkey_enc;


typedef struct
{
  unsigned char version;
  unsigned char cipher_algo;
  CDK_S2K_HD s2k;
  unsigned char seskeylen;
  unsigned char seskey[32];
} cdkPKT_symkey_enc;


typedef struct
{
  unsigned long len;
  int extralen;
  unsigned char mdc_method;
  CDK_STREAM buf;
} cdkPKT_encrypted;


typedef struct
{
  unsigned char hash[20];
} cdkPKT_mdc;


typedef struct
{
  unsigned long len;
  CDK_STREAM buf;
  int mode;
  unsigned long timestamp;
  int namelen;
  char name[1];
} cdkPKT_plaintext;


typedef struct
{
  int len;
  int algorithm;
  CDK_STREAM buf;
} cdkPKT_compressed;


struct cdk_packet_s
{
  size_t pktlen; /* real packet length */
  size_t pktsize; /* length with all headers */
  int old_ctb;
  cdk_packet_types_t pkttype;
  union
  {
    cdkPKT_mdc * mdc;
    cdkPKT_user_id * user_id;
    cdkPKT_public_key * public_key;
    cdkPKT_secret_key * secret_key;
    cdkPKT_signature * signature;
    cdkPKT_pubkey_enc * pubkey_enc;
    cdkPKT_symkey_enc * symkey_enc;
    cdkPKT_compressed * compressed;
    cdkPKT_encrypted * encrypted;
    cdkPKT_plaintext * plaintext;
    cdkPKT_onepass_sig * onepass_sig;
  } pkt;
};
typedef struct cdk_packet_s CDK_PACKET;


/*-- main.c --*/
/* memory routines */
typedef void (*CDK_LOG_FNC) (void *, int, const char *, va_list);
void cdk_set_log_level (int lvl);
void cdk_set_log_handler (CDK_LOG_FNC logfnc, void * opaque);
const char* cdk_strerror (int ec);
void cdk_set_malloc_hooks (void *(*new_alloc_func) (size_t n),
                           void *(*new_alloc_secure_func) (size_t n),
                           void *(*new_realloc_func) (void * p, size_t n),
                           void *(*new_calloc_func) (size_t m, size_t n),
                           void (*new_free_func) (void *));
int cdk_malloc_hook_initialized (void);
void * cdk_malloc (size_t size);
void * cdk_calloc (size_t n, size_t m);
void * cdk_realloc (void * ptr, size_t size);
void * cdk_salloc (size_t size, int clear);
char * cdk_strdup (const char * ptr);
void cdk_free (void * ptr);
/* session handle routines */
int cdk_handle_new (CDK_HD * r_ctx);
void cdk_handle_free (CDK_HD c);
void cdk_handle_set_keydb (CDK_HD hd, CDK_KEYDB_HD db);
CDK_KEYDB_HD cdk_handle_get_keydb( CDK_HD hd, int type );
int cdk_handle_control( CDK_HD hd, int action, int cmd, ... );
void cdk_handle_set_callback (CDK_HD hd,
                              void (*cb) (void *opa, int type, const char * s),
                              void * cb_value);
void cdk_handle_set_passphrase_cb( CDK_HD hd,
                                   char *(*cb) (void *opa, const char *prompt),
                                   void * cb_value );

/* shortcuts for some controls */
#define cdk_handle_set_armor( a, val ) \
  cdk_handle_control( (a), CDK_CTLF_SET, CDK_CTL_ARMOR, (val) )

#define cdk_handle_set_compress( a, algo, level ) \
  cdk_handle_control( (a), CDK_CTLF_SET, CDK_CTL_COMPRESS, (algo), (level) )


/*-- cipher.c --*/
void cdk_set_progress_handler (void (*cb)(void * hd, unsigned off,
                                          unsigned size), void * cb_value);

/*-- new-packet.c --*/
int cdk_pkt_new (CDK_PACKET ** r_pkt);
void cdk_pkt_init( CDK_PACKET * pkt );
int cdk_pkt_alloc (CDK_PACKET ** r_pkt, int id);
void cdk_pkt_free (CDK_PACKET * pkt);
void cdk_pkt_release (CDK_PACKET * pkt);
int cdk_pkt_parse (CDK_STREAM inp, CDK_PACKET * pkt);
int cdk_pkt_build (CDK_STREAM out, CDK_PACKET * pkt);
/* sub packet routines */
CDK_SUBPKT cdk_subpkt_new (size_t size);
void cdk_subpkt_free (CDK_SUBPKT ctx);
CDK_SUBPKT cdk_subpkt_find (CDK_SUBPKT ctx, int type);
const unsigned char * cdk_subpkt_get_buf (CDK_SUBPKT ctx,
                                          int * r_type,
                                          size_t * r_nbytes);
unsigned char  * cdk_prefs_get_array( cdkPKT_user_id * id, int type,
                                      size_t *ret_len );

/*-- pubkey.c --*/
#define is_RSA(a) ((a) == CDK_PK_RSA \
                   || (a) == CDK_PK_RSA_E \
                   || (a) == CDK_PK_RSA_S)
#define is_ELG(a) ((a) == CDK_PK_ELG || (a) == CDK_PK_ELG_E)
#define is_DSA(a) ((a) == CDK_PK_DSA)

int cdk_pk_encrypt (cdkPKT_public_key * pk, cdkPKT_pubkey_enc * pke,
                    CDK_SESSKEY esk);
int cdk_pk_decrypt (cdkPKT_secret_key * sk, cdkPKT_pubkey_enc * pke,
                    CDK_SESSKEY *r_sk);
int cdk_pk_sign (cdkPKT_secret_key * sk, cdkPKT_signature * sig,
                 const unsigned char * md);
int cdk_pk_verify (cdkPKT_public_key * pk, cdkPKT_signature * sig,
                   const unsigned char * md);
int cdk_pk_get_mpi (cdkPKT_public_key * pk, int idx,
                    unsigned char * buf, size_t * r_count, size_t * r_nbits);
int cdk_sk_get_mpi (cdkPKT_secret_key * sk, int idx,
                    unsigned char * buf, size_t * r_count, size_t * r_nbits);
int cdk_pk_get_nbits (cdkPKT_public_key * pk);
int cdk_pk_get_npkey (int algo);
int cdk_pk_get_nskey (int algo);
int cdk_pk_get_nsig (int algo);
int cdk_pk_get_nenc (int algo);
int cdk_pk_get_fingerprint (cdkPKT_public_key * pk, unsigned char * fpr);
unsigned long cdk_pk_fingerprint_get_keyid (const unsigned char * fpr,
                                            size_t fprlen,
                                            unsigned long * keyid);
unsigned long cdk_pk_get_keyid (cdkPKT_public_key * pk, unsigned long * keyid);
unsigned long cdk_sk_get_keyid (cdkPKT_secret_key * sk, unsigned long * keyid);
unsigned long cdk_sig_get_keyid (cdkPKT_signature * sg, unsigned long * keyid);
int cdk_sk_unprotect (cdkPKT_secret_key * sk, const char * pw);
int cdk_sk_protect (cdkPKT_secret_key * sk, const char * pw);
int cdk_pk_from_secret_key( cdkPKT_secret_key * sk,
                            cdkPKT_public_key ** ret_pk );

/*-- seskey.c --*/
int cdk_sesskey_new( CDK_SESSKEY * r_sk );
void cdk_sesskey_free( CDK_SESSKEY sk );
int cdk_dek_new( CDK_DEK * r_dek );
void cdk_dek_free( CDK_DEK dek );
int cdk_dek_set_cipher( CDK_DEK dek, int algo );
int cdk_dek_set_key( CDK_DEK dek, const unsigned char *key, size_t keylen );
int cdk_dek_from_passphrase( CDK_DEK * ret_dek, int cipher_algo,
                             CDK_S2K_HD s2k, int mode, const char * pw );
int cdk_dek_encode_pkcs1( CDK_DEK dek, int nbits, CDK_SESSKEY * r_esk );
int cdk_dek_decode_pkcs1( CDK_DEK * ret_dek, CDK_SESSKEY esk );
int cdk_dek_extract( CDK_DEK * ret_dek, CDK_HD hd, cdkPKT_pubkey_enc * enc,
                     cdkPKT_secret_key * sk );
void cdk_dek_set_mdc_flag( CDK_DEK dek, int val );
/* string to key */
int cdk_s2k_new (CDK_S2K_HD * ret_s2k, int mode, int algo,
                 const unsigned char * salt);
void cdk_s2k_free (CDK_S2K_HD s2k);

/*-- armor.c --*/
int cdk_file_armor (CDK_HD hd, const char * file, const char * output);
int cdk_file_dearmor (const char * file, const char * output);
int cdk_armor_filter_use (CDK_STREAM inp);

/*-- stream.c --*/
int cdk_stream_control (CDK_STREAM s, int ctl, int val);
int cdk_stream_open (const char * file, CDK_STREAM * ret_s);
int cdk_stream_new (const char * file, CDK_STREAM * ret_s);
int cdk_stream_create (const char * file, CDK_STREAM * ret_s);
CDK_STREAM cdk_stream_tmp (void);
CDK_STREAM cdk_stream_tmp_from_mem (const void * buf, size_t count);
void cdk_stream_tmp_set_mode (CDK_STREAM s, int val);
CDK_STREAM cdk_stream_fpopen (FILE * fp, unsigned write_mode);
int cdk_stream_flush (CDK_STREAM s);
int cdk_stream_set_cache (CDK_STREAM s, int val);
int cdk_stream_filter_disable (CDK_STREAM s, int type);
int cdk_stream_close (CDK_STREAM s);
unsigned cdk_stream_get_length (CDK_STREAM s);
int cdk_stream_read (CDK_STREAM s, void * buf, size_t count);
int cdk_stream_write (CDK_STREAM s, const void * buf, size_t count);
int cdk_stream_putc (CDK_STREAM s, int c);
int cdk_stream_getc (CDK_STREAM s);
int cdk_stream_eof (CDK_STREAM s);
long cdk_stream_tell (CDK_STREAM s);
int cdk_stream_seek (CDK_STREAM s, long offset);
int cdk_stream_set_armor_flag (CDK_STREAM s, int type);
int cdk_stream_set_literal_flag (CDK_STREAM s, int mode, const char * fname);
int cdk_stream_set_cipher_flag (CDK_STREAM s, CDK_DEK dek, int use_mdc);
int cdk_stream_set_compress_flag (CDK_STREAM s, int algo, int level);
int cdk_stream_set_hash_flag (CDK_STREAM s, int algo);
int cdk_stream_set_text_flag (CDK_STREAM s, const char * lf);
int cdk_stream_kick_off (CDK_STREAM inp, CDK_STREAM out);
int cdk_stream_mmap( CDK_STREAM s, unsigned char ** ret_buf,
                     size_t * ret_count );

/*-- keydb.c --*/
int cdk_keydb_new (CDK_KEYDB_HD * r_hd, int type, void * data, size_t count);
int cdk_keydb_open (CDK_KEYDB_HD hd, CDK_STREAM * ret_kr);
int cdk_keydb_check_sk( CDK_KEYDB_HD hd, unsigned long * keyid );
int cdk_keydb_search_new (CDK_DBSEARCH * r_dbs, int type, void * desc);
void cdk_keydb_search_free (CDK_DBSEARCH dbs);
int cdk_keydb_search (CDK_KEYDB_HD hd, CDK_DBSEARCH ks, CDK_KBNODE * ret_key);
int cdk_keydb_search_auto (CDK_KEYDB_HD hd, const char *desc,
                           CDK_KBNODE * ret_key);
void cdk_keydb_free (CDK_KEYDB_HD hd);
int cdk_keydb_get_bykeyid (CDK_KEYDB_HD hd, unsigned long * keyid,
                           CDK_KBNODE * ret_key);
int cdk_keydb_get_byfpr (CDK_KEYDB_HD hd, const unsigned char * fpr,
                         CDK_KBNODE * ret_key);
int cdk_keydb_get_bypattern (CDK_KEYDB_HD hd, const char * patt,
                             CDK_KBNODE * ret_key);
int cdk_keydb_get_pk (CDK_KEYDB_HD khd, unsigned long * keyid,
                      cdkPKT_public_key ** ret_pk);
int cdk_keydb_get_sk (CDK_KEYDB_HD khd, unsigned long * keyid,
                      cdkPKT_secret_key ** ret_sk);
int cdk_keydb_get_keyblock (CDK_STREAM inp, CDK_KBNODE * ret_key);
int cdk_keydb_idx_rebuild( CDK_KEYDB_HD hd );
int cdk_keydb_export (CDK_KEYDB_HD hd, CDK_STREAM out, CDK_STRLIST remusr);
int cdk_keydb_import (CDK_KEYDB_HD hd, CDK_KBNODE knode, int result[4]);

/*-- kbnode.c --*/
CDK_KBNODE cdk_kbnode_new (CDK_PACKET * pkt);
int cdk_kbnode_read_from_mem (CDK_KBNODE * ret_node,
                             const unsigned char * buf, size_t buflen);
int cdk_kbnode_write_to_mem (CDK_KBNODE node,
                             unsigned char * buf, size_t * r_nbytes);
void cdk_kbnode_release (CDK_KBNODE node);
CDK_KBNODE cdk_kbnode_walk (CDK_KBNODE root, CDK_KBNODE * ctx, int all);
CDK_PACKET * cdk_kbnode_find_packet (CDK_KBNODE node, int pkttype);
CDK_PACKET * cdk_kbnode_get_packet (CDK_KBNODE node);
CDK_KBNODE cdk_kbnode_find (CDK_KBNODE node, int pkttype);
CDK_KBNODE cdk_kbnode_find_prev (CDK_KBNODE root, CDK_KBNODE node, int pkttyp);
CDK_KBNODE cdk_kbnode_find_next (CDK_KBNODE node, int pkttype);

/*-- sig-check.c --*/
int cdk_pk_check_sigs (CDK_KBNODE knode, CDK_KEYDB_HD hd, int * r_status);
#define cdk_key_check_sigs cdk_pk_check_sigs

/*-- keylist.c --*/
int cdk_pklist_select_algo (CDK_KEYLIST pkl);
int cdk_pklist_use_mdc (CDK_KEYLIST pkl);
int cdk_pklist_build (CDK_KEYDB_HD hd, CDK_STRLIST remusr,
                      CDK_KEYLIST * ret_pkl, int use);
void cdk_pklist_release (CDK_KEYLIST pkl);
int cdk_pklist_encrypt (CDK_KEYLIST pkl, CDK_DEK dek, CDK_STREAM out);
/* secret key list */
int cdk_sklist_build( CDK_KEYDB_HD db, CDK_HD hd, CDK_STRLIST locusr,
                      CDK_KEYLIST * ret_skl, int unlock, unsigned int use );
void cdk_sklist_release (CDK_KEYLIST skl);
int cdk_sklist_write (CDK_KEYLIST skl, CDK_STREAM outp, void * mdctx,
                      int sigclass, int sigver);
int cdk_sklist_write_onepass( CDK_KEYLIST skl, CDK_STREAM outp,
                              int sigclass, int mdalgo );

/*-- encrypt.c --*/
int cdk_stream_encrypt (CDK_HD hd, CDK_STRLIST remusr,
                        CDK_STREAM inp, CDK_STREAM out);
int cdk_file_encrypt (CDK_HD hd, CDK_STRLIST remusr,
                      const char * file, const char * output);
int cdk_file_decrypt (CDK_HD hd, const char * file, const char * output);
int cdk_data_transform( CDK_HD hd, int mode,
                        CDK_STRLIST locusr, CDK_STRLIST remusr,
                        const void * inbuf, size_t insize,
                        unsigned char ** outbuf, size_t * outsize,
                        int modval );

/*-- sign.c --*/
int cdk_stream_sign( CDK_HD hd, CDK_STREAM inp, CDK_STREAM out,
                     CDK_STRLIST locusr, CDK_STRLIST remusr,
                     int encryptflag, int sigmode );
int cdk_file_sign (CDK_HD hd, CDK_STRLIST locusr, CDK_STRLIST remusr,
                   const char * file, const char * output,
                   int sigmode, int encryptflag);

/*-- verify.c --*/
int cdk_stream_verify( CDK_HD hd, CDK_STREAM inp, CDK_STREAM out );
int cdk_file_verify (CDK_HD hd, const char * file, const char * output);
unsigned long cdk_sig_get_ulong_attr (CDK_HD hd, int idx, int what);
const void * cdk_sig_get_data_attr (CDK_HD hd, int idx, int what);
unsigned char * cdk_sig_get_info_as_xml( CDK_HD hd, int advanced );

/*-- trustdb.c --*/
int cdk_trustdb_get_validity (CDK_STREAM inp, cdkPKT_user_id * id, int *r_val);
int cdk_trustdb_get_ownertrust (CDK_STREAM inp, cdkPKT_public_key * pk,
                                int * r_val, int * r_flags);

/*-- misc.c --*/
void cdk_strlist_free (CDK_STRLIST sl);
CDK_STRLIST cdk_strlist_add (CDK_STRLIST * list, const char * string);
const char * cdk_strlist_walk (CDK_STRLIST root, CDK_STRLIST * context);
const char * cdk_check_version (const char * req_version);
/* UTF8 */
char * cdk_utf8_encode (const char * string);
char * cdk_utf8_decode (const char * string, size_t length, int delim);

/*-- keyserver.c --*/
int cdk_keyserver_recv_key (const char * host, int port,
                            const unsigned char * keyid, int kid_type,
                            CDK_KBNODE * r_key);

/*-- keygen.c --*/
int cdk_keygen_new (CDK_KEYGEN_CTX * r_hd);
void cdk_keygen_free (CDK_KEYGEN_CTX hd);
int cdk_keygen_set_prefs (CDK_KEYGEN_CTX hd, int type,
                          const unsigned char * array, size_t n);
int cdk_keygen_set_algo_info (CDK_KEYGEN_CTX hd, int type, int algo, int bits);
void cdk_keygen_set_mdc_feature (CDK_KEYGEN_CTX hd, int val);
void cdk_keygen_set_expire_date (CDK_KEYGEN_CTX hd, int type, long timestamp);
void cdk_keygen_set_name (CDK_KEYGEN_CTX hd, const char * name);
void cdk_keygen_set_passphrase (CDK_KEYGEN_CTX hd, const char * pass);
int cdk_keygen_start (CDK_KEYGEN_CTX hd);
int cdk_keygen_save (CDK_KEYGEN_CTX hd, const char * pub, const char * sec);

#ifdef __cplusplus
}
#endif 

#endif /* OPENCDK_H */

