/* silcpgp.h Author: Pekka Riikonen Copyright (C) 2007 - 2008 Pekka Riikonen This program 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; version 2 of the License. This program 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. */ /****h* silcpgp/OpenPGP Interface * * DESCRIPTION * * This implementation supports OpenPGP public key versions 2, 3 and 4. * OpenPGP private key support exist only for version 4. This means that * this API can be used verify signatures with all versions of OpenPGP public * keys, but signatures can only be computed with version 4 private keys. * This implementation also only generates version 4 private keys. * * The interface implements the RFC 2440 and rfc2440bis-22 Internet Draft * specifications. * ***/ #ifndef SILCPGP_H #define SILCPGP_H /****s* silcpgp/SilcPGPPublicKey * * NAME * * typedef struct { ... } *SilcPGPPublicKey; * * DESCRIPTION * * This structure defines the OpenPGP public key (certificate). This * context can be retrieved from SilcPublicKey by calling * silc_pkcs_public_key_get_pkcs for the PKCS type SILC_PKCS_OPENPGP. * * SOURCE */ typedef struct SilcPGPPublicKeyStruct { SilcList packets; /* Packets making this public key, contains main key, subkeys, signatures etc. */ SilcDList subkeys; /* Subkeys, each is SilcPGPPublicKey */ const SilcPKCSAlgorithm *pkcs; /* PKCS Algorithm */ void *public_key; /* PKCS Algorithm specific public key */ unsigned char key_id[8]; /* Public key ID */ unsigned char fingerprint[20]; /* Fingerprint of the public key */ SilcUInt32 created; /* Time when public key was created */ SilcUInt16 valid; /* Validity period (V3 keys) */ SilcUInt8 version; /* Version, 2, 3 or 4 */ SilcUInt8 algorithm; /* Algorithm, SilcPGPPKCSAlgorithm */ } *SilcPGPPublicKey; /***/ /****s* silcpgp/SilcPGPPrivateKey * * NAME * * typedef struct { ... } *SilcPGPPrivateKey; * * DESCRIPTION * * This structure defines the OpenPGP private key. This context can be * retrieved from SilcPublicKey by calling silc_pkcs_private_key_get_pkcs * for the PKCS type SILC_PKCS_OPENPGP. * * SOURCE */ typedef struct SilcPGPPrivateKeyStruct { SilcList packets; /* Packets making this private key, contains main key, subkeys, signatures etc. */ SilcDList subkeys; /* Subkeys, each is SilcPGPPrivateKey */ SilcPGPPublicKey public_key; /* Public key */ void *private_key; /* Algorithm specific private key */ SilcUInt32 s2k_count; /* S2K iterate octet count */ SilcUInt8 cipher; /* Cipher, SilcPGPCipher */ SilcUInt8 s2k_type; /* S2K type, SilcPGPS2KType */ SilcUInt8 s2k_hash; /* Hash, SilcPGPHash */ } *SilcPGPPrivateKey; /***/ /****s* silcpgp/SilcPGPPacket * * NAME * * typedef struct SilcPGPPacketStruct *SilcPGPPacket; * * DESCRIPTION * * OpenPGP packet context. This context is allocated by calling * silc_pgp_packet_decode. * ***/ typedef struct SilcPGPPacketStruct *SilcPGPPacket; /****d* silcpgp/SilcPGPPacketTag * * NAME * * typedef enum { ... } SilcPGPPacketTag; * * DESCRIPTION * * OpenPGP packet types. * * SOURCE */ typedef enum { SILC_PGP_PACKET_PKENC_SK = 1, /* Public key enc session key */ SILC_PGP_PACKET_SIGNATURE = 2, /* Signature packet */ SILC_PGP_PACKET_SENC_SK = 3, /* Symmetric-key enc session key */ SILC_PGP_PACKET_OP_SIGNATURE = 4, /* One pass signature packet */ SILC_PGP_PACKET_SECKEY = 5, /* Secret key packet */ SILC_PGP_PACKET_PUBKEY = 6, /* Public key packet */ SILC_PGP_PACKET_SECKEY_SUB = 7, /* Secret subkey packet */ SILC_PGP_PACKET_COMP_DATA = 8, /* Compressed data packet */ SILC_PGP_PACKET_SENC_DATA = 9, /* Symmetrically enc data packet */ SILC_PGP_PACKET_MARKER = 10, /* Marker packet */ SILC_PGP_PACKET_LITERAL_DATA = 11, /* Literal data packet */ SILC_PGP_PACKET_TRUST = 12, /* Trust packet */ SILC_PGP_PACKET_USER_ID = 13, /* User ID packet */ SILC_PGP_PACKET_PUBKEY_SUB = 14, /* Public subkey packet */ SILC_PGP_PACKET_USER_ATTR = 17, /* User attribute packet */ SILC_PGP_PACKET_SENC_I_DATA = 18, /* Symmetric key enc/integ data */ SILC_PGP_PACKET_MDC = 19, /* Modification detection code */ } SilcPGPPacketTag; /***/ /****d* silcpgp/SilcPGPPKCSAlgorithm * * NAME * * typedef enum { ... } SilcPGPPKCSAlgorithm; * * DESCRIPTION * * OpenPGP public key cryptosystem algorithms. * * SOURCE */ typedef enum { SILC_PGP_PKCS_RSA = 1, /* RSA */ SILC_PGP_PKCS_RSA_ENC_ONLY = 2, /* RSA encryption allowed only */ SILC_PGP_PKCS_RSA_SIG_ONLY = 3, /* RSA signatures allowed only */ SILC_PGP_PKCS_ELGAMAL_ENC_ONLY = 16, /* Elgamal encryption only */ SILC_PGP_PKCS_DSA = 17, /* DSA */ SILC_PGP_PKCS_ECDSA = 19, /* ECDSA */ SILC_PGP_PKCS_ELGAMAL = 20, /* Elgamal encryption/signatures */ SILC_PGP_PKCS_DH = 21, /* Diffie-Hellman */ } SilcPGPPKCSAlgorithm; /***/ /****d* silcpgp/SilcPGPCipher * * NAME * * typedef enum { ... } SilcPGPCipher; * * DESCRIPTION * * OpenPGP ciphers. * * SOURCE */ typedef enum { SILC_PGP_CIPHER_NONE = 0, /* No cipher, plaintext */ SILC_PGP_CIPHER_IDEA = 1, /* IDEA */ SILC_PGP_CIPHER_3DES = 2, /* Triple-DES */ SILC_PGP_CIPHER_CAST5 = 3, /* CAST5 (CAST-128) */ SILC_PGP_CIPHER_BLOWFISH = 4, /* Blowfish */ SILC_PGP_CIPHER_AES128 = 7, /* AES 128-bit key */ SILC_PGP_CIPHER_AES192 = 8, /* AES 192-bit key */ SILC_PGP_CIPHER_AES256 = 9, /* AES 256-bit key */ SILC_PGP_CIPHER_TWOFISH = 10, /* Twofish 256-bit key */ } SilcPGPCipher; /***/ /****d* silcpgp/SilcPGPHash * * NAME * * typedef enum { ... } SilcPGPHash; * * DESCRIPTION * * OpenPGP hash functions. * * SOURCE */ typedef enum { SILC_PGP_HASH_MD5 = 1, /* MD5 */ SILC_PGP_HASH_SHA1 = 2, /* SHA-1 */ SILC_PGP_HASH_RIPEMD160 = 3, /* RIPE-MD160 */ SILC_PGP_HASH_SHA256 = 8, /* SHA-256 */ SILC_PGP_HASH_SHA384 = 9, /* SHA-394 */ SILC_PGP_HASH_SHA512 = 10, /* SHA-512 */ SILC_PGP_HASH_SHA224 = 11, /* SHA-224 */ } SilcPGPHash; /***/ /****d* silcpgp/SilcPGPS2KType * * NAME * * typedef enum { ... } SilcPGPS2KType; * * DESCRIPTION * * String-to-key (S2K) specifier types. These define how the passphrase * is converted into encryption and decryption key. * * SOURCE */ typedef enum { SILC_PGP_S2K_SIMPLE = 0, /* Simple S2K */ SILC_PGP_S2K_SALTED = 1, /* Salted S2K */ SILC_PGP_S2K_ITERATED_SALTED = 3, /* Iterated and salted S2K */ } SilcPGPS2KType; /***/ /****d* silcpgp/SilcPGPKeyType * * NAME * * typedef enum { ... } SilcPGPKeyType; * * DESCRIPTION * * PGP key generation types. These types define what kind of PGP key * is created with silc_pgp_generate_key. * * SILC_PGP_RSA * * Generates RSA key that can be used for both signatures and encryption. * This is default. If key type is not specified, this is used as * default key type. * * SILC_PGP_DSA_SIG * * Generates signature only DSA key. The key cannot be used for * encryption. * * SILC_PGP_ECDSA_SIG * * Generates signature only ECDSA key. The key cannot be used for * encryption. * * SILC_PGP_DSA_SIG_ELGAMAL_ENC * * Generates key with DSA for signatures and Elgamal for encryption. * * SILC_PGP_DSA_SIG_RSA_ENC * * Generates key with DSA for signatures and RSA for encryption. * * SOURCE */ typedef enum { SILC_PGP_RSA = 0, /* Generate RSA key */ SILC_PGP_DSA_SIG = 1, /* Generate signature only DSA key */ SILC_PGP_ECDSA_SIG = 2, /* Generate signature only ECDSA key */ SILC_PGP_DSA_SIG_ELGAMAL_ENC = 3, /* Generate DSA and Elgamal key */ SILC_PGP_DSA_SIG_RSA_ENC = 4, /* Generate DSA and RSA key */ } SilcPGPKeyType; /***/ typedef struct SilcPgpKeygenParamsStruct { SilcPGPKeyType type; int key_len_bits; int expire_days; int expire_weeks; int expire_months; int expire_years; } SilcPgpKeygenParams; /* XXX TODO */ SilcBool silc_pgp_generate_key(SilcPgpKeygenParams *params, const char *user_id, SilcRng rng, SilcPublicKey *ret_public_key, SilcPrivateKey *ret_private_key); /****f* silcpgp/silc_pgp_packet_decode * * SYNOPSIS * * SilcBool silc_pgp_packet_decode(const unsigned char *data, * SilcUInt32 data_len, * SilcBool *success, * SilcList *ret_list); * * DESCRIPTION * * Decodes PGP packets from the data buffer indicated by `data' of length * of `data_len' bytes. The data buffer may include one or more packets * that are decoded and returned to the `ret_list'. The caller must free * the returned packets with silc_pgp_packet_free_list. Each entry in * the `ret_list' is SilcPGPPacket. * * Returns the number of packets decoded or 0 on error. If the `success' * is FALSE but this returns > 0 then not all packets were decoded * successfully and the `ret_list' includes the packets that were decoded. * When the `success' is TRUE all packets were decoded successfully. * * EXAMPLE * * SilcList list; * SilcBool success; * unsigned char *data; * SilcUInt32 data_len; * SilcPGPPublicKey public_key; * * // Open public key file (binary format) and parse all PGP packets * data = silc_file_readfile("pubkey.bin", &data_len, NULL); * silc_pgp_packet_decode(data, data_len, &success, &list); * * // Parse public key * silc_pgp_public_key_decode(&list, &public_key); * ***/ int silc_pgp_packet_decode(const unsigned char *data, SilcUInt32 data_len, SilcBool *success, SilcList *ret_list); /****f* silcpgp/silc_pgp_packet_get_tag * * SYNOPSIS * * SilcPGPPacketTag silc_pgp_packet_get_tag(SilcPGPPacket packet); * * DESCRIPTION * * Returns the OpenPGP packet tag (packet type) from `packet'. * ***/ SilcPGPPacketTag silc_pgp_packet_get_tag(SilcPGPPacket packet); /****f* silcpgp/silc_pgp_packet_get_data * * SYNOPSIS * * unsigned char *silc_pgp_packet_get_data(SilcPGPPacket packet, * SilcUInt32 *data_len); * * DESCRIPTION * * Returns the packet data from the `packet'. The returned pointer * must not be freed by the caller. The length of the data is returned * into `data_len' pointer. * ***/ unsigned char *silc_pgp_packet_get_data(SilcPGPPacket packet, SilcUInt32 *data_len); /****f* silcpgp/silc_pgp_packet_free * * SYNOPSIS * * void silc_pgp_packet_free(SilcPGPPacket packet); * * DESCRIPTION * * Free PGP packet. * ***/ void silc_pgp_packet_free(SilcPGPPacket packet); /****f* silcpgp/silc_pgp_packet_free_list * * SYNOPSIS * * void silc_pgp_packet_free_list(SilcList *list); * * DESCRIPTION * * Free all PGP packets from the `list'. All packets in the list will * become invalid after this call. * ***/ void silc_pgp_packet_free_list(SilcList *list); /****f* silcpgp/silc_pgp_public_key_decode * * SYNOPSIS * * SilcBool silc_pgp_public_key_decode(SilcList *list, * SilcPGPPublicKey *ret_public_key); * * DESCRIPTION * * Decodes OpenPGP public key (certificate) from decoded PGP packets list * indicated by `list'. The decoded public key is returned into the * `ret_public_key' which the caller must free by calling the * silc_pgp_public_key_free function. Returns FALSE on error. * * The `list' can be allocated by calling silc_pgp_packet_decode. * If the `list' contains more that one public keys this only decodes * the first one. The public key `list' is advanced while decoding the * public key. If another public key follows the first public key, this * function may be called again to decode that public key as well. * ***/ SilcBool silc_pgp_public_key_decode(SilcList *pubkey, SilcPGPPublicKey *ret_public_key); /****f* silcpgp/silc_pgp_public_key_free * * SYNOPSIS * * void silc_pgp_public_key_free(SilcPGPPublicKey public_key); * * DESCRIPTION * * Frees the public key. * ***/ void silc_pgp_public_key_free(SilcPGPPublicKey public_key); /****f* silcpgp/silc_pgp_private_key_decode * * SYNOPSIS * * SilcBool silc_pgp_private_key_decode(SilcList *list, * const char *passphrase, * SilcUInt32 passphrase_len, * SilcPGPPrivateKey *ret_private_key); * * DESCRIPTION * * Decodes OpenPGP secret key (private key) from decoded PGP packets list * indicated by `list'. The decoded private key is returned into the * `ret_private_key' which the caller must free by calling the * silc_pgp_private_key_free function. Returns FALSE on error. * * The `passphrase' can be provided in case the private key is * encrypted. Usually all OpenPGP private keys are encrypted so the * passphrase should be always provided. * * The `list' can be allocated by calling silc_pgp_packet_decode. * If the `list' contains more that one private keys this only decodes * the first one. The private key `list' is advanced while decoding the * public key. If another private key follows the first public key, this * function may be called again to decode that private key as well. * ***/ SilcBool silc_pgp_private_key_decode(SilcList *list, const char *passphrase, SilcUInt32 passphrase_len, SilcPGPPrivateKey *ret_private_key); /****f* silcpgp/silc_pgp_private_key_free * * SYNOPSIS * * void silc_pgp_private_key_free(SilcPGPPrivateKey private_key); * * DESCRIPTION * * Frees the private key. * ***/ void silc_pgp_private_key_free(SilcPGPPrivateKey private_key); /****f* silcpgp/silc_pgp_s2k * * SYNOPSIS * * unsigned char *silc_pgp_s2k(SilcPGPS2KType type, * SilcPGPHash hash, * const char *passphrase, * SilcUInt32 passphrase_len, * SilcUInt32 key_len, * unsigned char *salt, * SilcUInt32 iter_octet_count, * SilcRng rng); * * DESCRIPTION * * Computes the OpenPGP string-to-key (S2K). Converts passphrases to * encryption and decryption keys. The `passphrase' must be non-NULL. * * The `type' specifies the S2K specifier type. The `hash' is the * hash algorithm used if the `type' is SILC_PGP_S2K_SALTED or * SILC_PGP_S2K_ITERATED_SALTED. If the `type' is * SILC_PGP_S2K_ITERATED_SALTED the `iter_octet_count' is the number of * bytes to iteratively hash (max value is 65536). * * The `key_len' is the length of the key to produce in bytes. If `salt' * is NULL this will generate an encryption key. If it is non-NULL this * will use the salt to compute the decryption key. * ***/ unsigned char *silc_pgp_s2k(SilcPGPS2KType type, SilcPGPHash hash, const char *passphrase, SilcUInt32 passphrase_len, SilcUInt32 key_len, unsigned char *salt, SilcUInt32 iter_count, SilcRng rng); unsigned char *silc_pgp_dearmor(unsigned char *data, SilcUInt32 data_len, SilcUInt32 *ret_len); #include "silcpgp_i.h" #endif /* SILCPGP_H */