/* opencdk.h - Open Crypto Development Kit (OpenCDK)
* Copyright (C) 2001-2012 Free Software Foundation, Inc.
*
* Author: Timo Schulz
*
* This file is part of OpenCDK.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see
*
*/
#ifndef OPENCDK_H
#define OPENCDK_H
#include
#include
#include /* for size_t */
#include
#include
#include
#include
#include
/* The OpenCDK version as a string. */
#define OPENCDK_VERSION "0.6.6"
/* The OpenCDK version as integer components major.minor.path */
#define OPENCDK_VERSION_MAJOR 0
#define OPENCDK_VERSION_MINOR 6
#define OPENCDK_VERSION_PATCH 6
#ifdef __cplusplus
extern "C" {
#endif
/* General contexts */
/* 'Session' handle to support the various options and run-time
information. */
struct cdk_ctx_s;
typedef struct cdk_ctx_s *cdk_ctx_t;
/* A generic context to store list of strings. */
struct cdk_strlist_s;
typedef struct cdk_strlist_s *cdk_strlist_t;
/* Context used to list keys of a keyring. */
struct cdk_listkey_s;
typedef struct cdk_listkey_s *cdk_listkey_t;
/* Opaque String to Key (S2K) handle. */
struct cdk_s2k_s;
typedef struct cdk_s2k_s *cdk_s2k_t;
/* Abstract I/O object, a stream, which is used for most operations. */
struct cdk_stream_s;
typedef struct cdk_stream_s *cdk_stream_t;
/* Opaque handle for the user ID preferences. */
struct cdk_prefitem_s;
typedef struct cdk_prefitem_s *cdk_prefitem_t;
/* Node to store a single key node packet. */
struct cdk_kbnode_s;
typedef struct cdk_kbnode_s *cdk_kbnode_t;
/* Key database handle. */
struct cdk_keydb_hd_s;
typedef struct cdk_keydb_hd_s *cdk_keydb_hd_t;
struct cdk_keydb_search_s;
typedef struct cdk_keydb_search_s *cdk_keydb_search_t;
/* Context to store a list of recipient keys. */
struct cdk_keylist_s;
typedef struct cdk_keylist_s *cdk_keylist_t;
/* Context to encapsulate a single sub packet of a signature. */
struct cdk_subpkt_s;
typedef struct cdk_subpkt_s *cdk_subpkt_t;
/* Context used to generate key pairs. */
struct cdk_keygen_ctx_s;
typedef struct cdk_keygen_ctx_s *cdk_keygen_ctx_t;
/* Handle for a single designated revoker. */
struct cdk_desig_revoker_s;
typedef struct cdk_desig_revoker_s *cdk_desig_revoker_t;
/* Alias for backward compatibility. */
typedef bigint_t cdk_mpi_t;
/* All valid error constants. */
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_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_No_Data = 26,
CDK_No_Passphrase = 27,
CDK_Network_Error = 28
} cdk_error_t;
enum cdk_control_flags {
CDK_CTLF_SET = 0, /* Value to set an option */
CDK_CTLF_GET = 1, /* Value to get an option */
CDK_CTL_DIGEST = 10, /* Option to set the digest algorithm. */
CDK_CTL_ARMOR = 12, /* Option to enable armor output. */
CDK_CTL_COMPRESS = 13, /* Option to enable compression. */
CDK_CTL_COMPAT = 14, /* Option to switch in compat mode. */
CDK_CTL_OVERWRITE = 15, /* Option to enable file overwritting. */
CDK_CTL_S2K = 16, /* Option to set S2K values. */
CDK_CTL_FORCE_DIGEST = 19, /* Force the use of a digest algorithm. */
CDK_CTL_BLOCKMODE_ON = 20 /* Enable partial body lengths */
};
/* Specifies all valid log levels. */
enum cdk_log_level_t {
CDK_LOG_NONE = 0, /* No log message will be shown. */
CDK_LOG_INFO = 1,
CDK_LOG_DEBUG = 2,
CDK_LOG_DEBUG_PKT = 3
};
/* All valid compression algorithms in OpenPGP */
enum cdk_compress_algo_t {
CDK_COMPRESS_NONE = 0,
CDK_COMPRESS_ZIP = 1,
CDK_COMPRESS_ZLIB = 2,
CDK_COMPRESS_BZIP2 = 3 /* Not supported in this version */
};
/* All valid public key algorithms valid in OpenPGP */
enum cdk_pubkey_algo_t {
CDK_PK_UNKNOWN = 0,
CDK_PK_RSA = 1,
CDK_PK_RSA_E = 2, /* RSA-E and RSA-S are deprecated use RSA instead */
CDK_PK_RSA_S = 3, /* and use the key flags in the self signatures. */
CDK_PK_ELG_E = 16,
CDK_PK_DSA = 17
};
/* The valid 'String-To-Key' modes */
enum cdk_s2k_type_t {
CDK_S2K_SIMPLE = 0,
CDK_S2K_SALTED = 1,
CDK_S2K_ITERSALTED = 3,
CDK_S2K_GNU_EXT = 101
/* GNU extensions: refer to DETAILS from GnuPG:
http://cvs.gnupg.org/cgi-bin/viewcvs.cgi/trunk/doc/DETAILS?root=GnuPG
*/
};
/* The different kind of user ID preferences. */
enum cdk_pref_type_t {
CDK_PREFTYPE_NONE = 0,
CDK_PREFTYPE_SYM = 1, /* Symmetric ciphers */
CDK_PREFTYPE_HASH = 2, /* Message digests */
CDK_PREFTYPE_ZIP = 3 /* Compression algorithms */
};
/* All valid sub packet types. */
enum cdk_sig_subpacket_t {
CDK_SIGSUBPKT_NONE = 0,
CDK_SIGSUBPKT_SIG_CREATED = 2,
CDK_SIGSUBPKT_SIG_EXPIRE = 3,
CDK_SIGSUBPKT_EXPORTABLE = 4,
CDK_SIGSUBPKT_TRUST = 5,
CDK_SIGSUBPKT_REGEXP = 6,
CDK_SIGSUBPKT_REVOCABLE = 7,
CDK_SIGSUBPKT_KEY_EXPIRE = 9,
CDK_SIGSUBPKT_PREFS_SYM = 11,
CDK_SIGSUBPKT_REV_KEY = 12,
CDK_SIGSUBPKT_ISSUER = 16,
CDK_SIGSUBPKT_NOTATION = 20,
CDK_SIGSUBPKT_PREFS_HASH = 21,
CDK_SIGSUBPKT_PREFS_ZIP = 22,
CDK_SIGSUBPKT_KS_FLAGS = 23,
CDK_SIGSUBPKT_PREF_KS = 24,
CDK_SIGSUBPKT_PRIMARY_UID = 25,
CDK_SIGSUBPKT_POLICY = 26,
CDK_SIGSUBPKT_KEY_FLAGS = 27,
CDK_SIGSUBPKT_SIGNERS_UID = 28,
CDK_SIGSUBPKT_REVOC_REASON = 29,
CDK_SIGSUBPKT_FEATURES = 30
};
/* All valid armor types. */
enum cdk_armor_type_t {
CDK_ARMOR_MESSAGE = 0,
CDK_ARMOR_PUBKEY = 1,
CDK_ARMOR_SECKEY = 2,
CDK_ARMOR_SIGNATURE = 3,
CDK_ARMOR_CLEARSIG = 4
};
enum cdk_keydb_flag_t {
/* Valid database search modes */
CDK_DBSEARCH_EXACT = 1, /* Exact string search */
CDK_DBSEARCH_SUBSTR = 2, /* Sub string search */
CDK_DBSEARCH_SHORT_KEYID = 3, /* 32-bit keyid search */
CDK_DBSEARCH_KEYID = 4, /* 64-bit keyid search */
CDK_DBSEARCH_FPR = 5, /* 160-bit fingerprint search */
CDK_DBSEARCH_NEXT = 6, /* Enumerate all keys */
CDK_DBSEARCH_AUTO = 7, /* Try to classify the string */
/* Valid database types */
CDK_DBTYPE_PK_KEYRING = 100, /* A file with one or more public keys */
CDK_DBTYPE_SK_KEYRING = 101, /* A file with one or more secret keys */
CDK_DBTYPE_DATA = 102, /* A buffer with at least one public key */
};
/* All valid modes for cdk_data_transform() */
enum cdk_crypto_mode_t {
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
};
#define CDK_KEY_USG_ENCR (CDK_KEY_USG_COMM_ENCR | CDK_KEY_USG_STORAGE_ENCR)
#define CDK_KEY_USG_SIGN (CDK_KEY_USG_DATA_SIGN | CDK_KEY_USG_CERT_SIGN)
/* A list of valid public key usages. */
enum cdk_key_usage_t {
CDK_KEY_USG_CERT_SIGN = 1,
CDK_KEY_USG_DATA_SIGN = 2,
CDK_KEY_USG_COMM_ENCR = 4,
CDK_KEY_USG_STORAGE_ENCR = 8,
CDK_KEY_USG_SPLIT_KEY = 16,
CDK_KEY_USG_AUTH = 32,
CDK_KEY_USG_SHARED_KEY = 128
};
/* Valid flags for keys. */
enum cdk_key_flag_t {
CDK_KEY_VALID = 0,
CDK_KEY_INVALID = 1, /* Missing or wrong self signature */
CDK_KEY_EXPIRED = 2, /* Key is expired. */
CDK_KEY_REVOKED = 4, /* Key has been revoked. */
CDK_KEY_NOSIGNER = 8
};
/* Trust values and flags for keys and user IDs */
enum cdk_trust_flag_t {
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,
/* trust flags */
CDK_TFLAG_REVOKED = 32,
CDK_TFLAG_SUB_REVOKED = 64,
CDK_TFLAG_DISABLED = 128
};
/* Signature states and the signature modes. */
enum cdk_signature_stat_t {
/* Signature status */
CDK_SIGSTAT_NONE = 0,
CDK_SIGSTAT_GOOD = 1,
CDK_SIGSTAT_BAD = 2,
CDK_SIGSTAT_NOKEY = 3,
CDK_SIGSTAT_VALID = 4, /* True if made with a valid key. */
/* FIXME: We need indicators for revoked/expires signatures. */
/* Signature modes */
CDK_SIGMODE_NORMAL = 100,
CDK_SIGMODE_DETACHED = 101,
CDK_SIGMODE_CLEAR = 102
};
/* Key flags. */
typedef enum {
CDK_FLAG_KEY_REVOKED = 256,
CDK_FLAG_KEY_EXPIRED = 512,
CDK_FLAG_SIG_EXPIRED = 1024
} cdk_key_flags_t;
/* Possible format for the literal data. */
typedef enum {
CDK_LITFMT_BINARY = 0,
CDK_LITFMT_TEXT = 1,
CDK_LITFMT_UNICODE = 2
} cdk_lit_format_t;
/* Valid OpenPGP packet types and their IDs */
typedef enum {
CDK_PKT_RESERVED = 0,
CDK_PKT_PUBKEY_ENC = 1,
CDK_PKT_SIGNATURE = 2,
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_MARKER = 10,
CDK_PKT_LITERAL = 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_MDC = 19
} cdk_packet_type_t;
/* Define the maximal number of multiprecion integers for
a public key. */
#define MAX_CDK_PK_PARTS 4
/* Define the maximal number of multiprecision integers for
a signature/encrypted blob issued by a secret key. */
#define MAX_CDK_DATA_PARTS 2
/* Helper macro to figure out if the packet is encrypted */
#define CDK_PKT_IS_ENCRYPTED(pkttype) (\
((pkttype)==CDK_PKT_ENCRYPTED_MDC) \
|| ((pkttype)==CDK_PKT_ENCRYPTED))
struct cdk_pkt_signature_s {
unsigned char version;
unsigned char sig_class;
unsigned int timestamp;
unsigned int expiredate;
unsigned int keyid[2];
unsigned char pubkey_algo;
unsigned char digest_algo;
unsigned char digest_start[2];
unsigned short hashed_size;
cdk_subpkt_t hashed;
unsigned short unhashed_size;
cdk_subpkt_t unhashed;
bigint_t mpi[MAX_CDK_DATA_PARTS];
cdk_desig_revoker_t revkeys;
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 int key[2]; /* only valid for key signatures */
};
typedef struct cdk_pkt_signature_s *cdk_pkt_signature_t;
struct cdk_pkt_userid_s {
unsigned int len;
unsigned is_primary:1;
unsigned is_revoked:1;
unsigned mdc_feature:1;
cdk_prefitem_t prefs;
size_t prefs_size;
unsigned char *attrib_img; /* Tag 17 if not null */
size_t attrib_len;
cdk_pkt_signature_t selfsig;
char *name;
};
typedef struct cdk_pkt_userid_s *cdk_pkt_userid_t;
struct cdk_pkt_pubkey_s {
unsigned char version;
unsigned char pubkey_algo;
unsigned char fpr[20];
unsigned int keyid[2];
unsigned int main_keyid[2];
unsigned int timestamp;
unsigned int expiredate;
bigint_t mpi[MAX_CDK_PK_PARTS];
unsigned is_revoked:1;
unsigned is_invalid:1;
unsigned has_expired:1;
int pubkey_usage;
cdk_pkt_userid_t uid;
cdk_prefitem_t prefs;
size_t prefs_size;
cdk_desig_revoker_t revkeys;
};
typedef struct cdk_pkt_pubkey_s *cdk_pkt_pubkey_t;
/* Alias to define a generic public key context. */
typedef cdk_pkt_pubkey_t cdk_pubkey_t;
struct cdk_pkt_seckey_s {
cdk_pkt_pubkey_t pk;
unsigned int expiredate;
int version;
int pubkey_algo;
unsigned int keyid[2];
unsigned int 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_t s2k;
unsigned char iv[16];
unsigned char ivlen;
} protect;
unsigned short csum;
bigint_t mpi[MAX_CDK_PK_PARTS];
unsigned char *encdata;
size_t enclen;
unsigned char is_protected;
unsigned is_primary:1;
unsigned has_expired:1;
unsigned is_revoked:1;
};
typedef struct cdk_pkt_seckey_s *cdk_pkt_seckey_t;
/* Alias to define a generic secret key context. */
typedef cdk_pkt_seckey_t cdk_seckey_t;
struct cdk_pkt_onepass_sig_s {
unsigned char version;
unsigned int keyid[2];
unsigned char sig_class;
unsigned char digest_algo;
unsigned char pubkey_algo;
unsigned char last;
};
typedef struct cdk_pkt_onepass_sig_s *cdk_pkt_onepass_sig_t;
struct cdk_pkt_pubkey_enc_s {
unsigned char version;
unsigned int keyid[2];
int throw_keyid;
unsigned char pubkey_algo;
bigint_t mpi[MAX_CDK_DATA_PARTS];
};
typedef struct cdk_pkt_pubkey_enc_s *cdk_pkt_pubkey_enc_t;
struct cdk_pkt_encrypted_s {
unsigned int len;
int extralen;
unsigned char mdc_method;
cdk_stream_t buf;
};
typedef struct cdk_pkt_encrypted_s *cdk_pkt_encrypted_t;
struct cdk_pkt_mdc_s {
unsigned char hash[20];
};
typedef struct cdk_pkt_mdc_s *cdk_pkt_mdc_t;
struct cdk_pkt_literal_s {
unsigned int len;
cdk_stream_t buf;
int mode;
unsigned int timestamp;
int namelen;
char *name;
};
typedef struct cdk_pkt_literal_s *cdk_pkt_literal_t;
struct cdk_pkt_compressed_s {
unsigned int len;
int algorithm;
cdk_stream_t buf;
};
typedef struct cdk_pkt_compressed_s *cdk_pkt_compressed_t;
/* Structure which represents a single OpenPGP packet. */
struct cdk_packet_s {
size_t pktlen; /* real packet length */
size_t pktsize; /* length with all headers */
int old_ctb; /* 1 if RFC1991 mode is used */
cdk_packet_type_t pkttype;
union {
cdk_pkt_mdc_t mdc;
cdk_pkt_userid_t user_id;
cdk_pkt_pubkey_t public_key;
cdk_pkt_seckey_t secret_key;
cdk_pkt_signature_t signature;
cdk_pkt_pubkey_enc_t pubkey_enc;
cdk_pkt_compressed_t compressed;
cdk_pkt_encrypted_t encrypted;
cdk_pkt_literal_t literal;
cdk_pkt_onepass_sig_t onepass_sig;
} pkt;
};
typedef struct cdk_packet_s *cdk_packet_t;
/* Allocate a new packet or a new packet with the given packet type. */
cdk_error_t cdk_pkt_new(cdk_packet_t * r_pkt);
cdk_error_t cdk_pkt_alloc(cdk_packet_t * r_pkt,
cdk_packet_type_t pkttype);
/* Only release the contents of the packet but not @PKT itself. */
void cdk_pkt_free(cdk_packet_t pkt);
/* Release the packet contents and the packet structure @PKT itself. */
void cdk_pkt_release(cdk_packet_t pkt);
/* Read or write the given output from or to the stream. */
cdk_error_t cdk_pkt_read(cdk_stream_t inp, cdk_packet_t pkt);
cdk_error_t cdk_pkt_write(cdk_stream_t out, cdk_packet_t pkt);
/* Sub packet routines */
cdk_subpkt_t cdk_subpkt_new(size_t size);
void cdk_subpkt_free(cdk_subpkt_t ctx);
cdk_subpkt_t cdk_subpkt_find(cdk_subpkt_t ctx, size_t type);
cdk_subpkt_t cdk_subpkt_find_next(cdk_subpkt_t root, size_t type);
size_t cdk_subpkt_type_count(cdk_subpkt_t ctx, size_t type);
cdk_subpkt_t cdk_subpkt_find_nth(cdk_subpkt_t ctx, size_t type,
size_t index);
cdk_error_t cdk_subpkt_add(cdk_subpkt_t root, cdk_subpkt_t node);
const unsigned char *cdk_subpkt_get_data(cdk_subpkt_t ctx,
size_t * r_type,
size_t * r_nbytes);
void cdk_subpkt_init(cdk_subpkt_t node, size_t type,
const void *buf, size_t buflen);
/* Designated Revoker routines */
const unsigned char *cdk_key_desig_revoker_walk(cdk_desig_revoker_t
root,
cdk_desig_revoker_t
* ctx,
int *r_class,
int *r_algid);
#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_E)
#define is_DSA(a) ((a) == CDK_PK_DSA)
/* Encrypt the given session key @SK with the public key @PK
and write the contents into the packet @PKE. */
cdk_error_t cdk_pk_encrypt(cdk_pubkey_t pk,
cdk_pkt_pubkey_enc_t pke, bigint_t sk);
/* Decrypt the given encrypted session key in @PKE with the secret key
@SK and store it in @R_SK. */
cdk_error_t cdk_pk_decrypt(cdk_seckey_t sk,
cdk_pkt_pubkey_enc_t pke,
bigint_t * r_sk);
/* Sign the given message digest @MD with the secret key @SK and
store the signature in the packet @SIG. */
cdk_error_t cdk_pk_sign(cdk_seckey_t sk, cdk_pkt_signature_t sig,
const unsigned char *md);
/* Verify the given signature in @SIG with the public key @PK
and compare it against the message digest @MD. */
cdk_error_t cdk_pk_verify(cdk_pubkey_t pk, cdk_pkt_signature_t sig,
const unsigned char *md);
/* Use cdk_pk_get_npkey() and cdk_pk_get_nskey to find out how much
multiprecision integers a key consists of. */
/* Return a multi precision integer of the public key with the index @IDX
in the buffer @BUF. @R_NWRITTEN will contain the length in octets.
Optional @R_NBITS may contain the size in bits. */
cdk_error_t cdk_pk_get_mpi(cdk_pubkey_t pk, size_t idx,
unsigned char *buf, size_t buflen,
size_t * r_nwritten, size_t * r_nbits);
/* Same as the function above but of the secret key. */
cdk_error_t cdk_sk_get_mpi(cdk_seckey_t sk, size_t idx,
unsigned char *buf, size_t buflen,
size_t * r_nwritten, size_t * r_nbits);
/* Helper to get the exact number of multi precision integers
for the given object. */
int cdk_pk_get_nbits(cdk_pubkey_t 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);
/* Fingerprint and key ID routines. */
/* Calculate the fingerprint of the given public key.
the FPR parameter must be at least 20 octets to hold the SHA1 hash. */
cdk_error_t cdk_pk_get_fingerprint(cdk_pubkey_t pk,
unsigned char *fpr);
/* Same as above, but with additional sanity checks of the buffer size. */
cdk_error_t cdk_pk_to_fingerprint(cdk_pubkey_t pk,
unsigned char *fpr,
size_t fprlen, size_t * r_nout);
/* Derive the keyid from the fingerprint. This is only possible for
modern, version 4 keys. */
unsigned int cdk_pk_fingerprint_get_keyid(const unsigned char *fpr,
size_t fprlen,
unsigned int *keyid);
/* Various functions to get the keyid from the specific packet type. */
unsigned int cdk_pk_get_keyid(cdk_pubkey_t pk,
unsigned int *keyid);
unsigned int cdk_sk_get_keyid(cdk_seckey_t sk,
unsigned int *keyid);
unsigned int cdk_sig_get_keyid(cdk_pkt_signature_t sig,
unsigned int *keyid);
/* Key release functions. */
void cdk_pk_release(cdk_pubkey_t pk);
void cdk_sk_release(cdk_seckey_t sk);
/* Create a public key with the data from the secret key @SK. */
cdk_error_t cdk_pk_from_secret_key(cdk_seckey_t sk,
cdk_pubkey_t * ret_pk);
/* Sexp conversion of keys. */
cdk_error_t cdk_pubkey_to_sexp(cdk_pubkey_t pk, char **sexp,
size_t * len);
cdk_error_t cdk_seckey_to_sexp(cdk_seckey_t sk, char **sexp,
size_t * len);
/* String to Key routines. */
cdk_error_t cdk_s2k_new(cdk_s2k_t * ret_s2k, int mode,
int digest_algo,
const unsigned char *salt);
void cdk_s2k_free(cdk_s2k_t s2k);
/* Protect the inbuf with ASCII armor of the specified type.
If @outbuf and @outlen are NULL, the function returns the calculated
size of the base64 encoded data in @nwritten. */
cdk_error_t cdk_armor_encode_buffer(const unsigned char *inbuf,
size_t inlen, char *outbuf,
size_t outlen,
size_t * nwritten, int type);
/* This context contain user callbacks for different stream operations.
Some of these callbacks might be NULL to indicate that the callback
is not used. */
struct cdk_stream_cbs_s {
cdk_error_t(*open) (void *);
cdk_error_t(*release) (void *);
int (*read) (void *, void *buf, size_t);
int (*write) (void *, const void *buf, size_t);
int (*seek) (void *, off_t);
};
typedef struct cdk_stream_cbs_s *cdk_stream_cbs_t;
int cdk_stream_is_compressed(cdk_stream_t s);
/* Return a stream object which is associated to a socket. */
cdk_error_t cdk_stream_sockopen(const char *host,
unsigned short port,
cdk_stream_t * ret_out);
/* Return a stream object which is associated to an existing file. */
cdk_error_t cdk_stream_open(const char *file,
cdk_stream_t * ret_s);
/* Return a stream object which is associated to a file which will
be created when the stream is closed. */
cdk_error_t cdk_stream_new(const char *file, cdk_stream_t * ret_s);
/* Return a stream object with custom callback functions for the
various core operations. */
cdk_error_t cdk_stream_new_from_cbs(cdk_stream_cbs_t cbs,
void *opa,
cdk_stream_t * ret_s);
cdk_error_t cdk_stream_create(const char *file,
cdk_stream_t * ret_s);
cdk_error_t cdk_stream_tmp_new(cdk_stream_t * r_out);
cdk_error_t cdk_stream_tmp_from_mem(const void *buf, size_t buflen,
cdk_stream_t * r_out);
void cdk_stream_tmp_set_mode(cdk_stream_t s, int val);
cdk_error_t cdk_stream_flush(cdk_stream_t s);
cdk_error_t cdk_stream_enable_cache(cdk_stream_t s, int val);
cdk_error_t cdk_stream_filter_disable(cdk_stream_t s, int type);
cdk_error_t cdk_stream_close(cdk_stream_t s);
off_t cdk_stream_get_length(cdk_stream_t s);
int cdk_stream_read(cdk_stream_t s, void *buf, size_t count);
int cdk_stream_write(cdk_stream_t s, const void *buf,
size_t count);
int cdk_stream_putc(cdk_stream_t s, int c);
int cdk_stream_getc(cdk_stream_t s);
int cdk_stream_eof(cdk_stream_t s);
off_t cdk_stream_tell(cdk_stream_t s);
cdk_error_t cdk_stream_seek(cdk_stream_t s, off_t offset);
cdk_error_t cdk_stream_set_armor_flag(cdk_stream_t s, int type);
/* Push the literal filter for the given stream. */
cdk_error_t cdk_stream_set_literal_flag(cdk_stream_t s,
cdk_lit_format_t mode,
const char *fname);
cdk_error_t cdk_stream_set_compress_flag(cdk_stream_t s, int algo,
int level);
cdk_error_t cdk_stream_set_hash_flag(cdk_stream_t s, int algo);
cdk_error_t cdk_stream_set_text_flag(cdk_stream_t s,
const char *lf);
cdk_error_t cdk_stream_kick_off(cdk_stream_t inp,
cdk_stream_t out);
cdk_error_t cdk_stream_mmap(cdk_stream_t s,
unsigned char **ret_buf,
size_t * ret_buflen);
cdk_error_t cdk_stream_mmap_part(cdk_stream_t s, off_t off,
size_t len,
unsigned char **ret_buf,
size_t * ret_buflen);
/* Read from the stream but restore the file pointer after reading
the requested amount of bytes. */
int cdk_stream_peek(cdk_stream_t inp, unsigned char *buf,
size_t buflen);
/* Create a new key db handle from a memory buffer. */
cdk_error_t cdk_keydb_new_from_mem(cdk_keydb_hd_t * r_hd,
int secret, int armor,
const void *data,
size_t datlen);
/* Check that a secret key with the given key ID is available. */
cdk_error_t cdk_keydb_check_sk(cdk_keydb_hd_t hd,
unsigned int *keyid);
/* Prepare the key db search. */
cdk_error_t cdk_keydb_search_start(cdk_keydb_search_t * st,
cdk_keydb_hd_t db, int type,
void *desc);
void cdk_keydb_search_release(cdk_keydb_search_t st);
/* Return a key which matches a valid description given in
cdk_keydb_search_start(). */
cdk_error_t cdk_keydb_search(cdk_keydb_search_t st,
cdk_keydb_hd_t hd,
cdk_kbnode_t * ret_key);
/* Release the key db handle and all its resources. */
void cdk_keydb_free(cdk_keydb_hd_t hd);
/* The following functions will try to find a key in the given key
db handle either by keyid, by fingerprint or by some pattern. */
cdk_error_t cdk_keydb_get_bykeyid(cdk_keydb_hd_t hd,
unsigned int *keyid,
cdk_kbnode_t * ret_pk);
cdk_error_t cdk_keydb_get_byfpr(cdk_keydb_hd_t hd,
const unsigned char *fpr,
cdk_kbnode_t * ret_pk);
cdk_error_t cdk_keydb_get_bypattern(cdk_keydb_hd_t hd,
const char *patt,
cdk_kbnode_t * ret_pk);
/* These function, in contrast to most other key db functions, only
return the public or secret key packet without the additional
signatures and user IDs. */
cdk_error_t cdk_keydb_get_pk(cdk_keydb_hd_t khd,
unsigned int *keyid,
cdk_pubkey_t * ret_pk);
cdk_error_t cdk_keydb_get_sk(cdk_keydb_hd_t khd,
unsigned int *keyid,
cdk_seckey_t * ret_sk);
/* Try to read the next key block from the given input stream.
The key will be returned in @RET_KEY on success. */
cdk_error_t cdk_keydb_get_keyblock(cdk_stream_t inp,
cdk_kbnode_t * ret_key);
/* Rebuild the key db index if possible. */
cdk_error_t cdk_keydb_idx_rebuild(cdk_keydb_hd_t db,
cdk_keydb_search_t dbs);
/* Export one or more keys from the given key db handle into
the stream @OUT. The export is done by substring search and
uses the string list @REMUSR for the pattern. */
cdk_error_t cdk_keydb_export(cdk_keydb_hd_t hd, cdk_stream_t out,
cdk_strlist_t remusr);
/* Import the given key node @knode into the key db. */
cdk_error_t cdk_keydb_import(cdk_keydb_hd_t hd,
cdk_kbnode_t knode);
/* List or enumerate keys from a given key db handle. */
/* Start the key list process. Either use @PATT for a pattern search
or @FPATT for a list of pattern. */
cdk_error_t cdk_listkey_start(cdk_listkey_t * r_ctx,
cdk_keydb_hd_t db, const char *patt,
cdk_strlist_t fpatt);
void cdk_listkey_close(cdk_listkey_t ctx);
/* Return the next key which matches the pattern. */
cdk_error_t cdk_listkey_next(cdk_listkey_t ctx,
cdk_kbnode_t * ret_key);
cdk_kbnode_t cdk_kbnode_new(cdk_packet_t pkt);
cdk_error_t cdk_kbnode_read_from_mem(cdk_kbnode_t * ret_node,
int armor,
const unsigned char *buf,
size_t buflen);
cdk_error_t cdk_kbnode_write_to_mem(cdk_kbnode_t node,
unsigned char *buf,
size_t * r_nbytes);
cdk_error_t cdk_kbnode_write_to_mem_alloc(cdk_kbnode_t node,
unsigned char **r_buf,
size_t * r_buflen);
void cdk_kbnode_release(cdk_kbnode_t node);
void cdk_kbnode_delete(cdk_kbnode_t node);
void cdk_kbnode_insert(cdk_kbnode_t root, cdk_kbnode_t node,
cdk_packet_type_t pkttype);
int cdk_kbnode_commit(cdk_kbnode_t * root);
void cdk_kbnode_remove(cdk_kbnode_t * root, cdk_kbnode_t node);
void cdk_kbnode_move(cdk_kbnode_t * root, cdk_kbnode_t node,
cdk_kbnode_t where);
cdk_kbnode_t cdk_kbnode_walk(cdk_kbnode_t root, cdk_kbnode_t * ctx,
int all);
cdk_packet_t cdk_kbnode_find_packet(cdk_kbnode_t node,
cdk_packet_type_t pkttype);
cdk_packet_t cdk_kbnode_get_packet(cdk_kbnode_t node);
cdk_kbnode_t cdk_kbnode_find(cdk_kbnode_t node,
cdk_packet_type_t pkttype);
cdk_kbnode_t cdk_kbnode_find_prev(cdk_kbnode_t root,
cdk_kbnode_t node,
cdk_packet_type_t pkttype);
cdk_kbnode_t cdk_kbnode_find_next(cdk_kbnode_t node,
cdk_packet_type_t pkttype);
cdk_error_t cdk_kbnode_hash(cdk_kbnode_t node, digest_hd_st * md,
int is_v4, cdk_packet_type_t pkttype,
int flags);
/* Check each signature in the key node and return a summary of the
key status in @r_status. Values of cdk_key_flag_t are used. */
cdk_error_t cdk_pk_check_sigs(cdk_kbnode_t knode,
cdk_keydb_hd_t hd, int *r_status);
/* Check the self signature of the key to make sure it is valid. */
cdk_error_t cdk_pk_check_self_sig(cdk_kbnode_t knode,
int *r_status);
/* Return a matching algorithm from the given public key list.
@PREFTYPE can be either sym-cipher/compress/digest. */
int cdk_pklist_select_algo(cdk_keylist_t pkl, int preftype);
/* Return 0 or 1 if the given key list is able to understand the
MDC feature. */
int cdk_pklist_use_mdc(cdk_keylist_t pkl);
cdk_error_t cdk_pklist_build(cdk_keylist_t * ret_pkl,
cdk_keydb_hd_t hd,
cdk_strlist_t remusr, int use);
void cdk_pklist_release(cdk_keylist_t pkl);
/* Secret key lists */
cdk_error_t cdk_sklist_build(cdk_keylist_t * ret_skl,
cdk_keydb_hd_t db, cdk_ctx_t hd,
cdk_strlist_t locusr,
int unlock, unsigned int use);
void cdk_sklist_release(cdk_keylist_t skl);
cdk_error_t cdk_sklist_write(cdk_keylist_t skl, cdk_stream_t outp,
digest_hd_st * mdctx, int sigclass,
int sigver);
cdk_error_t cdk_sklist_write_onepass(cdk_keylist_t skl,
cdk_stream_t outp,
int sigclass, int mdalgo);
/* Encrypt the given stream @INP with the recipients given in @REMUSR.
If @REMUSR is NULL, symmetric encryption will be used. The output
will be written to @OUT. */
cdk_error_t cdk_stream_encrypt(cdk_ctx_t hd, cdk_strlist_t remusr,
cdk_stream_t inp, cdk_stream_t out);
/* Decrypt the @INP stream into @OUT. */
cdk_error_t cdk_stream_decrypt(cdk_ctx_t hd, cdk_stream_t inp,
cdk_stream_t out);
/* Same as the function above but it works on files. */
cdk_error_t cdk_file_encrypt(cdk_ctx_t hd, cdk_strlist_t remusr,
const char *file, const char *output);
cdk_error_t cdk_file_decrypt(cdk_ctx_t hd, const char *file,
const char *output);
/* Generic function to transform data. The mode can be either sign,
verify, encrypt, decrypt, import or export. The meanings of the
parameters are similar to the functions above.
@OUTBUF will contain the output and @OUTSIZE the length of it. */
cdk_error_t cdk_data_transform(cdk_ctx_t hd,
enum cdk_crypto_mode_t mode,
cdk_strlist_t locusr,
cdk_strlist_t remusr,
const void *inbuf, size_t insize,
unsigned char **outbuf,
size_t * outsize, int modval);
int cdk_trustdb_get_validity(cdk_stream_t inp, cdk_pkt_userid_t id,
int *r_val);
int cdk_trustdb_get_ownertrust(cdk_stream_t inp, cdk_pubkey_t pk,
int *r_val, int *r_flags);
void cdk_strlist_free(cdk_strlist_t sl);
cdk_strlist_t cdk_strlist_add(cdk_strlist_t * list,
const char *string);
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);
#ifdef __cplusplus
}
#endif
#endif /* OPENCDK_H */