X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Finclude%2Fgnunet_crypto_lib.h;h=1e2af892509c8b97bfa939ace9d26a1e08a51b02;hb=211fd52268a5ae7856273dd8d8b3b3ed427beadb;hp=75aabe75f1b4eeb01e4b67e7d061c9988502454d;hpb=2df23abd0a1e5a67c3a2ae362fa2f4641f1ebe6d;p=oweals%2Fgnunet.git diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 75aabe75f..1e2af8925 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Christian Grothoff (and other contributing authors) + (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -71,7 +71,6 @@ enum GNUNET_CRYPTO_Quality */ #define GNUNET_CRYPTO_AES_KEY_LENGTH (256/8) - /** * @brief Length of RSA encrypted data (2048 bit) * @@ -84,26 +83,68 @@ enum GNUNET_CRYPTO_Quality */ #define GNUNET_CRYPTO_RSA_DATA_ENCODING_LENGTH 256 - /** - * Length of an RSA KEY (d,e,len), 2048 bit (=256 octests) key d, 2 byte e + * Length of an RSA KEY (n,e,len), 2048 bit (=256 octests) key n, 2 byte e */ #define GNUNET_CRYPTO_RSA_KEY_LENGTH 258 - /** * Length of a hash value */ -#define GNUNET_CRYPTO_HASH_LENGTH 512/8 +#define GNUNET_CRYPTO_HASH_LENGTH (512/8) + +/** + * Maximum length of an ECC signature. + * Note: round up to multiple of 8 minus 2 for alignment. + */ +#define GNUNET_CRYPTO_ECC_SIGNATURE_DATA_ENCODING_LENGTH 190 + +/** + * Maximum length of the public key (q-point, Q = dP) when encoded. + */ +#define GNUNET_CRYPTO_ECC_MAX_PUBLIC_KEY_LENGTH 140 + /** * The private information of an RSA key pair. */ struct GNUNET_CRYPTO_RsaPrivateKey; +/** + * The private information of an ECC private key. + */ +struct GNUNET_CRYPTO_EccPrivateKey; + + +GNUNET_NETWORK_STRUCT_BEGIN + +/** + * GNUnet mandates a certain format for the encoding + * of private RSA key information that is provided + * by the RSA implementations. This format is used + * to serialize a private RSA key (typically when + * writing it to disk). + */ +struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded +{ + /** + * Total size of the structure, in bytes, in big-endian! + */ + uint16_t len GNUNET_PACKED; + uint16_t sizen GNUNET_PACKED; /* in big-endian! */ + uint16_t sizee GNUNET_PACKED; /* in big-endian! */ + uint16_t sized GNUNET_PACKED; /* in big-endian! */ + uint16_t sizep GNUNET_PACKED; /* in big-endian! */ + uint16_t sizeq GNUNET_PACKED; /* in big-endian! */ + uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */ + uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */ + /* followed by the actual values */ +}; +GNUNET_NETWORK_STRUCT_END + /** - * @brief 0-terminated ASCII encoding of a GNUNET_HashCode. + * @brief 0-terminated ASCII encoding of a struct GNUNET_HashCode. */ struct GNUNET_CRYPTO_HashAsciiEncoded { @@ -111,6 +152,15 @@ struct GNUNET_CRYPTO_HashAsciiEncoded }; +/** + * @brief 0-terminated ASCII encoding of a 'struct GNUNET_ShortHashCode'. + */ +struct GNUNET_CRYPTO_ShortHashAsciiEncoded +{ + unsigned char short_encoding[53]; +}; + + /** * @brief an RSA signature @@ -184,6 +234,85 @@ struct GNUNET_CRYPTO_RsaEncryptedData }; +/** + * @brief header of what an ECC signature signs + * this must be followed by "size - 8" bytes of + * the actual signed data + */ +struct GNUNET_CRYPTO_EccSignaturePurpose +{ + /** + * How many bytes does this signature sign? + * (including this purpose header); in network + * byte order (!). + */ + uint32_t size GNUNET_PACKED; + + /** + * What does this signature vouch for? This + * must contain a GNUNET_SIGNATURE_PURPOSE_XXX + * constant (from gnunet_signatures.h). In + * network byte order! + */ + uint32_t purpose GNUNET_PACKED; + +}; + + +/** + * @brief an ECC signature + */ +struct GNUNET_CRYPTO_EccSignature +{ + /** + * Overall size of the signature data. + */ + uint16_t size; + + /** + * S-expression, padded with zeros. + */ + char sexpr[GNUNET_CRYPTO_ECC_SIGNATURE_DATA_ENCODING_LENGTH]; +}; + + +/** + * Public ECC key (always for NIST P-521) encoded in a format suitable + * for network transmission as created using 'gcry_sexp_sprint'. + */ +struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded +{ + /** + * Size of the encoding, in network byte order. + */ + uint16_t size; + + /** + * Actual length of the q-point binary encoding. + */ + uint16_t len; + + /** + * 0-padded q-point in binary encoding (GCRYPT_MPI_FMT_USG). + */ + unsigned char key[GNUNET_CRYPTO_ECC_MAX_PUBLIC_KEY_LENGTH]; +}; + + +struct GNUNET_CRYPTO_EccPrivateKeyBinaryEncoded +{ + /** + * Overall size of the private key. + */ + uint16_t size; + + /* followd by S-expression, opaque to applications */ + + /* FIXME: consider defining padding to make this a fixed-size struct */ + +}; + + /** * @brief type for session keys */ @@ -205,7 +334,7 @@ GNUNET_NETWORK_STRUCT_END * @brief IV for sym cipher * * NOTE: must be smaller (!) in size than the - * GNUNET_HashCode. + * struct GNUNET_HashCode. */ struct GNUNET_CRYPTO_AesInitializationVector { @@ -320,6 +449,7 @@ GNUNET_CRYPTO_random_permute (enum GNUNET_CRYPTO_Quality mode, unsigned int n); void GNUNET_CRYPTO_aes_create_session_key (struct GNUNET_CRYPTO_AesSessionKey *key); + /** * Check that a new session key is well-formed. * @@ -401,20 +531,82 @@ GNUNET_CRYPTO_aes_derive_iv_v (struct GNUNET_CRYPTO_AesInitializationVector *iv, * safely cast to char*, a '\\0' termination is set). */ void -GNUNET_CRYPTO_hash_to_enc (const GNUNET_HashCode * block, +GNUNET_CRYPTO_hash_to_enc (const struct GNUNET_HashCode * block, struct GNUNET_CRYPTO_HashAsciiEncoded *result); /** - * Convert ASCII encoding back to GNUNET_CRYPTO_hash + * Convert short hash to ASCII encoding. + * + * @param block the hash code + * @param result where to store the encoding (struct GNUNET_CRYPTO_ShortHashAsciiEncoded can be + * safely cast to char*, a '\\0' termination is set). + */ +void +GNUNET_CRYPTO_short_hash_to_enc (const struct GNUNET_CRYPTO_ShortHashCode * block, + struct GNUNET_CRYPTO_ShortHashAsciiEncoded *result); + + +/** + * Convert ASCII encoding back to a 'struct GNUNET_HashCode' + * * @param enc the encoding + * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) * @param result where to store the GNUNET_CRYPTO_hash code * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding */ int -GNUNET_CRYPTO_hash_from_string (const char *enc, GNUNET_HashCode * result); +GNUNET_CRYPTO_hash_from_string2 (const char *enc, size_t enclen, + struct GNUNET_HashCode * result); +/** + * Convert ASCII encoding back to a 'struct GNUNET_CRYPTO_ShortHash' + * + * @param enc the encoding + * @param enclen number of characters in 'enc' (without 0-terminator, which can be missing) + * @param result where to store the GNUNET_CRYPTO_hash code + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +int +GNUNET_CRYPTO_short_hash_from_string2 (const char *enc, size_t enclen, + struct GNUNET_CRYPTO_ShortHashCode * result); + + +/** + * Convert ASCII encoding back to struct GNUNET_HashCode + * + * @param enc the encoding + * @param result where to store the hash code + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +#define GNUNET_CRYPTO_hash_from_string(enc, result) \ + GNUNET_CRYPTO_hash_from_string2 (enc, strlen(enc), result) + + +/** + * Convert ASCII encoding back to a 'struct GNUNET_CRYPTO_ShortHash' + * + * @param enc the encoding + * @param result where to store the GNUNET_CRYPTO_ShortHash + * @return GNUNET_OK on success, GNUNET_SYSERR if result has the wrong encoding + */ +#define GNUNET_CRYPTO_short_hash_from_string(enc, result) \ + GNUNET_CRYPTO_short_hash_from_string2 (enc, strlen(enc), result) + + +/** + * Compare function for ShortHashCodes, producing a total ordering + * of all hashcodes. + * + * @param h1 some hash code + * @param h2 some hash code + * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2. + */ +int +GNUNET_CRYPTO_short_hash_cmp (const struct GNUNET_CRYPTO_ShortHashCode * h1, + const struct GNUNET_CRYPTO_ShortHashCode * h2); + /** * Compute the distance between 2 hashcodes. * The computation must be fast, not involve @@ -427,8 +619,8 @@ GNUNET_CRYPTO_hash_from_string (const char *enc, GNUNET_HashCode * result); * @return number between 0 and UINT32_MAX */ uint32_t -GNUNET_CRYPTO_hash_distance_u32 (const GNUNET_HashCode * a, - const GNUNET_HashCode * b); +GNUNET_CRYPTO_hash_distance_u32 (const struct GNUNET_HashCode * a, + const struct GNUNET_HashCode * b); /** @@ -439,7 +631,43 @@ GNUNET_CRYPTO_hash_distance_u32 (const GNUNET_HashCode * a, * @param ret pointer to where to write the hashcode */ void -GNUNET_CRYPTO_hash (const void *block, size_t size, GNUNET_HashCode * ret); +GNUNET_CRYPTO_hash (const void *block, size_t size, struct GNUNET_HashCode * ret); + + +/** + * Compute short (256-bit) hash of a given block. + * + * @param block the data to hash + * @param size size of the block + * @param ret pointer to where to write the hashcode + */ +void +GNUNET_CRYPTO_short_hash (const void *block, size_t size, + struct GNUNET_CRYPTO_ShortHashCode * ret); + + +/** + * Double short (256-bit) hash to create a long hash. + * + * @param sh short hash to double + * @param dh where to store the (doubled) long hash (not really a hash) + */ +void +GNUNET_CRYPTO_short_hash_double (const struct GNUNET_CRYPTO_ShortHashCode *sh, + struct GNUNET_HashCode *dh); + + +/** + * Truncate doubled short hash back to a short hash. + * + * @param dh doubled short hash to reduce again + * @param sh where to store the short hash + * @return GNUNET_OK on success, GNUNET_SYSERR if this was not a + * doubled short hash + */ +int +GNUNET_CRYPTO_short_hash_from_truncation (const struct GNUNET_HashCode *dh, + struct GNUNET_CRYPTO_ShortHashCode *sh); /** @@ -453,7 +681,7 @@ GNUNET_CRYPTO_hash (const void *block, size_t size, GNUNET_HashCode * ret); void GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, const void *plaintext, size_t plaintext_len, - GNUNET_HashCode * hmac); + struct GNUNET_HashCode * hmac); /** @@ -464,7 +692,7 @@ GNUNET_CRYPTO_hmac (const struct GNUNET_CRYPTO_AuthKey *key, * @param res resulting hash, NULL on error */ typedef void (*GNUNET_CRYPTO_HashCompletedCallback) (void *cls, - const GNUNET_HashCode * + const struct GNUNET_HashCode * res); @@ -507,7 +735,7 @@ GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc); */ void GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode, - GNUNET_HashCode * result); + struct GNUNET_HashCode * result); /** @@ -518,9 +746,9 @@ GNUNET_CRYPTO_hash_create_random (enum GNUNET_CRYPTO_Quality mode, * @param result set to b - a */ void -GNUNET_CRYPTO_hash_difference (const GNUNET_HashCode * a, - const GNUNET_HashCode * b, - GNUNET_HashCode * result); +GNUNET_CRYPTO_hash_difference (const struct GNUNET_HashCode * a, + const struct GNUNET_HashCode * b, + struct GNUNET_HashCode * result); /** @@ -531,9 +759,9 @@ GNUNET_CRYPTO_hash_difference (const GNUNET_HashCode * a, * @param result set to a + delta */ void -GNUNET_CRYPTO_hash_sum (const GNUNET_HashCode * a, - const GNUNET_HashCode * delta, - GNUNET_HashCode * result); +GNUNET_CRYPTO_hash_sum (const struct GNUNET_HashCode * a, + const struct GNUNET_HashCode * delta, + struct GNUNET_HashCode * result); /** @@ -544,8 +772,8 @@ GNUNET_CRYPTO_hash_sum (const GNUNET_HashCode * a, * @param result set to a ^ b */ void -GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a, const GNUNET_HashCode * b, - GNUNET_HashCode * result); +GNUNET_CRYPTO_hash_xor (const struct GNUNET_HashCode * a, const struct GNUNET_HashCode * b, + struct GNUNET_HashCode * result); /** @@ -556,7 +784,7 @@ GNUNET_CRYPTO_hash_xor (const GNUNET_HashCode * a, const GNUNET_HashCode * b, * @param iv set to a valid initialization vector */ void -GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc, +GNUNET_CRYPTO_hash_to_aes_key (const struct GNUNET_HashCode * hc, struct GNUNET_CRYPTO_AesSessionKey *skey, struct GNUNET_CRYPTO_AesInitializationVector *iv); @@ -570,11 +798,11 @@ GNUNET_CRYPTO_hash_to_aes_key (const GNUNET_HashCode * hc, * @return Bit \a bit from hashcode \a code, -1 for invalid index */ int -GNUNET_CRYPTO_hash_get_bit (const GNUNET_HashCode * code, unsigned int bit); +GNUNET_CRYPTO_hash_get_bit (const struct GNUNET_HashCode * code, unsigned int bit); /** * Determine how many low order bits match in two - * GNUNET_HashCodes. i.e. - 010011 and 011111 share + * struct GNUNET_HashCodes. i.e. - 010011 and 011111 share * the first two lowest order bits, and therefore the * return value is two (NOT XOR distance, nor how many * bits match absolutely!). @@ -585,8 +813,8 @@ GNUNET_CRYPTO_hash_get_bit (const GNUNET_HashCode * code, unsigned int bit); * @return the number of bits that match */ unsigned int -GNUNET_CRYPTO_hash_matching_bits (const GNUNET_HashCode * first, - const GNUNET_HashCode * second); +GNUNET_CRYPTO_hash_matching_bits (const struct GNUNET_HashCode * first, + const struct GNUNET_HashCode * second); /** @@ -598,7 +826,7 @@ GNUNET_CRYPTO_hash_matching_bits (const GNUNET_HashCode * first, * @return 1 if h1 > h2, -1 if h1 < h2 and 0 if h1 == h2. */ int -GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1, const GNUNET_HashCode * h2); +GNUNET_CRYPTO_hash_cmp (const struct GNUNET_HashCode * h1, const struct GNUNET_HashCode * h2); /** @@ -611,9 +839,9 @@ GNUNET_CRYPTO_hash_cmp (const GNUNET_HashCode * h1, const GNUNET_HashCode * h2); * @return -1 if h1 is closer, 1 if h2 is closer and 0 if h1==h2. */ int -GNUNET_CRYPTO_hash_xorcmp (const GNUNET_HashCode * h1, - const GNUNET_HashCode * h2, - const GNUNET_HashCode * target); +GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode * h1, + const struct GNUNET_HashCode * h2, + const struct GNUNET_HashCode * target); /** @@ -715,12 +943,37 @@ GNUNET_CRYPTO_kdf (void *result, size_t out_len, const void *xts, /** - * Create a new private key. Caller must free return value. + * Convert a public key to a string. * - * @return fresh private key + * @param pub key to convert + * @return string representing 'pub' */ -struct GNUNET_CRYPTO_RsaPrivateKey * -GNUNET_CRYPTO_rsa_key_create (void); +char * +GNUNET_CRYPTO_rsa_public_key_to_string (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub); + + +/** + * Convert a string representing a public key to a public key. + * + * @param enc encoded public key + * @param enclen number of bytes in enc (without 0-terminator) + * @param pub where to store the public key + * @return GNUNET_OK on success + */ +int +GNUNET_CRYPTO_rsa_public_key_from_string (const char *enc, + size_t enclen, + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pub); + + +/** + * Encode the private key in a format suitable for + * storing it into a file. + * @return encoding of the private key + */ +struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded * +GNUNET_CRYPTO_rsa_encode_key (const struct GNUNET_CRYPTO_RsaPrivateKey *hostkey); + /** * Decode the private key from the data-format back @@ -728,10 +981,12 @@ GNUNET_CRYPTO_rsa_key_create (void); * * @param buf the buffer where the private key data is stored * @param len the length of the data in 'buffer' + * @return NULL on error */ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len); + /** * Create a new private key by reading it from a file. If the * files does not exist, create a new key and write it to the @@ -745,11 +1000,68 @@ GNUNET_CRYPTO_rsa_decode_key (const char *buf, uint16_t len); * @param filename name of file to use for storage * @return new private key, NULL on error (for example, * permission denied) + * @deprecated use 'GNUNET_CRYPTO_rsa_key_create_start' instead */ struct GNUNET_CRYPTO_RsaPrivateKey * GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename); +/** + * Handle to cancel private key generation. + */ +struct GNUNET_CRYPTO_RsaKeyGenerationContext; + + +/** + * Function called upon completion of 'GNUNET_CRYPTO_rsa_key_create_async'. + * + * @param cls closure + * @param pk NULL on error, otherwise the private key (which must be free'd by the callee) + * @param emsg NULL on success, otherwise an error message + */ +typedef void (*GNUNET_CRYPTO_RsaKeyCallback)(void *cls, + struct GNUNET_CRYPTO_RsaPrivateKey *pk, + const char *emsg); + + +/** + * Create a new private key by reading it from a file. If the files + * does not exist, create a new key and write it to the file. If the + * contents of the file are invalid the old file is deleted and a + * fresh key is created. + * + * @param filename name of file to use for storage + * @param cont function to call when done (or on errors) + * @param cont_cls closure for 'cont' + * @return handle to abort operation, NULL on fatal errors (cont will not be called if NULL is returned) + */ +struct GNUNET_CRYPTO_RsaKeyGenerationContext * +GNUNET_CRYPTO_rsa_key_create_start (const char *filename, + GNUNET_CRYPTO_RsaKeyCallback cont, + void *cont_cls); + + +/** + * Abort RSA key generation. + * + * @param gc key generation context to abort + */ +void +GNUNET_CRYPTO_rsa_key_create_stop (struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc); + + +/** + * Setup a hostkey file for a peer given the name of the + * configuration file (!). This function is used so that + * at a later point code can be certain that reading a + * hostkey is fast (for example in time-dependent testcases). + * + * @param cfg_name name of the configuration file to use + */ +void +GNUNET_CRYPTO_rsa_setup_hostkey (const char *cfg_name); + + /** * Deterministically (!) create a private key using only the * given HashCode as input to the PRNG. @@ -758,15 +1070,16 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename); * @return some private key purely dependent on input */ struct GNUNET_CRYPTO_RsaPrivateKey * -GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc); +GNUNET_CRYPTO_rsa_key_create_from_hash (const struct GNUNET_HashCode *hc); /** * Free memory occupied by the private key. - * @param hostkey pointer to the memory to free + * + * @param key pointer to the memory to free */ void -GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *hostkey); +GNUNET_CRYPTO_rsa_key_free (struct GNUNET_CRYPTO_RsaPrivateKey *key); /** @@ -848,6 +1161,179 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose, +/** + * Function called upon completion of 'GNUNET_CRYPTO_ecc_key_create_async'. + * + * @param cls closure + * @param pk NULL on error, otherwise the private key (which must be free'd by the callee) + * @param emsg NULL on success, otherwise an error message + */ +typedef void (*GNUNET_CRYPTO_EccKeyCallback)(void *cls, + struct GNUNET_CRYPTO_EccPrivateKey *pk, + const char *emsg); + + +/** + * Free memory occupied by ECC key + * + * @param privatekey pointer to the memory to free + */ +void +GNUNET_CRYPTO_ecc_key_free (struct GNUNET_CRYPTO_EccPrivateKey *privatekey); + + +/** + * Extract the public key for the given private key. + * + * @param priv the private key + * @param pub where to write the public key + */ +void +GNUNET_CRYPTO_ecc_key_get_public (const struct GNUNET_CRYPTO_EccPrivateKey *priv, + struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pub); + +/** + * Convert a public key to a string. + * + * @param pub key to convert + * @return string representing 'pub' + */ +char * +GNUNET_CRYPTO_ecc_public_key_to_string (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pub); + + +/** + * Convert a string representing a public key to a public key. + * + * @param enc encoded public key + * @param enclen number of bytes in enc (without 0-terminator) + * @param pub where to store the public key + * @return GNUNET_OK on success + */ +int +GNUNET_CRYPTO_ecc_public_key_from_string (const char *enc, + size_t enclen, + struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *pub); + + +/** + * Encode the private key in a format suitable for + * storing it into a file. + * + * @param key key to encode + * @return encoding of the private key. + * The first 4 bytes give the size of the array, as usual. + */ +struct GNUNET_CRYPTO_EccPrivateKeyBinaryEncoded * +GNUNET_CRYPTO_ecc_encode_key (const struct GNUNET_CRYPTO_EccPrivateKey *key); + + +/** + * Decode the private key from the file-format back + * to the "normal", internal format. + * + * @param buf the buffer where the private key data is stored + * @param len the length of the data in 'buffer' + * @return NULL on error + */ +struct GNUNET_CRYPTO_EccPrivateKey * +GNUNET_CRYPTO_ecc_decode_key (const char *buf, + size_t len); + + +/** + * Create a new private key by reading it from a file. If the + * files does not exist, create a new key and write it to the + * file. Caller must free return value. Note that this function + * can not guarantee that another process might not be trying + * the same operation on the same file at the same time. + * If the contents of the file + * are invalid the old file is deleted and a fresh key is + * created. + * + * @return new private key, NULL on error (for example, + * permission denied) + */ +struct GNUNET_CRYPTO_EccPrivateKey * +GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename); + + +/** + * Handle to cancel private key generation and state for the + * key generation operation. + */ +struct GNUNET_CRYPTO_EccKeyGenerationContext; + + +/** + * Create a new private key by reading it from a file. If the files + * does not exist, create a new key and write it to the file. If the + * contents of the file are invalid the old file is deleted and a + * fresh key is created. + * + * @param filename name of file to use for storage + * @param cont function to call when done (or on errors) + * @param cont_cls closure for 'cont' + * @return handle to abort operation, NULL on fatal errors (cont will not be called if NULL is returned) + */ +struct GNUNET_CRYPTO_EccKeyGenerationContext * +GNUNET_CRYPTO_ecc_key_create_start (const char *filename, + GNUNET_CRYPTO_EccKeyCallback cont, + void *cont_cls); + + +/** + * Abort ECC key generation. + * + * @param gc key generation context to abort + */ +void +GNUNET_CRYPTO_ecc_key_create_stop (struct GNUNET_CRYPTO_EccKeyGenerationContext *gc); + +/** + * Setup a hostkey file for a peer given the name of the + * configuration file (!). This function is used so that + * at a later point code can be certain that reading a + * hostkey is fast (for example in time-dependent testcases). + * + * @param cfg_name name of the configuration file to use + */ +void +GNUNET_CRYPTO_ecc_setup_hostkey (const char *cfg_name); + + +/** + * Sign a given block. + * + * @param key private key to use for the signing + * @param purpose what to sign (size, purpose) + * @param sig where to write the signature + * @return GNUNET_SYSERR on error, GNUNET_OK on success + */ +int +GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *key, + const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, + struct GNUNET_CRYPTO_EccSignature *sig); + + +/** + * Verify signature. + * + * @param purpose what is the purpose that the signature should have? + * @param validate block to validate (size, purpose, data) + * @param sig signature that is being validated + * @param publicKey public key of the signer + * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid + */ +int +GNUNET_CRYPTO_ecc_verify (uint32_t purpose, + const struct GNUNET_CRYPTO_EccSignaturePurpose + *validate, + const struct GNUNET_CRYPTO_EccSignature *sig, + const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded + *publicKey); + + /** * This function should only be called in testcases * where strong entropy gathering is not desired @@ -856,6 +1342,18 @@ GNUNET_CRYPTO_rsa_verify (uint32_t purpose, void GNUNET_CRYPTO_random_disable_entropy_gathering (void); + +/** + * Check if we are using weak random number generation. + * + * @return GNUNET_YES if weak number generation is on + * (thus will return YES if 'GNUNET_CRYPTO_random_disable_entropy_gathering' + * was called previously). + */ +int +GNUNET_CRYPTO_random_is_weak (void); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif