diff options
author | Nikos Mavrogiannopoulos <nmav@crystal.(none)> | 2008-06-28 01:25:02 +0300 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@crystal.(none)> | 2008-06-28 01:25:02 +0300 |
commit | 95c55c0eb57484533f4dd72c10481c66a66a53f2 (patch) | |
tree | 3bc580f54abd1775b28415ae8e20aab4fe2baade | |
parent | 0def0a1d7c28de6fd49995755de7b915cf701225 (diff) | |
download | gnutls-95c55c0eb57484533f4dd72c10481c66a66a53f2.tar.gz |
Initial merge attempt with gnutls_with_ext_mpi
104 files changed, 3843 insertions, 4141 deletions
@@ -13,8 +13,18 @@ Reported by Massimo Gaspari <massimo.gaspari@alice.it> in Reported by Roman Bogorodskiy <novel@FreeBSD.org> in <http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/2930>. +** Added API to replace and update the crypto backend. + ** API and ABI modifications: -No changes since last version. +gnutls_crypto_single_cipher_register2: Added +gnutls_crypto_single_mac_register2: Added +gnutls_crypto_single_digest_register2: Added +gnutls_crypto_cipher_register2: Added +gnutls_crypto_mac_register2: Added +gnutls_crypto_digest_register2: Added +gnutls_crypto_rnd_register2: Added +gnutls_crypto_pk_register2: Added +gnutls_crypto_bigint_register2: Added * Version 2.4.0 (released 2008-06-19) @@ -405,8 +415,6 @@ vasprintf symbol from the libgcrypt library which caused problems. ** Update of gnulib files. -** tests: New self-test of crypto.h RNG code tests/crypto_rng. - ** API and ABI modifications: GNUTLS_E_HANDSHAKE_TOO_LARGE: ADDED. diff --git a/doc/gnutls.texi b/doc/gnutls.texi index 5cec27d6e6..49f8431f63 100644 --- a/doc/gnutls.texi +++ b/doc/gnutls.texi @@ -199,7 +199,8 @@ development release. For example, GnuTLS 1.6.3 denote a stable release since 6 is even, and GnuTLS 1.7.11 denote a development release since 7 is odd. -GnuTLS depends on Libgcrypt, and you will need to install Libgcrypt +GnuTLS depends on Libgcrypt, +and you will need to install Libgcrypt before installing GnuTLS. Libgcrypt is available from @url{ftp://ftp.gnupg.org/gcrypt/libgcrypt}. Libgcrypt needs another library, libgpg-error, and you need to install libgpg-error before @@ -389,7 +390,7 @@ widely used OpenSSL@footnote{@url{http://www.openssl.org/}} library, to ease integration with existing applications. @acronym{GnuTLS} consists of three independent parts, namely the ``TLS -protocol part'', the ``Certificate part'', and the ``Crypto backend'' +protocol part'', the ``Certificate part'', and the ``Cryptographic backend'' part. The `TLS protocol part' is the actual protocol implementation, and is entirely implemented within the @acronym{GnuTLS} library. The `Certificate part' consists of the certificate parsing, and @@ -401,9 +402,10 @@ for the @acronym{X.509} certificate parsing functions. A smaller version of @acronym{OpenCDK}@footnote{@url{ftp://ftp.gnupg.org/gcrypt/alpha/gnutls/opencdk/}} is used for the @acronym{OpenPGP} key support in @acronym{GnuTLS}. -The ``Crypto backend'' is provided by the +The ``Cryptographic backend'' is provided by the @acronym{Libgcrypt}@footnote{@url{ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/}} -library. +library@footnote{On current versions of GnuTLS it is possible +to override the default crypto backend. Check @pxref{Cryptographic Backend} for details}. In order to ease integration in embedded systems, parts of the @acronym{GnuTLS} library can be disabled at compile time. That way a @@ -3597,6 +3599,7 @@ expressions. @include guile.texi + @node Internal architecture of GnuTLS @chapter Internal Architecture of GnuTLS @cindex Internal architecture @@ -3606,6 +3609,15 @@ way @acronym{GnuTLS} works. The focus is to give an idea to potential developers and those who want to know what happens inside the black box. +@menu +* The TLS Protocol:: +* TLS Handshake Protocol:: +* TLS Authentication Methods:: +* TLS Extension Handling:: +* Cryptographic Backend:: +@end menu + +@node The TLS Protocol @section The TLS Protocol The main needs for the TLS protocol to be used are shown in the image below. @@ -3618,6 +3630,7 @@ object are just structures with attributes. The operations listed are functions that require the first parameter to be that object. @image{gnutls-objects,15cm} +@node TLS Handshake Protocol @section TLS Handshake Protocol The @acronym{GnuTLS} handshake protocol is implemented as a state machine that waits for input or returns immediately when the non-blocking @@ -3635,6 +3648,7 @@ certificate ciphersuite. @image{gnutls-handshake-sequence,12cm} +@node TLS Authentication Methods @section TLS Authentication Methods In @acronym{GnuTLS} authentication methods can be implemented quite easily. Since the required changes to add a new authentication method affect only the @@ -3652,6 +3666,7 @@ for PSK ciphersuites and @code{auth_srp.c} for SRP ciphersuites. After implement the structure holding its pointers has to be registered in @code{gnutls_algorithms.c} in the @code{_gnutls_kx_algorithms} structure. +@node TLS Extension Handling @section TLS Extension Handling As with authentication methods, the TLS extensions handlers can be implemented using the following interface. @@ -3834,6 +3849,66 @@ is summarized in the following diagram. @image{gnutls-certificate-user-use-case,12cm} +@node Cryptographic Backend +@section Cryptographic Backend +Several new systems provide hardware assisted cryptographic algorithm implementations +that offer implementations some orders of magnitude faster than the software. For this +reason in current releases of GnuTLS it is possible to override parts of the crypto +backend or the whole. It is possible to override them both at runtime and compile time, however +here we will discuss the runtime possibility. The API available for this functionality +is in @code{gnutls/crypto.h} header file. + +@subsection Override specific algorithms +When an optimized implementation of a single algorithm is available, say a +hardware assisted version of @acronym{AES-CBC} then the following functions +can be used to register those algorithms. + +@itemize + +@item @ref{gnutls_crypto_single_cipher_register2} +To register a cipher algorithm. + +@item @ref{gnutls_crypto_single_mac_register2} +To register a MAC algorithm. + +@ref{gnutls_crypto_single_digest_register2} +To register a digest (hash) algorithm. + +@end itemize + +Those registration functions will only replace the specified algorithm and leave the +rest of subsystem intact. + +@subsection Override parts of the backend +In some systems, such as embedded ones, it might be desirable to override big parts +of the cryptographic backend, or even all of them. For this reason the following +functions are provided. + +@itemize + +@item @ref{gnutls_crypto_cipher_register2} +To override the cryptographic algorithms backend. + +@item @ref{gnutls_crypto_mac_register2} +To override the MAC algorithms backend. + +@item @ref{gnutls_crypto_digest_register2} +To override the digest algorithms backend. + +@item @ref{gnutls_crypto_rnd_register2} +To override the random number generator backend. + +@item @ref{gnutls_crypto_bigint_register2} +To override the big number number operations backend. + +@item @ref{gnutls_crypto_pk_register2} +To override the public key encryption backend. This is tight to the big number +operations so either both of them should be updated or care must be taken to +use the same format. + +@end itemize + +If all of them are used then GnuTLS will no longer use libgcrypt. @node Copying Information @appendix Copying Information diff --git a/includes/gnutls/crypto.h b/includes/gnutls/crypto.h index dc45165924..2faedf5a88 100644 --- a/includes/gnutls/crypto.h +++ b/includes/gnutls/crypto.h @@ -22,52 +22,198 @@ * */ -#if INTERNAL_GNUTLS_CRYPTO_H_ENABLE_UNSUPPORTED_API - #ifndef GNUTLS_CRYPTO_H # define GNUTLS_CRYPTO_H -typedef struct gnutls_crypto_cipher { +#define GNUTLS_CRYPTO_API_VERSION 0x01 +typedef struct { int (*init)( void** ctx); - int (*setkey)( void* ctx, const void * key, int keysize); - int (*setiv)(void* ctx, const void* iv, int ivsize); - int (*encrypt)(void* ctx, const void* plain, int plainsize, void* encr, int encrsize); - int (*decrypt)(void* ctx, const void* encr, int encrsize, void* plain, int plainsize); + int (*setkey)( void* ctx, const void * key, size_t keysize); + int (*setiv)(void* ctx, const void* iv, size_t ivsize); + int (*encrypt)(void* ctx, const void* plain, size_t plainsize, void* encr, size_t encrsize); + int (*decrypt)(void* ctx, const void* encr, size_t encrsize, void* plain, size_t plainsize); void (*deinit)( void* ctx); -} gnutls_crypto_cipher_st; +} gnutls_crypto_single_cipher_st; -typedef struct gnutls_crypto_mac { +typedef struct { int (*init)( void** ctx); - int (*setkey)( void* ctx, const void * key, int keysize); - int (*hash)( void* ctx, const void * text, int textsize); + int (*setkey)( void* ctx, const void * key, size_t keysize); + int (*hash)( void* ctx, const void * text, size_t textsize); + int (*copy)( void** dst_ctx, void* src_ctx); + int (*output) ( void* src_ctx, void* digest, size_t digestsize); + void (*deinit)( void* ctx); +} gnutls_crypto_single_mac_st; + +typedef struct { + int (*init)( gnutls_cipher_algorithm_t, void** ctx); + int (*setkey)( void* ctx, const void * key, size_t keysize); + int (*setiv)(void* ctx, const void* iv, size_t ivsize); + int (*encrypt)(void* ctx, const void* plain, size_t plainsize, void* encr, size_t encrsize); + int (*decrypt)(void* ctx, const void* encr, size_t encrsize, void* plain, size_t plainsize); + void (*deinit)( void* ctx); +} gnutls_crypto_cipher_st; + +typedef struct { + int (*init)( gnutls_mac_algorithm_t, void** ctx); + int (*setkey)( void* ctx, const void * key, size_t keysize); + int (*hash)( void* ctx, const void * text, size_t textsize); int (*copy)( void** dst_ctx, void* src_ctx); - int (*output) ( void* src_ctx, void* digest, int digestsize); + int (*output) ( void* src_ctx, void* digest, size_t digestsize); void (*deinit)( void* ctx); } gnutls_crypto_mac_st; +/* the same... setkey should be null */ +typedef gnutls_crypto_single_mac_st gnutls_crypto_single_digest_st; +typedef gnutls_crypto_mac_st gnutls_crypto_digest_st; + typedef enum gnutls_rnd_level { - GNUTLS_RND_KEY = 0, - GNUTLS_RND_RANDOM = 1, /* unpredictable */ - GNUTLS_RND_NONCE = 2, + GNUTLS_RND_KEY = 2, /* fatal in many sessions if broken */ + GNUTLS_RND_RANDOM = 1, /* fatal in session if broken */ + GNUTLS_RND_NONCE = 0, /* fatal in parts of session if broken - i.e. vulnerable to statistical analysis */ } gnutls_rnd_level_t; +typedef enum +{ + GNUTLS_PK_FLAG_NONE = 0, +} gnutls_pk_flag_t; + typedef struct gnutls_crypto_rnd { int (*init)( void** ctx); - int (*rnd) ( void* ctx, int /* gnutls_rnd_level_t */ level, void* data, int datasize); + int (*rnd) ( void* ctx, int /* gnutls_rnd_level_t */ level, void* data, size_t datasize); void (*deinit)( void* ctx); } gnutls_crypto_rnd_st; -/* the same... setkey should be null */ -typedef gnutls_crypto_mac_st gnutls_crypto_digest_st; +typedef void* bigint_t; + +typedef enum +{ + GNUTLS_MPI_FORMAT_USG = 0, /* raw unsigned integer format */ + GNUTLS_MPI_FORMAT_STD = 1, /* raw signed integer format - always a leading zero when positive */ + GNUTLS_MPI_FORMAT_PGP = 2, /* the pgp integer format */ +} gnutls_bigint_format_t; + +typedef struct +{ + bigint_t g; /* group generator */ + bigint_t p; /* prime */ +} gnutls_group_st; + +/* Multi precision integer arithmetic */ +typedef struct gnutls_crypto_bigint { + bigint_t (*bigint_new)( int nbits); + void (*bigint_release)( bigint_t n); + int (*bigint_cmp)(const bigint_t m1, const bigint_t m2); /* 0 for equality, > 0 for m1>m2, < 0 for m1<m2 */ + int (*bigint_cmp_ui)(const bigint_t m1, unsigned long m2); /* as bigint_cmp */ + bigint_t (*bigint_mod) (const bigint_t a, const bigint_t b); /* ret = a % b */ + bigint_t (*bigint_set) (bigint_t a, const bigint_t b); /* a = b -> ret == a */ + bigint_t (*bigint_set_ui) (bigint_t a, unsigned long b); /* a = b -> ret == a */ + unsigned int (*bigint_get_nbits)(const bigint_t a); + bigint_t (*bigint_powm) (bigint_t w, const bigint_t b, const bigint_t e,const bigint_t m); /* w = b ^ e mod m */ + bigint_t (*bigint_addm) (bigint_t w, const bigint_t a, const bigint_t b, const bigint_t m); /* w = a + b mod m */ + bigint_t (*bigint_subm) (bigint_t w, const bigint_t a, const bigint_t b, const bigint_t m); /* w = a - b mod m */ + bigint_t (*bigint_mulm) (bigint_t w, const bigint_t a, const bigint_t b, const bigint_t m); /* w = a * b mod m */ + bigint_t (*bigint_add) (bigint_t w, const bigint_t a, const bigint_t b); /* w = a + b */ + bigint_t (*bigint_sub) (bigint_t w, const bigint_t a, const bigint_t b); /* w = a - b */ + bigint_t (*bigint_mul) (bigint_t w, const bigint_t a, const bigint_t b); /* w = a * b */ + bigint_t (*bigint_add_ui) (bigint_t w, const bigint_t a, unsigned long b); /* w = a + b */ + bigint_t (*bigint_sub_ui) (bigint_t w, const bigint_t a, unsigned long b); /* w = a - b */ + bigint_t (*bigint_mul_ui) (bigint_t w, const bigint_t a, unsigned long b); /* w = a * b */ + bigint_t (*bigint_div) (bigint_t q, const bigint_t a, const bigint_t b); /* q = a / b */ + int (*bigint_prime_check) (const bigint_t pp); /* 0 if prime */ + int (*bigint_generate_group) (gnutls_group_st* gg, unsigned int bits); + + bigint_t (*bigint_scan) ( const void* buf, size_t buf_size, gnutls_bigint_format_t format); /* reads an bigint from a buffer */ + /* stores an bigint into the buffer. + * returns GNUTLS_E_SHORT_MEMORY_BUFFER if buf_size is not sufficient to store this integer, + * and updates the buf_size; + */ + int (*bigint_print)( const bigint_t a, void* buf, size_t* buf_size, gnutls_bigint_format_t format); + +} gnutls_crypto_bigint_st; + +typedef struct pk_params { + bigint_t *params; + unsigned int params_nr; /* the number of parameters */ + unsigned int flags; +} gnutls_pk_params_st; + +void gnutls_pk_params_release( gnutls_pk_params_st* p); +void gnutls_pk_params_init( gnutls_pk_params_st* p); + +/* params are: + * RSA: + * [0] is modulus + * [1] is public exponent + * [2] is private exponent (private key only) + * [3] is prime1 (p) (private key only) + * [4] is prime2 (q) (private key only) + * [5] is coefficient (u == inverse of p mod q) (private key only) + * + * note that other packages use inverse of q mod p, + * so we need to perform conversions using fixup_params(). + * + * DSA: + * [0] is p + * [1] is q + * [2] is g + * [3] is y (public key) + * [4] is x (private key only) + */ + +typedef enum +{ + GNUTLS_IMPORT, + GNUTLS_EXPORT +} gnutls_direction_t; + +/* Public key algorithms */ +typedef struct gnutls_crypto_pk { + /* The params structure should contain the private or public key + * parameters, depending on the operation */ + int (*encrypt)( gnutls_pk_algorithm_t, gnutls_datum_t* ciphertext, + const gnutls_datum_t* plaintext, const gnutls_pk_params_st* /* public */); + int (*decrypt)( gnutls_pk_algorithm_t, gnutls_datum_t* plaintext, + const gnutls_datum_t* ciphertext, const gnutls_pk_params_st* /* private */); + + int (*sign)( gnutls_pk_algorithm_t, gnutls_datum_t* signature, + const gnutls_datum_t* data, const gnutls_pk_params_st* /* private */); + int (*verify)( gnutls_pk_algorithm_t, const gnutls_datum_t* data, + const gnutls_datum_t* signature, const gnutls_pk_params_st* /* public */); + + int (*generate)( gnutls_pk_algorithm_t, unsigned int level /*bits*/, gnutls_pk_params_st*); + /* this function should convert params to ones suitable + * for the above functions + */ + int (*pk_fixup_private_params)( gnutls_pk_algorithm_t, gnutls_direction_t, gnutls_pk_params_st*); + +} gnutls_crypto_pk_st; /* priority: infinity for backend algorithms, 90 for kernel algorithms - lowest wins */ -int gnutls_crypto_cipher_register( gnutls_cipher_algorithm_t algorithm, int priority, gnutls_crypto_cipher_st* s); -int gnutls_crypto_mac_register( gnutls_mac_algorithm_t algorithm, int priority, gnutls_crypto_mac_st* s); -int gnutls_crypto_digest_register( gnutls_digest_algorithm_t algorithm, int priority, gnutls_crypto_digest_st* s); -int gnutls_crypto_rnd_register( int priority, gnutls_crypto_rnd_st* s); +#define gnutls_crypto_single_cipher_register( algo, prio, st) gnutls_crypto_single_cipher_register2( algo, prio, GNUTLS_CRYPTO_API_VERSION, st) +#define gnutls_crypto_single_mac_register( algo, prio, st) gnutls_crypto_single_mac_register2( algo, prio, GNUTLS_CRYPTO_API_VERSION, st) +#define gnutls_crypto_single_digest_register( algo, prio, st) gnutls_crypto_single_digest_register2( algo, prio, GNUTLS_CRYPTO_API_VERSION, st) -#endif +int gnutls_crypto_single_cipher_register2( gnutls_cipher_algorithm_t algorithm, int priority, int version, gnutls_crypto_single_cipher_st* s); +int gnutls_crypto_single_mac_register2( gnutls_mac_algorithm_t algorithm, int priority, int version, gnutls_crypto_single_mac_st* s); +int gnutls_crypto_single_digest_register2( gnutls_digest_algorithm_t algorithm, int priority, int version, gnutls_crypto_single_digest_st* s); + +#define gnutls_crypto_cipher_register( prio, st) gnutls_crypto_cipher_register2( prio, GNUTLS_CRYPTO_API_VERSION, st) +#define gnutls_crypto_mac_register( prio, st) gnutls_crypto_mac_register2( prio, GNUTLS_CRYPTO_API_VERSION, st) +#define gnutls_crypto_digest_register( prio, st) gnutls_crypto_digest_register2( prio, GNUTLS_CRYPTO_API_VERSION, st) + +int gnutls_crypto_cipher_register2( int priority, int version, gnutls_crypto_cipher_st* s); +int gnutls_crypto_mac_register2( int priority, int version, gnutls_crypto_mac_st* s); +int gnutls_crypto_digest_register2( int priority, int version, gnutls_crypto_digest_st* s); + +#define gnutls_crypto_rnd_register( prio, st) gnutls_crypto_rnd_register2( prio, GNUTLS_CRYPTO_API_VERSION, st) +#define gnutls_crypto_pk_register( prio, st) gnutls_crypto_pk_register2( prio, GNUTLS_CRYPTO_API_VERSION, st) +#define gnutls_crypto_bigint_register( prio, st) gnutls_crypto_bigint_register2( prio, GNUTLS_CRYPTO_API_VERSION, st) + +int gnutls_crypto_rnd_register2( int priority, int version, gnutls_crypto_rnd_st* s); +int gnutls_crypto_pk_register2( int priority, int version, gnutls_crypto_pk_st* s); +int gnutls_crypto_bigint_register2( int priority, int version, gnutls_crypto_bigint_st* s); #endif + diff --git a/includes/gnutls/gnutls.h.in b/includes/gnutls/gnutls.h.in index 6f4854091d..1bd5d03876 100644 --- a/includes/gnutls/gnutls.h.in +++ b/includes/gnutls/gnutls.h.in @@ -79,7 +79,19 @@ extern "C" GNUTLS_CIPHER_CAMELLIA_128_CBC, GNUTLS_CIPHER_CAMELLIA_256_CBC, GNUTLS_CIPHER_RC2_40_CBC = 90, - GNUTLS_CIPHER_DES_CBC + GNUTLS_CIPHER_DES_CBC, + + /* used only for PGP internals. Ignored in TLS/SSL + */ + GNUTLS_CIPHER_IDEA_PGP_CFB=200, + GNUTLS_CIPHER_3DES_PGP_CFB, + GNUTLS_CIPHER_CAST5_PGP_CFB, + GNUTLS_CIPHER_BLOWFISH_PGP_CFB, + GNUTLS_CIPHER_SAFER_SK128_PGP_CFB, + GNUTLS_CIPHER_AES128_PGP_CFB, + GNUTLS_CIPHER_AES192_PGP_CFB, + GNUTLS_CIPHER_AES256_PGP_CFB, + GNUTLS_CIPHER_TWOFISH_PGP_CFB, } gnutls_cipher_algorithm_t; typedef enum diff --git a/lib/Makefile.am b/lib/Makefile.am index 2ff3862211..121b638f51 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -84,7 +84,8 @@ COBJECTS = gnutls_record.c gnutls_compress.c debug.c gnutls_cipher.c \ gnutls_x509.c ext_cert_type.c gnutls_rsa_export.c \ auth_rsa_export.c ext_server_name.c auth_dh_common.c \ gnutls_helper.c ext_inner_application.c \ - gnutls_supplemental.c crypto.c random.c + gnutls_supplemental.c crypto.c random.c pk-libgcrypt.c mpi-libgcrypt.c \ + rnd-libgcrypt.c cipher-libgcrypt.c mac-libgcrypt.c if ENABLE_OPRFI COBJECTS += $(OPRFI_COBJECTS) diff --git a/lib/auth_anon.c b/lib/auth_anon.c index e1b46df6cb..fcfe333976 100644 --- a/lib/auth_anon.c +++ b/lib/auth_anon.c @@ -64,8 +64,8 @@ const mod_auth_st anon_auth_struct = { static int gen_anon_server_kx (gnutls_session_t session, opaque ** data) { - mpi_t g, p; - const mpi_t *mpis; + bigint_t g, p; + const bigint_t *mpis; int ret; gnutls_dh_params_t dh_params; gnutls_anon_server_credentials_t cred; @@ -117,9 +117,9 @@ proc_anon_client_kx (gnutls_session_t session, opaque * data, gnutls_anon_server_credentials_t cred; int bits; int ret; - mpi_t p, g; + bigint_t p, g; gnutls_dh_params_t dh_params; - const mpi_t *mpis; + const bigint_t *mpis; bits = _gnutls_dh_get_allowed_prime_bits (session); diff --git a/lib/auth_dh_common.c b/lib/auth_dh_common.c index 20549ca737..0a76c97b71 100644 --- a/lib/auth_dh_common.c +++ b/lib/auth_dh_common.c @@ -54,7 +54,7 @@ _gnutls_free_dh_info (dh_info_st * dh) int _gnutls_proc_dh_common_client_kx (gnutls_session_t session, opaque * data, size_t _data_size, - mpi_t g, mpi_t p) + bigint_t g, bigint_t p) { uint16_t n_Y; size_t _n_Y; @@ -67,7 +67,7 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session, _n_Y = n_Y; DECR_LEN (data_size, n_Y); - if (_gnutls_mpi_scan_nz (&session->key->client_Y, &data[2], &_n_Y)) + if (_gnutls_mpi_scan_nz (&session->key->client_Y, &data[2], _n_Y)) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; @@ -92,12 +92,12 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session, (&session->security_parameters.current_cipher_suite) != GNUTLS_KX_DHE_PSK) { - ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY); + ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key); } else /* In DHE_PSK the key is set differently */ { gnutls_datum_t tmp_dh_key; - ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY); + ret = _gnutls_mpi_dprint (session->key->KEY, &tmp_dh_key); if (ret < 0) { gnutls_assert (); @@ -122,7 +122,7 @@ _gnutls_proc_dh_common_client_kx (gnutls_session_t session, int _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data) { - mpi_t x = NULL, X = NULL; + bigint_t x = NULL, X = NULL; size_t n_X; int ret; @@ -139,7 +139,7 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data) _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x)); - _gnutls_mpi_print (NULL, &n_X, X); + _gnutls_mpi_print (X, NULL, &n_X); (*data) = gnutls_malloc (n_X + 2); if (*data == NULL) { @@ -147,7 +147,7 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data) goto error; } - _gnutls_mpi_print (&(*data)[2], &n_X, X); + _gnutls_mpi_print (X, &(*data)[2], &n_X); _gnutls_mpi_release (&X); _gnutls_write_uint16 (n_X, &(*data)[0]); @@ -173,12 +173,12 @@ _gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data) (&session->security_parameters.current_cipher_suite) != GNUTLS_KX_DHE_PSK) { - ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY); + ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key); } else /* In DHE_PSK the key is set differently */ { gnutls_datum_t tmp_dh_key; - ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY); + ret = _gnutls_mpi_dprint (session->key->KEY, &tmp_dh_key); if (ret < 0) { gnutls_assert (); @@ -258,18 +258,18 @@ _gnutls_proc_dh_common_server_kx (gnutls_session_t session, _n_g = n_g; _n_p = n_p; - if (_gnutls_mpi_scan_nz (&session->key->client_Y, data_Y, &_n_Y) != 0) + if (_gnutls_mpi_scan_nz (&session->key->client_Y, data_Y, _n_Y) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } - if (_gnutls_mpi_scan_nz (&session->key->client_g, data_g, &_n_g) != 0) + if (_gnutls_mpi_scan_nz (&session->key->client_g, data_g, _n_g) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } - if (_gnutls_mpi_scan_nz (&session->key->client_p, data_p, &_n_p) != 0) + if (_gnutls_mpi_scan_nz (&session->key->client_p, data_p, _n_p) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; @@ -305,9 +305,9 @@ _gnutls_proc_dh_common_server_kx (gnutls_session_t session, * be inserted */ int _gnutls_dh_common_print_server_kx (gnutls_session_t session, - mpi_t g, mpi_t p, opaque ** data, int psk) + bigint_t g, bigint_t p, opaque ** data, int psk) { - mpi_t x, X; + bigint_t x, X; size_t n_X, n_g, n_p; int ret, data_size, pos; uint8_t *pdata; @@ -322,9 +322,9 @@ _gnutls_dh_common_print_server_kx (gnutls_session_t session, session->key->dh_secret = x; _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x)); - _gnutls_mpi_print (NULL, &n_g, g); - _gnutls_mpi_print (NULL, &n_p, p); - _gnutls_mpi_print (NULL, &n_X, X); + _gnutls_mpi_print (g, NULL, &n_g); + _gnutls_mpi_print (p, NULL, &n_p); + _gnutls_mpi_print (X, NULL, &n_X); data_size = n_g + n_p + n_X + 6; if (psk != 0) @@ -346,17 +346,17 @@ _gnutls_dh_common_print_server_kx (gnutls_session_t session, pos += 2; } - _gnutls_mpi_print (&pdata[pos + 2], &n_p, p); + _gnutls_mpi_print (p, &pdata[pos + 2], &n_p); _gnutls_write_uint16 (n_p, &pdata[pos]); pos += n_p + 2; - _gnutls_mpi_print (&pdata[pos + 2], &n_g, g); + _gnutls_mpi_print (g, &pdata[pos + 2], &n_g); _gnutls_write_uint16 (n_g, &pdata[pos]); pos += n_g + 2; - _gnutls_mpi_print (&pdata[pos + 2], &n_X, X); + _gnutls_mpi_print (X, &pdata[pos + 2], &n_X); _gnutls_mpi_release (&X); _gnutls_write_uint16 (n_X, &pdata[pos]); diff --git a/lib/auth_dh_common.h b/lib/auth_dh_common.h index be0ad06629..b4ec6b6a00 100644 --- a/lib/auth_dh_common.h +++ b/lib/auth_dh_common.h @@ -38,8 +38,8 @@ void _gnutls_free_dh_info (dh_info_st * dh); int _gnutls_gen_dh_common_client_kx (gnutls_session_t, opaque **); int _gnutls_proc_dh_common_client_kx (gnutls_session_t session, opaque * data, size_t _data_size, - mpi_t p, mpi_t g); -int _gnutls_dh_common_print_server_kx (gnutls_session_t, mpi_t g, mpi_t p, + bigint_t p, bigint_t g); +int _gnutls_dh_common_print_server_kx (gnutls_session_t, bigint_t g, bigint_t p, opaque ** data, int psk); int _gnutls_proc_dh_common_server_kx (gnutls_session_t session, opaque * data, size_t _data_size, diff --git a/lib/auth_dhe.c b/lib/auth_dhe.c index ef10802889..ba5220d28c 100644 --- a/lib/auth_dhe.c +++ b/lib/auth_dhe.c @@ -81,8 +81,8 @@ const mod_auth_st dhe_dss_auth_struct = { static int gen_dhe_server_kx (gnutls_session_t session, opaque ** data) { - mpi_t g, p; - const mpi_t *mpis; + bigint_t g, p; + const bigint_t *mpis; int ret = 0, data_size; int bits; gnutls_cert *apr_cert_list; @@ -245,8 +245,8 @@ proc_dhe_client_kx (gnutls_session_t session, opaque * data, { gnutls_certificate_credentials_t cred; int ret; - mpi_t p, g; - const mpi_t *mpis; + bigint_t p, g; + const bigint_t *mpis; gnutls_dh_params_t dh_params; cred = (gnutls_certificate_credentials_t) diff --git a/lib/auth_dhe_psk.c b/lib/auth_dhe_psk.c index efa26bf082..0e752c2030 100644 --- a/lib/auth_dhe_psk.c +++ b/lib/auth_dhe_psk.c @@ -119,8 +119,8 @@ error: static int gen_psk_server_kx (gnutls_session_t session, opaque ** data) { - mpi_t g, p; - const mpi_t *mpis; + bigint_t g, p; + const bigint_t *mpis; int ret; gnutls_dh_params_t dh_params; gnutls_psk_server_credentials_t cred; @@ -171,9 +171,9 @@ proc_psk_client_kx (gnutls_session_t session, opaque * data, { int bits; int ret; - mpi_t p, g; + bigint_t p, g; gnutls_dh_params_t dh_params; - const mpi_t *mpis; + const bigint_t *mpis; gnutls_psk_server_credentials_t cred; psk_auth_info_t info; gnutls_datum_t username; diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c index d4f34a000d..b84dcb306e 100644 --- a/lib/auth_rsa.c +++ b/lib/auth_rsa.c @@ -41,6 +41,7 @@ #include <gnutls_sig.h> #include <gnutls_x509.h> #include <random.h> +#include <gnutls_mpi.h> int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **); int _gnutls_proc_rsa_client_kx (gnutls_session_t, opaque *, size_t); @@ -66,7 +67,7 @@ const mod_auth_st rsa_auth_struct = { */ int _gnutls_get_public_rsa_params (gnutls_session_t session, - mpi_t params[MAX_PUBLIC_PARAMS_SIZE], + bigint_t params[MAX_PUBLIC_PARAMS_SIZE], int *params_len) { int ret; @@ -98,8 +99,7 @@ _gnutls_get_public_rsa_params (gnutls_session_t session, /* EXPORT case: */ if (_gnutls_cipher_suite_get_kx_algo - (&session->security_parameters.current_cipher_suite) - == GNUTLS_KX_RSA_EXPORT + (&session->security_parameters.current_cipher_suite) == GNUTLS_KX_RSA_EXPORT && _gnutls_mpi_get_nbits (peer_cert.params[0]) > 512) { @@ -147,7 +147,7 @@ _gnutls_get_public_rsa_params (gnutls_session_t session, */ int _gnutls_get_private_rsa_params (gnutls_session_t session, - mpi_t ** params, int *params_size) + bigint_t ** params, int *params_size) { int bits; gnutls_certificate_credentials_t cred; @@ -211,7 +211,7 @@ _gnutls_proc_rsa_client_kx (gnutls_session_t session, opaque * data, gnutls_datum_t plaintext; gnutls_datum_t ciphertext; int ret, dsize; - mpi_t *params; + bigint_t *params; int params_len; int randomize_key = 0; ssize_t data_size = _data_size; @@ -322,7 +322,7 @@ _gnutls_gen_rsa_client_kx (gnutls_session_t session, opaque ** data) { cert_auth_info_t auth = session->key->auth_info; gnutls_datum_t sdata; /* data to send */ - mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; int params_len = MAX_PUBLIC_PARAMS_SIZE; int ret, i; gnutls_protocol_t ver; diff --git a/lib/auth_rsa_export.c b/lib/auth_rsa_export.c index 66826c98d1..3b4b24c045 100644 --- a/lib/auth_rsa_export.c +++ b/lib/auth_rsa_export.c @@ -69,7 +69,7 @@ static int gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data) { gnutls_rsa_params_t rsa_params; - const mpi_t *rsa_mpis; + const bigint_t *rsa_mpis; size_t n_e, n_m; uint8_t *data_e, *data_m; int ret = 0, data_size; @@ -126,8 +126,8 @@ gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data) info = _gnutls_get_auth_info (session); _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]); - _gnutls_mpi_print (NULL, &n_m, rsa_mpis[0]); - _gnutls_mpi_print (NULL, &n_e, rsa_mpis[1]); + _gnutls_mpi_print (rsa_mpis[0], NULL, &n_m); + _gnutls_mpi_print (rsa_mpis[1], NULL, &n_e); (*data) = gnutls_malloc (n_e + n_m + 4); if (*data == NULL) @@ -136,12 +136,12 @@ gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data) } data_m = &(*data)[0]; - _gnutls_mpi_print (&data_m[2], &n_m, rsa_mpis[0]); + _gnutls_mpi_print (rsa_mpis[0], &data_m[2], &n_m); _gnutls_write_uint16 (n_m, data_m); data_e = &data_m[2 + n_m]; - _gnutls_mpi_print (&data_e[2], &n_e, rsa_mpis[1]); + _gnutls_mpi_print (rsa_mpis[1], &data_e[2], &n_e); _gnutls_write_uint16 (n_e, data_e); @@ -275,13 +275,13 @@ proc_rsa_export_server_kx (gnutls_session_t session, _n_e = n_e; _n_m = n_m; - if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, &_n_m) != 0) + if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, _n_m) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } - if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, &_n_e) != 0) + if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, _n_e) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; diff --git a/lib/auth_srp.c b/lib/auth_srp.c index 4f2a5d7db2..d438a163b8 100644 --- a/lib/auth_srp.c +++ b/lib/auth_srp.c @@ -75,10 +75,12 @@ const mod_auth_st srp_auth_struct = { * all are ok. */ inline static int -check_b_mod_n (mpi_t b, mpi_t n) +check_b_mod_n (bigint_t b, bigint_t n) { int ret; - mpi_t r = _gnutls_mpi_alloc_like (b); + bigint_t r; + + r = _gnutls_mpi_mod (b, n); if (r == NULL) { @@ -86,7 +88,6 @@ check_b_mod_n (mpi_t b, mpi_t n) return GNUTLS_E_MEMORY_ERROR; } - _gnutls_mpi_mod (r, b, n); ret = _gnutls_mpi_cmp_ui (r, 0); _gnutls_mpi_release (&r); @@ -105,18 +106,18 @@ check_b_mod_n (mpi_t b, mpi_t n) * all are ok. */ inline static int -check_a_mod_n (mpi_t a, mpi_t n) +check_a_mod_n (bigint_t a, bigint_t n) { int ret; - mpi_t r = _gnutls_mpi_alloc_like (a); + bigint_t r; + r = _gnutls_mpi_mod (a, n); if (r == NULL) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } - _gnutls_mpi_mod (r, a, n); ret = _gnutls_mpi_cmp_ui (r, 0); _gnutls_mpi_release (&r); @@ -172,21 +173,21 @@ _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data) /* copy from pwd_entry to local variables (actually in session) */ tmp_size = pwd_entry->g.size; - if (_gnutls_mpi_scan_nz (&G, pwd_entry->g.data, &tmp_size) < 0) + if (_gnutls_mpi_scan_nz (&G, pwd_entry->g.data, tmp_size) < 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } tmp_size = pwd_entry->n.size; - if (_gnutls_mpi_scan_nz (&N, pwd_entry->n.data, &tmp_size) < 0) + if (_gnutls_mpi_scan_nz (&N, pwd_entry->n.data, tmp_size) < 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } tmp_size = pwd_entry->v.size; - if (_gnutls_mpi_scan_nz (&V, pwd_entry->v.data, &tmp_size) < 0) + if (_gnutls_mpi_scan_nz (&V, pwd_entry->v.data, tmp_size) < 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; @@ -201,7 +202,7 @@ _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data) return GNUTLS_E_MEMORY_ERROR; } - if (_gnutls_mpi_print (NULL, &n_b, B) != 0) + if (_gnutls_mpi_print (B, NULL, &n_b) != 0) { gnutls_assert (); return GNUTLS_E_MPI_PRINT_FAILED; @@ -243,7 +244,7 @@ _gnutls_gen_srp_server_kx (gnutls_session_t session, opaque ** data) */ data_b = &data_s[1 + pwd_entry->salt.size]; - if (_gnutls_mpi_print (&data_b[2], &n_b, B) != 0) + if (_gnutls_mpi_print (B, &data_b[2], &n_b) != 0) { gnutls_assert(); return GNUTLS_E_MPI_PRINT_FAILED; @@ -340,7 +341,7 @@ _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data) _gnutls_mpi_release (&session->key->u); _gnutls_mpi_release (&B); - ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY); + ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key); _gnutls_mpi_release (&S); if (ret < 0) @@ -349,7 +350,7 @@ _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data) return ret; } - if (_gnutls_mpi_print (NULL, &n_a, A) != 0) + if (_gnutls_mpi_print (A, NULL, &n_a) != 0) { gnutls_assert (); return GNUTLS_E_MPI_PRINT_FAILED; @@ -364,7 +365,7 @@ _gnutls_gen_srp_client_kx (gnutls_session_t session, opaque ** data) /* copy A */ data_a = (*data); - if (_gnutls_mpi_print (&data_a[2], &n_a, A) != 0) + if (_gnutls_mpi_print (A, &data_a[2], &n_a) != 0) { gnutls_free (*data); return GNUTLS_E_MPI_PRINT_FAILED; @@ -394,7 +395,7 @@ _gnutls_proc_srp_client_kx (gnutls_session_t session, opaque * data, _n_A = _gnutls_read_uint16 (&data[0]); DECR_LEN (data_size, _n_A); - if (_gnutls_mpi_scan_nz (&A, &data[2], &_n_A) || A == NULL) + if (_gnutls_mpi_scan_nz (&A, &data[2], _n_A) || A == NULL) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; @@ -440,7 +441,7 @@ _gnutls_proc_srp_client_kx (gnutls_session_t session, opaque * data, _gnutls_mpi_release (&session->key->u); _gnutls_mpi_release (&B); - ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY); + ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key); _gnutls_mpi_release (&S); if (ret < 0) @@ -597,9 +598,9 @@ check_g_n (const opaque * g, size_t n_g, const opaque * n, size_t n_n) * Otherwise only the included parameters must be used. */ static int -group_check_g_n (mpi_t g, mpi_t n) +group_check_g_n (bigint_t g, bigint_t n) { - mpi_t q = NULL, two = NULL, w = NULL; + bigint_t q = NULL, two = NULL, w = NULL; int ret; if (_gnutls_mpi_get_nbits (n) < 2048) @@ -611,7 +612,7 @@ group_check_g_n (mpi_t g, mpi_t n) /* N must be of the form N=2q+1 * where q is also a prime. */ - if (_gnutls_prime_check (n, 0) != 0) + if (_gnutls_prime_check (n) != 0) { _gnutls_dump_mpi ("no prime N: ", n); gnutls_assert (); @@ -640,9 +641,9 @@ group_check_g_n (mpi_t g, mpi_t n) /* q = q/2, remember that q is divisible by 2 (prime - 1) */ _gnutls_mpi_set_ui (two, 2); - _gnutls_mpi_div (q, NULL, q, two, 0); + _gnutls_mpi_div (q, q, two); - if (_gnutls_prime_check (q, 0) != 0) + if (_gnutls_prime_check (q) != 0) { /* N was not on the form N=2q+1, where q = prime */ @@ -790,19 +791,19 @@ _gnutls_proc_srp_server_kx (gnutls_session_t session, opaque * data, _n_n = n_n; _n_b = n_b; - if (_gnutls_mpi_scan_nz (&N, data_n, &_n_n) != 0) + if (_gnutls_mpi_scan_nz (&N, data_n, _n_n) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } - if (_gnutls_mpi_scan_nz (&G, data_g, &_n_g) != 0) + if (_gnutls_mpi_scan_nz (&G, data_g, _n_g) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } - if (_gnutls_mpi_scan_nz (&B, data_b, &_n_b) != 0) + if (_gnutls_mpi_scan_nz (&B, data_b, _n_b) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; @@ -843,7 +844,7 @@ _gnutls_proc_srp_server_kx (gnutls_session_t session, opaque * data, return ret; } - if (_gnutls_mpi_scan_nz (&session->key->x, hd, &_n_g) != 0) + if (_gnutls_mpi_scan_nz (&session->key->x, hd, _n_g) != 0) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; diff --git a/lib/cipher-libgcrypt.c b/lib/cipher-libgcrypt.c new file mode 100644 index 0000000000..7a511521bc --- /dev/null +++ b/lib/cipher-libgcrypt.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2008 Free Software Foundation + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +/* Here lie everything that has to do with large numbers, libgcrypt and + * other stuff that didn't fit anywhere else. + */ + +#include <gnutls_int.h> +#include <gnutls_errors.h> +#include <gnutls_cipher_int.h> +#include <gcrypt.h> + +/* Functions that refer to the libgcrypt library. + */ + +static int wrap_gcry_cipher_init( gnutls_cipher_algorithm_t algo, void** ctx) +{ +int err; + + switch (algo) + { + case GNUTLS_CIPHER_AES_128_CBC: + err = gcry_cipher_open ( (gcry_cipher_hd_t *)ctx, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC, 0); + break; + + case GNUTLS_CIPHER_AES_256_CBC: + err = gcry_cipher_open ((gcry_cipher_hd_t *)ctx, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, 0); + break; + + case GNUTLS_CIPHER_3DES_CBC: + err = gcry_cipher_open ((gcry_cipher_hd_t *)ctx, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0); + break; + + case GNUTLS_CIPHER_DES_CBC: + err = gcry_cipher_open ((gcry_cipher_hd_t *)ctx, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC, 0); + break; + + case GNUTLS_CIPHER_ARCFOUR_128: + case GNUTLS_CIPHER_ARCFOUR_40: + err = gcry_cipher_open ((gcry_cipher_hd_t *)ctx, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0); + break; + + case GNUTLS_CIPHER_RC2_40_CBC: + err = gcry_cipher_open ((gcry_cipher_hd_t *)ctx, GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC, 0); + break; + +#ifdef ENABLE_CAMELLIA + case GNUTLS_CIPHER_CAMELLIA_128_CBC: + err = gcry_cipher_open ((gcry_cipher_hd_t *)ctx, GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_MODE_CBC, 0); + break; + + case GNUTLS_CIPHER_CAMELLIA_256_CBC: + err = gcry_cipher_open ((gcry_cipher_hd_t *)ctx, GCRY_CIPHER_CAMELLIA256, GCRY_CIPHER_MODE_CBC, 0); + break; +#endif + default: + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + if (err == 0) return 0; + + gnutls_assert(); + return GNUTLS_E_ENCRYPTION_FAILED; +} + +static int wrap_gcry_cipher_setkey( void* ctx, const void * key, size_t keysize) +{ + gcry_cipher_setkey( ctx, key, keysize); + return 0; +} + +static int wrap_gcry_cipher_setiv( void* ctx, const void * iv, size_t ivsize) +{ + gcry_cipher_setiv( ctx, iv, ivsize); + return 0; +} + +static int wrap_gcry_cipher_decrypt( void* ctx, const void* encr, size_t encrsize, void* plain, size_t plainsize) +{ +int err; + + err = gcry_cipher_decrypt( ctx, plain, plainsize, encr, encrsize); + if (err == 0) return 0; + + gnutls_assert(); + return GNUTLS_E_ENCRYPTION_FAILED; +} + +static int wrap_gcry_cipher_encrypt( void* ctx, const void* plain, size_t plainsize, void* encr, size_t encrsize) +{ +int err; + + err = gcry_cipher_encrypt( ctx, encr, encrsize, plain, plainsize); + if (err == 0) return 0; + + gnutls_assert(); + return GNUTLS_E_ENCRYPTION_FAILED; +} + +int crypto_cipher_prio = INT_MAX; + +gnutls_crypto_cipher_st _gnutls_cipher_ops = { + .init = wrap_gcry_cipher_init, + .setkey = wrap_gcry_cipher_setkey, + .setiv = wrap_gcry_cipher_setiv, + .encrypt = wrap_gcry_cipher_encrypt, + .decrypt = wrap_gcry_cipher_decrypt, + .deinit = gcry_cipher_close, +}; diff --git a/lib/crypto.c b/lib/crypto.c index 92b999bca8..ccc9a81093 100644 --- a/lib/crypto.c +++ b/lib/crypto.c @@ -26,6 +26,10 @@ #include <gnutls_int.h> #include <gnutls/crypto.h> #include <crypto.h> +#include <gnutls_mpi.h> +#include <gnutls_pk.h> +#include <random.h> +#include <gnutls_cipher_int.h> typedef struct algo_list { int algorithm; @@ -37,7 +41,6 @@ typedef struct algo_list { #define cipher_list algo_list #define mac_list algo_list #define digest_list algo_list -#define rnd_list algo_list static int _algo_register( algo_list* al, int algorithm, int priority, void* s) { @@ -101,7 +104,6 @@ cipher_list* cl; static cipher_list glob_cl = { GNUTLS_CIPHER_NULL, 0, NULL, NULL }; static mac_list glob_ml = { GNUTLS_MAC_NULL, 0, NULL, NULL }; static digest_list glob_dl = { GNUTLS_MAC_NULL, 0, NULL, NULL }; -static rnd_list glob_rnd = { 0, 0, NULL, NULL }; static void _deregister(algo_list* cl) { @@ -124,13 +126,13 @@ void _gnutls_crypto_deregister(void) _deregister( &glob_cl); _deregister( &glob_ml); _deregister( &glob_dl); - _deregister( &glob_rnd); } /** - * gnutls_crypto_cipher_register - register a cipher algorithm + * gnutls_crypto_single_cipher_register2 - register a cipher algorithm * @algorithm: is the gnutls algorithm identifier * @priority: is the priority of the algorithm + * @version: should be set to %GNUTLS_CRYPTO_API_VERSION * @s: is a structure holding new cipher's data * * This function will register a cipher algorithm to be used @@ -141,22 +143,31 @@ void _gnutls_crypto_deregister(void) * * This function should be called before gnutls_global_init(). * + * For simplicity you can use the convenience gnutls_crypto_single_cipher_register() + * macro. + * * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. * **/ -int gnutls_crypto_cipher_register( gnutls_cipher_algorithm_t algorithm, int priority, gnutls_crypto_cipher_st* s) +int gnutls_crypto_single_cipher_register2( gnutls_cipher_algorithm_t algorithm, int priority, int version, gnutls_crypto_single_cipher_st* s) { + if (version != GNUTLS_CRYPTO_API_VERSION) + { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } return _algo_register( &glob_cl, algorithm, priority, s); } -gnutls_crypto_cipher_st *_gnutls_get_crypto_cipher( gnutls_cipher_algorithm_t algo) +gnutls_crypto_single_cipher_st *_gnutls_get_crypto_cipher( gnutls_cipher_algorithm_t algo) { return _get_algo( &glob_cl, algo); } /** - * gnutls_crypto_rnd_register - register a random generator + * gnutls_crypto_rnd_register2 - register a random generator * @priority: is the priority of the generator + * @version: should be set to %GNUTLS_CRYPTO_API_VERSION * @s: is a structure holding new generator's data * * This function will register a random generator to be used @@ -167,23 +178,33 @@ gnutls_crypto_cipher_st *_gnutls_get_crypto_cipher( gnutls_cipher_algorithm_t al * * This function should be called before gnutls_global_init(). * + * For simplicity you can use the convenience gnutls_crypto_rnd_register() + * macro. + * * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. * **/ -int gnutls_crypto_rnd_register( int priority, gnutls_crypto_rnd_st* s) +int gnutls_crypto_rnd_register2( int priority, int version, gnutls_crypto_rnd_st* s) { - return _algo_register( &glob_rnd, 1, priority, s); -} + if (version != GNUTLS_CRYPTO_API_VERSION) + { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } -gnutls_crypto_rnd_st *_gnutls_get_crypto_rnd() -{ - return _get_algo( &glob_rnd, 1); + if (crypto_rnd_prio > priority) { + memcpy( &_gnutls_rnd_ops, s, sizeof(*s)); + crypto_rnd_prio = priority; + return 0; + } + return GNUTLS_E_CRYPTO_ALREADY_REGISTERED; } /** - * gnutls_crypto_mac_register - register a MAC algorithm + * gnutls_crypto_single_mac_register2 - register a MAC algorithm * @algorithm: is the gnutls algorithm identifier * @priority: is the priority of the algorithm + * @version: should be set to %GNUTLS_CRYPTO_API_VERSION * @s: is a structure holding new algorithms's data * * This function will register a MAC algorithm to be used @@ -194,23 +215,33 @@ gnutls_crypto_rnd_st *_gnutls_get_crypto_rnd() * * This function should be called before gnutls_global_init(). * + * For simplicity you can use the convenience gnutls_crypto_single_mac_register() + * macro. + * * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. * **/ -int gnutls_crypto_mac_register( gnutls_mac_algorithm_t algorithm, int priority, gnutls_crypto_mac_st* s) +int gnutls_crypto_single_mac_register2( gnutls_mac_algorithm_t algorithm, int priority, int version, gnutls_crypto_single_mac_st* s) { + if (version != GNUTLS_CRYPTO_API_VERSION) + { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + return _algo_register( &glob_ml, algorithm, priority, s); } -gnutls_crypto_mac_st *_gnutls_get_crypto_mac( gnutls_mac_algorithm_t algo) +gnutls_crypto_single_mac_st *_gnutls_get_crypto_mac( gnutls_mac_algorithm_t algo) { return _get_algo( &glob_ml, algo); } /** - * gnutls_crypto_digest_register - register a digest algorithm + * gnutls_crypto_single_digest_register2 - register a digest algorithm * @algorithm: is the gnutls algorithm identifier * @priority: is the priority of the algorithm + * @version: should be set to %GNUTLS_CRYPTO_API_VERSION * @s: is a structure holding new algorithms's data * * This function will register a digest (hash) algorithm to be used @@ -221,15 +252,208 @@ gnutls_crypto_mac_st *_gnutls_get_crypto_mac( gnutls_mac_algorithm_t algo) * * This function should be called before gnutls_global_init(). * + * For simplicity you can use the convenience gnutls_crypto_single_digest_register() + * macro. + * * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. * **/ -int gnutls_crypto_digest_register( gnutls_digest_algorithm_t algorithm, int priority, gnutls_crypto_digest_st* s) +int gnutls_crypto_single_digest_register2( gnutls_digest_algorithm_t algorithm, int priority, int version, gnutls_crypto_single_digest_st* s) { + if (version != GNUTLS_CRYPTO_API_VERSION) + { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } return _algo_register( &glob_dl, algorithm, priority, s); } -gnutls_crypto_digest_st *_gnutls_get_crypto_digest( gnutls_digest_algorithm_t algo) +gnutls_crypto_single_digest_st *_gnutls_get_crypto_digest( gnutls_digest_algorithm_t algo) { return _get_algo( &glob_dl, algo); } + +/** + * gnutls_crypto_bigint_register2 - register a bigint interface + * @priority: is the priority of the interface + * @version: should be set to %GNUTLS_CRYPTO_API_VERSION + * @s: is a structure holding new interface's data + * + * This function will register an interface for gnutls to operate + * on big integers. Any interface registered will override + * the included interface. The interface with the lowest + * priority will be used by gnutls. + * + * Note that the bigint interface must interoperate with the public + * key interface. Thus if this interface is updated the + * gnutls_crypto_pk_register() should also be used. + * + * This function should be called before gnutls_global_init(). + * + * For simplicity you can use the convenience gnutls_crypto_bigint_register() + * macro. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + * + **/ +int gnutls_crypto_bigint_register2( int priority, int version, gnutls_crypto_bigint_st* s) +{ + if (version != GNUTLS_CRYPTO_API_VERSION) + { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + + if (crypto_bigint_prio > priority) { + memcpy( &_gnutls_mpi_ops, s, sizeof(*s)); + crypto_bigint_prio = priority; + return 0; + } + return GNUTLS_E_CRYPTO_ALREADY_REGISTERED; +} + +/** + * gnutls_crypto_pk_register2 - register a public key interface + * @priority: is the priority of the interface + * @version: should be set to %GNUTLS_CRYPTO_API_VERSION + * @s: is a structure holding new interface's data + * + * This function will register an interface for gnutls to operate + * on public key operations. Any interface registered will override + * the included interface. The interface with the lowest + * priority will be used by gnutls. + * + * Note that the bigint interface must interoperate with the bigint + * interface. Thus if this interface is updated the + * gnutls_crypto_bigint_register() should also be used. + * + * This function should be called before gnutls_global_init(). + * + * For simplicity you can use the convenience gnutls_crypto_pk_register() + * macro. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + * + **/ +int gnutls_crypto_pk_register2( int priority, int version, gnutls_crypto_pk_st* s) +{ + if (version != GNUTLS_CRYPTO_API_VERSION) + { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + if (crypto_pk_prio > priority) { + memcpy( &_gnutls_pk_ops, s, sizeof(*s)); + crypto_pk_prio = priority; + return 0; + } + return GNUTLS_E_CRYPTO_ALREADY_REGISTERED; +} + +/** + * gnutls_crypto_cipher_register2 - register a cipher interface + * @priority: is the priority of the cipher interface + * @version: should be set to %GNUTLS_CRYPTO_API_VERSION + * @s: is a structure holding new interface's data + * + * This function will register a cipher interface to be used + * by gnutls. Any interface registered will override + * the included engine and by convention kernel implemented + * interfaces should have priority of 90. The interface with the lowest + * priority will be used by gnutls. + * + * This function should be called before gnutls_global_init(). + * + * For simplicity you can use the convenience gnutls_crypto_cipher_register() + * macro. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + * + **/ +int gnutls_crypto_cipher_register2( int priority, int version, gnutls_crypto_cipher_st* s) +{ + if (version != GNUTLS_CRYPTO_API_VERSION) + { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + + if (crypto_cipher_prio > priority) { + memcpy( &_gnutls_cipher_ops, s, sizeof(*s)); + crypto_cipher_prio = priority; + return 0; + } + return GNUTLS_E_CRYPTO_ALREADY_REGISTERED; +} + +/** + * gnutls_crypto_mac_register2 - register a mac interface + * @priority: is the priority of the mac interface + * @version: should be set to %GNUTLS_CRYPTO_API_VERSION + * @s: is a structure holding new interface's data + * + * This function will register a mac interface to be used + * by gnutls. Any interface registered will override + * the included engine and by convention kernel implemented + * interfaces should have priority of 90. The interface with the lowest + * priority will be used by gnutls. + * + * This function should be called before gnutls_global_init(). + * + * For simplicity you can use the convenience gnutls_crypto_mac_register() + * macro. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + * + **/ +int gnutls_crypto_mac_register2( int priority, int version, gnutls_crypto_mac_st* s) +{ + if (version != GNUTLS_CRYPTO_API_VERSION) + { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + + if (crypto_mac_prio > priority) { + memcpy( &_gnutls_mac_ops, s, sizeof(*s)); + crypto_mac_prio = priority; + return 0; + } + return GNUTLS_E_CRYPTO_ALREADY_REGISTERED; +} + +/** + * gnutls_crypto_digest_register2 - register a digest interface + * @priority: is the priority of the digest interface + * @version: should be set to %GNUTLS_CRYPTO_API_VERSION + * @s: is a structure holding new interface's data + * + * This function will register a digest interface to be used + * by gnutls. Any interface registered will override + * the included engine and by convention kernel implemented + * interfaces should have priority of 90. The interface with the lowest + * priority will be used by gnutls. + * + * This function should be called before gnutls_global_init(). + * + * For simplicity you can use the convenience gnutls_crypto_digest_register() + * macro. + * + * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error. + * + **/ +int gnutls_crypto_digest_register2( int priority, int version, gnutls_crypto_digest_st* s) +{ + if (version != GNUTLS_CRYPTO_API_VERSION) + { + gnutls_assert(); + return GNUTLS_E_UNIMPLEMENTED_FEATURE; + } + + if (crypto_digest_prio > priority) { + memcpy( &_gnutls_digest_ops, s, sizeof(*s)); + crypto_digest_prio = priority; + return 0; + } + return GNUTLS_E_CRYPTO_ALREADY_REGISTERED; +} diff --git a/lib/crypto.h b/lib/crypto.h index 4497f6b7f0..3fb1b86719 100644 --- a/lib/crypto.h +++ b/lib/crypto.h @@ -1,5 +1,4 @@ -gnutls_crypto_cipher_st *_gnutls_get_crypto_cipher( gnutls_cipher_algorithm_t algo); -gnutls_crypto_digest_st *_gnutls_get_crypto_digest( gnutls_digest_algorithm_t algo); -gnutls_crypto_mac_st *_gnutls_get_crypto_mac( gnutls_mac_algorithm_t algo); -gnutls_crypto_rnd_st *_gnutls_get_crypto_rnd( void ); +gnutls_crypto_single_cipher_st *_gnutls_get_crypto_cipher( gnutls_cipher_algorithm_t algo); +gnutls_crypto_single_digest_st *_gnutls_get_crypto_digest( gnutls_digest_algorithm_t algo); +gnutls_crypto_single_mac_st *_gnutls_get_crypto_mac( gnutls_mac_algorithm_t algo); void _gnutls_crypto_deregister(void); diff --git a/lib/debug.c b/lib/debug.c index ef5a4af601..e63e8b019e 100644 --- a/lib/debug.c +++ b/lib/debug.c @@ -117,12 +117,14 @@ _gnutls_handshake2str (gnutls_handshake_description_t handshake) } void -_gnutls_dump_mpi (const char *prefix, mpi_t a) +_gnutls_dump_mpi (const char *prefix, bigint_t a) { + opaque mpi_buf[1024]; opaque buf[1024]; size_t n = sizeof buf; - if (gcry_mpi_print (GCRYMPI_FMT_HEX, buf, n, &n, a)) + if (_gnutls_mpi_print (a, mpi_buf, &n) < 0) strcpy (buf, "[can't print value]"); /* Flawfinder: ignore */ - _gnutls_hard_log ("MPI: length: %d\n\t%s%s\n", (n - 1) / 2, prefix, buf); + else _gnutls_bin2hex (mpi_buf, n, buf, sizeof(buf)); + _gnutls_hard_log ("MPI: length: %d\n\t%s%s\n", n, prefix, buf); } diff --git a/lib/debug.h b/lib/debug.h index 169bc21d9e..6832ed7284 100644 --- a/lib/debug.h +++ b/lib/debug.h @@ -27,4 +27,4 @@ void _gnutls_print_state (gnutls_session_t session); #endif const char *_gnutls_packet2str (content_type_t packet); const char *_gnutls_handshake2str (gnutls_handshake_description_t handshake); -void _gnutls_dump_mpi (const char *prefix, mpi_t a); +void _gnutls_dump_mpi (const char *prefix, bigint_t a); diff --git a/lib/gnutls_algorithms.c b/lib/gnutls_algorithms.c index 36dd77da12..da34f5e180 100644 --- a/lib/gnutls_algorithms.c +++ b/lib/gnutls_algorithms.c @@ -171,6 +171,18 @@ static const gnutls_cipher_entry algorithms[] = { {"CAMELLIA-128-CBC", GNUTLS_CIPHER_CAMELLIA_128_CBC, 16, 16, CIPHER_BLOCK, 16, 0}, #endif + +#ifdef ENABLE_OPENPGP + {"IDEA-PGP-CFB", GNUTLS_CIPHER_IDEA_PGP_CFB, 8, 16, CIPHER_BLOCK, 8, 0}, + {"3DES-PGP-CFB", GNUTLS_CIPHER_3DES_PGP_CFB, 8, 24, CIPHER_BLOCK, 8, 0}, + {"CAST5-PGP-CFB", GNUTLS_CIPHER_CAST5_PGP_CFB, 8, 16, CIPHER_BLOCK, 8, 0}, + {"BLOWFISH-PGP-CFB", GNUTLS_CIPHER_BLOWFISH_PGP_CFB, 8, 16/*actually unlimited*/, CIPHER_BLOCK, 8, 0}, + {"SAFER-SK128-PGP-CFB", GNUTLS_CIPHER_SAFER_SK128_PGP_CFB, 8, 16, CIPHER_BLOCK, 8, 0}, + {"AES-128-PGP-CFB", GNUTLS_CIPHER_AES128_PGP_CFB, 16, 16, CIPHER_BLOCK, 16, 0}, + {"AES-192-PGP-CFB", GNUTLS_CIPHER_AES192_PGP_CFB, 16, 24, CIPHER_BLOCK, 16, 0}, + {"AES-256-PGP-CFB", GNUTLS_CIPHER_AES256_PGP_CFB, 16, 32, CIPHER_BLOCK, 16, 0}, + {"TWOFISH-PGP-CFB", GNUTLS_CIPHER_TWOFISH_PGP_CFB, 16, 16, CIPHER_BLOCK, 16, 0}, +#endif {"NULL", GNUTLS_CIPHER_NULL, 1, 0, CIPHER_STREAM, 0, 0}, {0, 0, 0, 0, 0, 0, 0} }; diff --git a/lib/gnutls_cert.h b/lib/gnutls_cert.h index 426554cc89..b7c80b59a6 100644 --- a/lib/gnutls_cert.h +++ b/lib/gnutls_cert.h @@ -51,7 +51,7 @@ typedef struct gnutls_cert { - mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; /* the size of params depends on the public + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; /* the size of params depends on the public * key algorithm * RSA: [0] is modulus * [1] is public exponent @@ -82,7 +82,7 @@ typedef struct gnutls_cert typedef struct gnutls_privkey_int { - mpi_t params[MAX_PRIV_PARAMS_SIZE]; /* the size of params depends on the public + bigint_t params[MAX_PRIV_PARAMS_SIZE]; /* the size of params depends on the public * key algorithm */ /* diff --git a/lib/gnutls_cipher_int.c b/lib/gnutls_cipher_int.c index a7b50b9b1c..5ed60fa5b2 100644 --- a/lib/gnutls_cipher_int.c +++ b/lib/gnutls_cipher_int.c @@ -31,7 +31,7 @@ #define SR(x, cleanup) if ( (x)<0 ) { \ gnutls_assert(); \ - err = GNUTLS_E_INTERNAL_ERROR; \ + ret = GNUTLS_E_INTERNAL_ERROR; \ goto cleanup; \ } @@ -39,8 +39,8 @@ int _gnutls_cipher_init (cipher_hd_st* handle, gnutls_cipher_algorithm_t cipher, const gnutls_datum_t * key, const gnutls_datum_t * iv) { - int err = GC_INVALID_CIPHER; /* doesn't matter */ - gnutls_crypto_cipher_st * cc = NULL; + int ret = GNUTLS_E_INTERNAL_ERROR; + gnutls_crypto_single_cipher_st * cc = NULL; /* check if a cipher has been registered */ @@ -48,75 +48,33 @@ _gnutls_cipher_init (cipher_hd_st* handle, gnutls_cipher_algorithm_t cipher, if (cc != NULL) { handle->registered = 1; handle->hd.rh.cc = cc; - SR( cc->init(&handle->hd.rh.ctx), cc_cleanup ); + SR(cc->init(&handle->hd.rh.ctx), cc_cleanup); SR(cc->setkey( handle->hd.rh.ctx, key->data, key->size), cc_cleanup); if (iv->data && iv->size && cc->setiv) SR(cc->setiv( handle->hd.rh.ctx, iv->data, iv->size), cc_cleanup); return 0; } - handle->registered = 0; - /* otherwise use included ciphers + handle->registered = 0; + + /* otherwise use generic cipher interface */ - switch (cipher) - { - case GNUTLS_CIPHER_AES_128_CBC: - err = gc_cipher_open (GC_AES128, GC_CBC, &handle->hd.gc); - break; - - case GNUTLS_CIPHER_AES_256_CBC: - err = gc_cipher_open (GC_AES256, GC_CBC, &handle->hd.gc); - break; - - case GNUTLS_CIPHER_3DES_CBC: - err = gc_cipher_open (GC_3DES, GC_CBC, &handle->hd.gc); - break; - - case GNUTLS_CIPHER_DES_CBC: - err = gc_cipher_open (GC_DES, GC_CBC, &handle->hd.gc); - break; - - case GNUTLS_CIPHER_ARCFOUR_128: - err = gc_cipher_open (GC_ARCFOUR128, GC_STREAM, &handle->hd.gc); - break; - - case GNUTLS_CIPHER_ARCFOUR_40: - err = gc_cipher_open (GC_ARCFOUR40, GC_STREAM, &handle->hd.gc); - break; - - case GNUTLS_CIPHER_RC2_40_CBC: - err = gc_cipher_open (GC_ARCTWO40, GC_CBC, &handle->hd.gc); - break; - -#ifdef ENABLE_CAMELLIA - case GNUTLS_CIPHER_CAMELLIA_128_CBC: - err = gc_cipher_open (GC_CAMELLIA128, GC_CBC, &handle->hd.gc); - break; - - case GNUTLS_CIPHER_CAMELLIA_256_CBC: - err = gc_cipher_open (GC_CAMELLIA256, GC_CBC, &handle->hd.gc); - break; -#endif - - default: - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } + ret = _gnutls_cipher_ops.init( cipher, &handle->hd.gc); + if (ret < 0) { + gnutls_assert(); + return ret; + } - if (err == 0) - { - gc_cipher_setkey (handle->hd.gc, key->size, key->data); - if (iv->data != NULL && iv->size > 0) - gc_cipher_setiv (handle->hd.gc, iv->size, iv->data); - } - else if (cipher != GNUTLS_CIPHER_NULL) - { - gnutls_assert (); - _gnutls_x509_log ("Crypto cipher[%d] error: %d\n", cipher, err); - return GNUTLS_E_INTERNAL_ERROR; - /* FIXME: gc_strerror */ - } + ret = _gnutls_cipher_ops.setkey (handle->hd.gc, key->data, key->size); + if (ret < 0) { + _gnutls_cipher_ops.deinit( handle->hd.gc); + gnutls_assert(); + return ret; + } + if (iv->data != NULL && iv->size > 0) + _gnutls_cipher_ops.setiv (handle->hd.gc, iv->data, iv->size); + return 0; cc_cleanup: @@ -124,7 +82,7 @@ cc_cleanup: if (handle->hd.rh.cc) cc->deinit(handle->hd.rh.ctx); - return err; + return ret; } int @@ -138,11 +96,7 @@ _gnutls_cipher_encrypt (const cipher_hd_st* handle, void *text, int textlen) } if (handle->hd.gc == NULL) return 0; - if (gc_cipher_encrypt_inline (handle->hd.gc, textlen, text) != 0) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } + return _gnutls_cipher_ops.encrypt( handle->hd.gc, text, textlen, text, textlen); } return 0; } @@ -159,11 +113,7 @@ _gnutls_cipher_decrypt (const cipher_hd_st *handle, void *ciphertext, } if (handle->hd.gc == NULL) return 0; - if (gc_cipher_decrypt_inline (handle->hd.gc, ciphertextlen, ciphertext) != 0) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } + return _gnutls_cipher_ops.decrypt (handle->hd.gc, ciphertext, ciphertextlen, ciphertext, ciphertextlen); } return 0; } @@ -176,6 +126,6 @@ _gnutls_cipher_deinit (cipher_hd_st* handle) if (handle->registered && handle->hd.rh.ctx != NULL) { return handle->hd.rh.cc->deinit( handle->hd.rh.ctx); } - gc_cipher_close (handle->hd.gc); + _gnutls_cipher_ops.deinit (handle->hd.gc); } } diff --git a/lib/gnutls_cipher_int.h b/lib/gnutls_cipher_int.h index 897d805850..f004f55b27 100644 --- a/lib/gnutls_cipher_int.h +++ b/lib/gnutls_cipher_int.h @@ -27,15 +27,18 @@ #include <gnutls/crypto.h> +extern int crypto_cipher_prio; +extern gnutls_crypto_cipher_st _gnutls_cipher_ops; + typedef struct { - gnutls_crypto_cipher_st* cc; + gnutls_crypto_single_cipher_st* cc; void* ctx; } reg_hd; typedef struct { int registered; /* true or false(0) */ union { - gc_cipher_handle gc; /* when not registered */ + void* gc; /* when not registered */ reg_hd rh; /* when registered */ } hd; } cipher_hd_st; diff --git a/lib/gnutls_datum.h b/lib/gnutls_datum.h index 0f609531de..516d64e398 100644 --- a/lib/gnutls_datum.h +++ b/lib/gnutls_datum.h @@ -22,6 +22,9 @@ * */ +#ifndef GNUTLS_DATUM_H +# define GNUTLS_DATUM_H + void _gnutls_write_datum16 (opaque * dest, gnutls_datum_t dat); void _gnutls_write_datum24 (opaque * dest, gnutls_datum_t dat); void _gnutls_write_datum32 (opaque * dest, gnutls_datum_t dat); @@ -38,3 +41,5 @@ int _gnutls_datum_append_m (gnutls_datum_t * dat, const void *data, void _gnutls_free_datum_m (gnutls_datum_t * dat, gnutls_free_function); #define _gnutls_free_datum(x) _gnutls_free_datum_m(x, gnutls_free) + +#endif diff --git a/lib/gnutls_dh.c b/lib/gnutls_dh.c index 5bf5ec2774..1ceb8f203f 100644 --- a/lib/gnutls_dh.c +++ b/lib/gnutls_dh.c @@ -46,10 +46,10 @@ /* returns the public value (X), and the secret (ret_x). */ -mpi_t -gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime) +bigint_t +gnutls_calc_dh_secret (bigint_t * ret_x, bigint_t g, bigint_t prime) { - mpi_t e, x; + bigint_t e, x = NULL; int x_size = _gnutls_mpi_get_nbits (prime) - 1; /* The size of the secret key is less than * prime/2 @@ -61,27 +61,13 @@ gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime) return NULL; } - x = _gnutls_mpi_new (x_size); + x = _gnutls_mpi_randomize( NULL, x_size, GNUTLS_RND_RANDOM); if (x == NULL) { - gnutls_assert (); - if (ret_x) - *ret_x = NULL; - + gnutls_assert(); return NULL; } - /* FIXME: (x_size/8)*8 is there to overcome a bug in libgcrypt - * which does not really check the bits given but the bytes. - */ - do - { - _gnutls_mpi_randomize (x, (x_size / 8) * 8, GCRY_STRONG_RANDOM); - /* Check whether x is zero. - */ - } - while (_gnutls_mpi_cmp_ui (x, 0) == 0); - e = _gnutls_mpi_alloc_like (prime); if (e == NULL) { @@ -103,10 +89,10 @@ gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime) } -mpi_t -gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime) +bigint_t +gnutls_calc_dh_key (bigint_t f, bigint_t x, bigint_t prime) { - mpi_t k; + bigint_t k; int bits; bits = _gnutls_mpi_get_nbits (prime); diff --git a/lib/gnutls_dh.h b/lib/gnutls_dh.h index dc8a129da9..d9ab4153a6 100644 --- a/lib/gnutls_dh.h +++ b/lib/gnutls_dh.h @@ -25,10 +25,9 @@ #ifndef GNUTLS_DH_H # define GNUTLS_DH_H -const mpi_t *_gnutls_dh_params_to_mpi (gnutls_dh_params_t); -mpi_t gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime); -mpi_t gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime); -int _gnutls_dh_generate_prime (mpi_t * ret_g, mpi_t * ret_n, unsigned bits); +const bigint_t *_gnutls_dh_params_to_mpi (gnutls_dh_params_t); +bigint_t gnutls_calc_dh_secret (bigint_t * ret_x, bigint_t g, bigint_t prime); +bigint_t gnutls_calc_dh_key (bigint_t f, bigint_t x, bigint_t prime); gnutls_dh_params_t _gnutls_get_dh_params (gnutls_dh_params_t dh_params, diff --git a/lib/gnutls_dh_primes.c b/lib/gnutls_dh_primes.c index 720d2ee7d2..5ad7ce1b91 100644 --- a/lib/gnutls_dh_primes.c +++ b/lib/gnutls_dh_primes.c @@ -28,13 +28,15 @@ #include <x509_b64.h> /* for PKCS3 PEM decoding */ #include <gnutls_global.h> #include <gnutls_dh.h> +#include <gnutls_pk.h> +#include <gnutls/crypto.h> #include "x509/x509_int.h" #include "debug.h" /* returns the prime and the generator of DH params. */ -const mpi_t * +const bigint_t * _gnutls_dh_params_to_mpi (gnutls_dh_params_t dh_primes) { if (dh_primes == NULL || dh_primes->params[1] == NULL || @@ -46,94 +48,6 @@ _gnutls_dh_params_to_mpi (gnutls_dh_params_t dh_primes) return dh_primes->params; } -int -_gnutls_dh_generate_prime (mpi_t * ret_g, mpi_t * ret_n, unsigned int bits) -{ - mpi_t g = NULL, prime = NULL; - gcry_error_t err; - int result, times = 0, qbits; - mpi_t *factors = NULL; - - /* Calculate the size of a prime factor of (prime-1)/2. - * This is an emulation of the values in "Selecting Cryptographic Key Sizes" paper. - */ - if (bits < 256) - qbits = bits / 2; - else - { - qbits = (bits/40) + 105; - } - - if (qbits & 1) /* better have an even number */ - qbits++; - - /* find a prime number of size bits. - */ - do - { - - if (times) - { - _gnutls_mpi_release (&prime); - gcry_prime_release_factors (factors); - } - - err = gcry_prime_generate (&prime, bits, qbits, - &factors, NULL, NULL, GCRY_STRONG_RANDOM, - GCRY_PRIME_FLAG_SPECIAL_FACTOR); - - if (err != 0) - { - gnutls_assert (); - result = GNUTLS_E_INTERNAL_ERROR; - goto cleanup; - } - - err = gcry_prime_check (prime, 0); - - times++; - } - while (err != 0 && times < 10); - - if (err != 0) - { - gnutls_assert (); - result = GNUTLS_E_INTERNAL_ERROR; - goto cleanup; - } - - /* generate the group generator. - */ - err = gcry_prime_group_generator (&g, prime, factors, NULL); - if (err != 0) - { - gnutls_assert (); - result = GNUTLS_E_INTERNAL_ERROR; - goto cleanup; - } - - gcry_prime_release_factors (factors); - factors = NULL; - - if (ret_g) - *ret_g = g; - else - _gnutls_mpi_release (&g); - if (ret_n) - *ret_n = prime; - else - _gnutls_mpi_release (&prime); - - return 0; - -cleanup: - gcry_prime_release_factors (factors); - _gnutls_mpi_release (&g); - _gnutls_mpi_release (&prime); - - return result; - -} /* Replaces the prime in the static DH parameters, with a randomly * generated one. @@ -154,18 +68,18 @@ gnutls_dh_params_import_raw (gnutls_dh_params_t dh_params, const gnutls_datum_t * prime, const gnutls_datum_t * generator) { - mpi_t tmp_prime, tmp_g; + bigint_t tmp_prime, tmp_g; size_t siz; siz = prime->size; - if (_gnutls_mpi_scan_nz (&tmp_prime, prime->data, &siz)) + if (_gnutls_mpi_scan_nz (&tmp_prime, prime->data, siz)) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } siz = generator->size; - if (_gnutls_mpi_scan_nz (&tmp_g, generator->data, &siz)) + if (_gnutls_mpi_scan_nz (&tmp_g, generator->data, siz)) { _gnutls_mpi_release (&tmp_prime); gnutls_assert (); @@ -268,14 +182,17 @@ int gnutls_dh_params_generate2 (gnutls_dh_params_t params, unsigned int bits) { int ret; + gnutls_group_st group; - ret = _gnutls_dh_generate_prime (¶ms->params[1], - ¶ms->params[0], bits); + ret = _gnutls_mpi_generate_group (&group, bits); if (ret < 0) { gnutls_assert (); return ret; } + + params->params[0] = group.g; + params->params[1] = group.p; return 0; } @@ -421,8 +338,8 @@ gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params, opaque *p_data, *g_data; opaque *all_data; - _gnutls_mpi_print_lz (NULL, &g_size, params->params[1]); - _gnutls_mpi_print_lz (NULL, &p_size, params->params[0]); + _gnutls_mpi_print_lz (params->params[1], NULL, &g_size); + _gnutls_mpi_print_lz (params->params[0], NULL, &p_size); all_data = gnutls_malloc (g_size + p_size); if (all_data == NULL) @@ -434,8 +351,8 @@ gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params, p_data = &all_data[0]; g_data = &all_data[p_size]; - _gnutls_mpi_print_lz (p_data, &p_size, params->params[0]); - _gnutls_mpi_print_lz (g_data, &g_size, params->params[1]); + _gnutls_mpi_print_lz (params->params[0], p_data, &p_size); + _gnutls_mpi_print_lz (params->params[1], g_data, &g_size); /* Ok. Now we have the data. Create the asn1 structures */ @@ -584,8 +501,7 @@ gnutls_dh_params_export_raw (gnutls_dh_params_t params, gnutls_datum_t * prime, gnutls_datum_t * generator, unsigned int *bits) { - - size_t size; + int ret; if (params->params[1] == NULL || params->params[0] == NULL) { @@ -593,31 +509,20 @@ gnutls_dh_params_export_raw (gnutls_dh_params_t params, return GNUTLS_E_INVALID_REQUEST; } - size = 0; - _gnutls_mpi_print (NULL, &size, params->params[1]); - - generator->data = gnutls_malloc (size); - if (generator->data == NULL) + ret = _gnutls_mpi_dprint (params->params[1], generator); + if (ret < 0) { - return GNUTLS_E_MEMORY_ERROR; + gnutls_assert(); + return ret; } - generator->size = size; - _gnutls_mpi_print (generator->data, &size, params->params[1]); - - - size = 0; - _gnutls_mpi_print (NULL, &size, params->params[0]); - - prime->data = gnutls_malloc (size); - if (prime->data == NULL) + ret = _gnutls_mpi_dprint (params->params[0], prime); + if (ret < 0) { - gnutls_free (generator->data); - generator->data = NULL; - return GNUTLS_E_MEMORY_ERROR; + gnutls_assert(); + _gnutls_free_datum(generator); + return ret; } - prime->size = size; - _gnutls_mpi_print (prime->data, &size, params->params[0]); if (bits) *bits = _gnutls_mpi_get_nbits (params->params[0]); diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c index d54e836d51..d1afe66edd 100644 --- a/lib/gnutls_global.c +++ b/lib/gnutls_global.c @@ -27,6 +27,7 @@ #include <libtasn1.h> #include <gnutls_dh.h> #include <random.h> +#include <gcrypt.h> #ifdef HAVE_WINSOCK # include <winsock2.h> @@ -264,17 +265,6 @@ gnutls_global_init (void) #endif } - if (gc_init () != GC_OK) - { - gnutls_assert (); - _gnutls_debug_log ("Initializing crypto backend failed\n"); - return GNUTLS_E_INCOMPATIBLE_CRYPTO_LIBRARY; - } - - /* for gcrypt in order to be able to allocate memory */ - gc_set_allocators (gnutls_malloc, gnutls_secure_malloc, - _gnutls_is_secure_memory, gnutls_realloc, gnutls_free); - #ifdef DEBUG gnutls_global_set_log_function (dlog); #endif @@ -339,7 +329,6 @@ gnutls_global_deinit (void) asn1_delete_structure (&_gnutls_gnutls_asn); asn1_delete_structure (&_gnutls_pkix1_asn); _gnutls_crypto_deregister(); - gc_done (); } _gnutls_init--; } diff --git a/lib/gnutls_hash_int.c b/lib/gnutls_hash_int.c index 4b986f2b87..22aa7e11b4 100644 --- a/lib/gnutls_hash_int.c +++ b/lib/gnutls_hash_int.c @@ -30,46 +30,36 @@ #include <gnutls_hash_int.h> #include <gnutls_errors.h> -static inline Gc_hash _gnutls_mac2gc (gnutls_mac_algorithm_t mac) +static int digest_length(gnutls_digest_algorithm_t algo) { - switch (mac) - { - case GNUTLS_MAC_NULL: - return -1; - break; - case GNUTLS_MAC_SHA1: - return GC_SHA1; - break; - case GNUTLS_MAC_SHA256: - return GC_SHA256; - break; - case GNUTLS_MAC_SHA384: - return GC_SHA384; - break; - case GNUTLS_MAC_SHA512: - return GC_SHA512; - break; - case GNUTLS_MAC_MD5: - return GC_MD5; - break; - case GNUTLS_MAC_RMD160: - return GC_RMD160; - break; - case GNUTLS_MAC_MD2: - return GC_MD2; - break; - default: - gnutls_assert (); - return -1; + switch (algo) { + case GNUTLS_DIG_NULL: + return 0; + case GNUTLS_DIG_MD5: + case GNUTLS_DIG_MD2: + return 16; + case GNUTLS_DIG_SHA1: + case GNUTLS_DIG_RMD160: + return 20; + case GNUTLS_DIG_SHA256: + return 32; + case GNUTLS_DIG_SHA384: + return 48; + case GNUTLS_DIG_SHA512: + return 64; + case GNUTLS_DIG_SHA224: + return 28; + default: + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; } - return -1; } int -_gnutls_hash_init (digest_hd_st* dig, gnutls_mac_algorithm_t algorithm) +_gnutls_hash_init (digest_hd_st* dig, gnutls_digest_algorithm_t algorithm) { int result; - gnutls_crypto_digest_st * cc = NULL; + gnutls_crypto_single_digest_st * cc = NULL; dig->algorithm = algorithm; @@ -88,25 +78,22 @@ _gnutls_hash_init (digest_hd_st* dig, gnutls_mac_algorithm_t algorithm) dig->registered = 0; - result = gc_hash_open (_gnutls_mac2gc (algorithm), 0, &dig->hd.gc); - if (result) + result = _gnutls_digest_ops.init( algorithm, &dig->hd.gc); + if (result < 0) { gnutls_assert (); - return GNUTLS_E_HASH_FAILED; + return result; } return 0; } +/* returns the output size of the given hash/mac algorithm + */ int -_gnutls_hash_get_algo_len (gnutls_mac_algorithm_t algorithm) +_gnutls_hash_get_algo_len (gnutls_digest_algorithm_t algorithm) { - int ret; - - ret = gc_hash_digest_length (_gnutls_mac2gc (algorithm)); - - return ret; - + return digest_length(algorithm); } int @@ -116,7 +103,7 @@ _gnutls_hash (const digest_hd_st* handle, const void *text, size_t textlen) if (handle->registered) { return handle->hd.rh.cc->hash( handle->hd.rh.ctx, text, textlen); } - gc_hash_write (handle->hd.gc, textlen, text); + return _gnutls_digest_ops.hash (handle->hd.gc, text, textlen); } return 0; } @@ -134,35 +121,59 @@ int _gnutls_hash_copy (digest_hd_st* dst, digest_hd_st* src) return src->hd.rh.cc->copy( &dst->hd.rh.ctx, src->hd.rh.ctx); } - result = gc_hash_clone (src->hd.gc, &dst->hd.gc); - - if (result) + result = _gnutls_digest_ops.copy ( &dst->hd.gc, src->hd.gc); + if (result < 0) { - return GNUTLS_E_HASH_FAILED; + gnutls_assert(); + return result; } return 0; } +/* when the current output is needed without calling deinit + */ void -_gnutls_hash_deinit (digest_hd_st* handle, void *digest) +_gnutls_hash_output (digest_hd_st* handle, void *digest) { - const opaque *mac; int maclen; maclen = _gnutls_hash_get_algo_len (handle->algorithm); - if (handle->registered && handle->hd.rh.ctx != NULL) { - handle->hd.rh.cc->output( handle->hd.rh.ctx, digest, maclen); - handle->hd.rh.cc->deinit( handle->hd.rh.ctx); - return; - } + if (handle->registered && handle->hd.rh.ctx != NULL) + { + if (digest != NULL) + handle->hd.rh.cc->output( handle->hd.rh.ctx, digest, maclen); + return; + } - mac = gc_hash_read (handle->hd.gc); if (digest != NULL) - memcpy (digest, mac, maclen); + { + _gnutls_digest_ops.output( handle->hd.gc, digest, maclen); + } +} + +void +_gnutls_hash_deinit (digest_hd_st* handle, void *digest) +{ + _gnutls_hash_output( handle, digest); + + if (handle->registered && handle->hd.rh.ctx != NULL) + { + handle->hd.rh.cc->deinit( handle->hd.rh.ctx); + return; + } + + _gnutls_digest_ops.deinit( handle->hd.gc); +} + - gc_hash_close (handle->hd.gc); +/* HMAC interface */ + +int +_gnutls_hmac_get_algo_len (gnutls_mac_algorithm_t algorithm) +{ + return digest_length(algorithm); } @@ -170,7 +181,7 @@ int _gnutls_hmac_init (digest_hd_st *dig, gnutls_mac_algorithm_t algorithm, const void *key, int keylen) { int result; - gnutls_crypto_digest_st * cc = NULL; + gnutls_crypto_single_mac_st * cc = NULL; dig->algorithm = algorithm; dig->key = key; @@ -199,38 +210,62 @@ int _gnutls_hmac_init (digest_hd_st *dig, gnutls_mac_algorithm_t algorithm, dig->registered = 0; - result = gc_hash_open (_gnutls_mac2gc (algorithm), GC_HMAC, &dig->hd.gc); - if (result) - { - return GNUTLS_E_HASH_FAILED; + result = _gnutls_mac_ops.init (algorithm, &dig->hd.gc); + if (result < 0) + { + gnutls_assert(); + return result; } - gc_hash_hmac_setkey (dig->hd.gc, keylen, key); + _gnutls_mac_ops.setkey (dig->hd.gc, key, keylen); + + return 0; +} +int +_gnutls_hmac (const digest_hd_st* handle, const void *text, size_t textlen) +{ + if (textlen > 0) { + if (handle->registered) { + return handle->hd.rh.cc->hash( handle->hd.rh.ctx, text, textlen); + } + return _gnutls_mac_ops.hash (handle->hd.gc, text, textlen); + } return 0; } void -_gnutls_hmac_deinit (digest_hd_st* handle, void *digest) +_gnutls_hmac_output (digest_hd_st* handle, void *digest) { - const opaque *mac; int maclen; - maclen = _gnutls_hash_get_algo_len (handle->algorithm); + maclen = _gnutls_hmac_get_algo_len (handle->algorithm); - if (handle->registered && handle->hd.rh.ctx != NULL) { - handle->hd.rh.cc->output( handle->hd.rh.ctx, digest, maclen); - handle->hd.rh.cc->deinit( handle->hd.rh.ctx); - return; - } - - mac = gc_hash_read (handle->hd.gc); + if (handle->registered && handle->hd.rh.ctx != NULL) + { + if (digest != NULL) + handle->hd.rh.cc->output( handle->hd.rh.ctx, digest, maclen); + return; + } if (digest != NULL) - memcpy (digest, mac, maclen); + { + _gnutls_mac_ops.output( handle->hd.gc, digest, maclen); + } +} - gc_hash_close (handle->hd.gc); +void +_gnutls_hmac_deinit (digest_hd_st* handle, void *digest) +{ + _gnutls_hmac_output( handle, digest); + if (handle->registered && handle->hd.rh.ctx != NULL) + { + handle->hd.rh.cc->deinit( handle->hd.rh.ctx); + return; + } + + _gnutls_mac_ops.deinit( handle->hd.gc); } inline static int @@ -247,6 +282,10 @@ get_padsize (gnutls_mac_algorithm_t algorithm) } } + +/* Special functions for SSL3 MAC + */ + int _gnutls_mac_init_ssl3 (digest_hd_st* ret, gnutls_mac_algorithm_t algorithm, void *key, int keylen) { diff --git a/lib/gnutls_hash_int.h b/lib/gnutls_hash_int.h index 71e4c7e126..f4c4fbc761 100644 --- a/lib/gnutls_hash_int.h +++ b/lib/gnutls_hash_int.h @@ -31,8 +31,14 @@ /* for message digests */ +extern int crypto_mac_prio; +extern gnutls_crypto_mac_st _gnutls_mac_ops; + +extern int crypto_digest_prio; +extern gnutls_crypto_digest_st _gnutls_digest_ops; + typedef struct { - gnutls_crypto_mac_st* cc; + gnutls_crypto_single_mac_st* cc; void* ctx; } digest_reg_hd; @@ -40,7 +46,7 @@ typedef struct { int registered; /* true or false(0) */ union { - gc_hash_handle gc; /* when not registered */ + void* gc; /* when not registered */ digest_reg_hd rh; /* when registered */ } hd; gnutls_mac_algorithm_t algorithm; @@ -50,19 +56,23 @@ typedef struct int _gnutls_hmac_init (digest_hd_st*, gnutls_mac_algorithm_t algorithm, const void *key, int keylen); -#define _gnutls_hmac_get_algo_len _gnutls_hash_get_algo_len -#define _gnutls_hmac _gnutls_hash +int _gnutls_hmac_get_algo_len (gnutls_mac_algorithm_t algorithm); +int _gnutls_hmac (const digest_hd_st* handle, const void *text, + size_t textlen); + void _gnutls_hmac_deinit (digest_hd_st* handle, void *digest); +void _gnutls_hmac_output (digest_hd_st* handle, void *digest); int _gnutls_mac_init_ssl3 (digest_hd_st*, gnutls_mac_algorithm_t algorithm, void *key, int keylen); void _gnutls_mac_deinit_ssl3 (digest_hd_st* handle, void *digest); -int _gnutls_hash_init (digest_hd_st*, gnutls_mac_algorithm_t algorithm); -int _gnutls_hash_get_algo_len (gnutls_mac_algorithm_t algorithm); +int _gnutls_hash_init (digest_hd_st*, gnutls_digest_algorithm_t algorithm); +int _gnutls_hash_get_algo_len (gnutls_digest_algorithm_t algorithm); int _gnutls_hash (const digest_hd_st* handle, const void *text, size_t textlen); void _gnutls_hash_deinit (digest_hd_st* handle, void *digest); +void _gnutls_hash_output (digest_hd_st* handle, void *digest); int _gnutls_ssl3_generate_random (void *secret, int secret_len, void *rnd, int random_len, int bytes, diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 8c3ff46ac1..eb392e77de 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -189,21 +189,21 @@ struct gnutls_key_st { /* For DH KX */ gnutls_datum_t key; - mpi_t KEY; - mpi_t client_Y; - mpi_t client_g; - mpi_t client_p; - mpi_t dh_secret; + bigint_t KEY; + bigint_t client_Y; + bigint_t client_g; + bigint_t client_p; + bigint_t dh_secret; /* for SRP */ - mpi_t A; - mpi_t B; - mpi_t u; - mpi_t b; - mpi_t a; - mpi_t x; + bigint_t A; + bigint_t B; + bigint_t u; + bigint_t b; + bigint_t a; + bigint_t x; /* RSA: e, m */ - mpi_t rsa[2]; + bigint_t rsa[2]; /* this is used to hold the peers authentication data */ @@ -409,7 +409,7 @@ typedef struct gnutls_dh_params_int { /* [0] is the prime, [1] is the generator. */ - mpi_t params[2]; + bigint_t params[2]; } dh_params_st; typedef struct diff --git a/lib/gnutls_mpi.c b/lib/gnutls_mpi.c index eec2c1be78..ef1248af67 100644 --- a/lib/gnutls_mpi.c +++ b/lib/gnutls_mpi.c @@ -30,43 +30,102 @@ #include <libtasn1.h> #include <gnutls_errors.h> #include <gnutls_num.h> +#include <gnutls_mpi.h> +#include <random.h> -/* Functions that refer to the libgcrypt library. +/* Functions that refer to the mpi library. */ +#define clearbit(v,n) ((unsigned char)(v) & ~( (unsigned char)(1) << (unsigned)(n))) + +/* FIXME: test this function */ +bigint_t _gnutls_mpi_randomize( bigint_t r, unsigned int bits, gnutls_rnd_level_t level) +{ +opaque * buf = NULL; +int size = 1+(bits/8), ret; +int rem, i; +bigint_t tmp; + + buf = gnutls_malloc( size); + if (buf == NULL) + { + gnutls_assert(); + return NULL; + } + + ret = _gnutls_rnd( level, buf, size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + /* mask the bits that weren't requested */ + rem = bits % 8; + + if (rem == 0) { + buf[0]=0; + } else { + for (i=8;i>=rem;i--) + buf[0]=clearbit(buf[0], i); + } + + ret = _gnutls_mpi_scan ( &tmp, buf, size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + + if (r != NULL) + { + _gnutls_mpi_set(r, tmp); + _gnutls_mpi_release( &tmp); + return r; + } + + return tmp; + +cleanup: + gnutls_free(buf); + return NULL; +} + void -_gnutls_mpi_release (mpi_t * x) +_gnutls_mpi_release (bigint_t * x) { if (*x == NULL) return; - gcry_mpi_release (*x); + + _gnutls_mpi_ops.bigint_release (*x); *x = NULL; } /* returns zero on success */ int -_gnutls_mpi_scan (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes) +_gnutls_mpi_scan (bigint_t * ret_mpi, const void * buffer, size_t nbytes) { - int ret; - - ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, buffer, *nbytes, nbytes); - if (ret) - return GNUTLS_E_MPI_SCAN_FAILED; - + *ret_mpi = _gnutls_mpi_ops.bigint_scan (buffer, nbytes, GNUTLS_MPI_FORMAT_USG); + if (*ret_mpi == NULL) + { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + return 0; } /* returns zero on success. Fails if the number is zero. */ int -_gnutls_mpi_scan_nz (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes) +_gnutls_mpi_scan_nz (bigint_t *ret_mpi, const void * buffer, size_t nbytes) { - int ret; +int ret; - ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, buffer, *nbytes, nbytes); - if (ret) - return GNUTLS_E_MPI_SCAN_FAILED; + ret = _gnutls_mpi_scan(ret_mpi, buffer, nbytes); + if (ret < 0) + return ret; /* MPIs with 0 bits are illegal */ @@ -80,58 +139,50 @@ _gnutls_mpi_scan_nz (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes) } int -_gnutls_mpi_scan_pgp (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes) +_gnutls_mpi_scan_pgp (bigint_t *ret_mpi, const void * buffer, size_t nbytes) { - int ret; - ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_PGP, buffer, *nbytes, nbytes); - if (ret) - return GNUTLS_E_MPI_SCAN_FAILED; - - /* MPIs with 0 bits are illegal - */ - if (_gnutls_mpi_get_nbits (*ret_mpi) == 0) + *ret_mpi = _gnutls_mpi_ops.bigint_scan (buffer, nbytes, GNUTLS_MPI_FORMAT_PGP); + if (*ret_mpi == NULL) { - _gnutls_mpi_release (ret_mpi); + gnutls_assert(); return GNUTLS_E_MPI_SCAN_FAILED; } - + return 0; } +/* Always has the first bit zero */ int -_gnutls_mpi_print (void *buffer, size_t * nbytes, const mpi_t a) +_gnutls_mpi_dprint_lz (const bigint_t a, gnutls_datum_t * dest) { int ret; + opaque *buf = NULL; + size_t bytes = 0; - if (nbytes == NULL || a == NULL) + if (dest == NULL || a == NULL) return GNUTLS_E_INVALID_REQUEST; - ret = gcry_mpi_print (GCRYMPI_FMT_USG, buffer, *nbytes, nbytes, a); - if (!ret) - return 0; - - return GNUTLS_E_MPI_PRINT_FAILED; -} + _gnutls_mpi_print_lz (a, NULL, &bytes); -/* Always has the first bit zero */ -int -_gnutls_mpi_print_lz (void *buffer, size_t * nbytes, const mpi_t a) -{ - int ret; - - if (nbytes == NULL || a == NULL) - return GNUTLS_E_INVALID_REQUEST; + if (bytes != 0) + buf = gnutls_malloc (bytes); + if (buf == NULL) + return GNUTLS_E_MEMORY_ERROR; - ret = gcry_mpi_print (GCRYMPI_FMT_STD, buffer, *nbytes, nbytes, a); - if (!ret) - return 0; + ret = _gnutls_mpi_print_lz (a, buf, &bytes); + if (ret < 0) + { + gnutls_free (buf); + return ret; + } - return GNUTLS_E_MPI_PRINT_FAILED; + dest->data = buf; + dest->size = bytes; + return 0; } -/* Always has the first bit zero */ int -_gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a) +_gnutls_mpi_dprint (const bigint_t a, gnutls_datum_t * dest) { int ret; opaque *buf = NULL; @@ -140,64 +191,75 @@ _gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a) if (dest == NULL || a == NULL) return GNUTLS_E_INVALID_REQUEST; - gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &bytes, a); - + _gnutls_mpi_print (a, NULL, &bytes); if (bytes != 0) buf = gnutls_malloc (bytes); if (buf == NULL) return GNUTLS_E_MEMORY_ERROR; - ret = gcry_mpi_print (GCRYMPI_FMT_STD, buf, bytes, &bytes, a); - if (!ret) + ret = _gnutls_mpi_print (a, buf, &bytes); + if (ret < 0) { - dest->data = buf; - dest->size = bytes; - return 0; + gnutls_free (buf); + return ret; } - gnutls_free (buf); - return GNUTLS_E_MPI_PRINT_FAILED; + dest->data = buf; + dest->size = bytes; + return 0; } +/* This function will copy the mpi data into a datum, + * but will set minimum size to 'size'. That means that + * the output value is left padded with zeros. + */ int -_gnutls_mpi_dprint (gnutls_datum_t * dest, const mpi_t a) +_gnutls_mpi_dprint_size (const bigint_t a, gnutls_datum_t * dest, size_t size) { int ret; opaque *buf = NULL; size_t bytes = 0; + unsigned int i; if (dest == NULL || a == NULL) return GNUTLS_E_INVALID_REQUEST; - gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &bytes, a); - + _gnutls_mpi_print (a, NULL, &bytes); if (bytes != 0) - buf = gnutls_malloc (bytes); + buf = gnutls_malloc (MAX(size, bytes)); if (buf == NULL) return GNUTLS_E_MEMORY_ERROR; - ret = gcry_mpi_print (GCRYMPI_FMT_USG, buf, bytes, &bytes, a); - if (!ret) + dest->size = MAX(size, bytes); + + if (bytes <= size) { + size_t diff = size - bytes; + for (i=0;i<diff;i++) + buf[i] = 0; + ret = _gnutls_mpi_print(a, &buf[diff], &bytes); + } else { + ret = _gnutls_mpi_print(a, buf, &bytes); + } + + if (ret < 0) { - dest->data = buf; - dest->size = bytes; - return 0; + gnutls_free (buf); + return ret; } - gnutls_free (buf); - return GNUTLS_E_MPI_PRINT_FAILED; + dest->data = buf; + dest->size = MAX(size, bytes); + return 0; } - /* this function reads an integer * from asn1 structs. Combines the read and mpi_scan * steps. */ int -_gnutls_x509_read_int (ASN1_TYPE node, const char *value, mpi_t * ret_mpi) +_gnutls_x509_read_int (ASN1_TYPE node, const char *value, bigint_t * ret_mpi) { int result; - size_t s_len; opaque *tmpstr = NULL; int tmpstr_size; @@ -224,23 +286,22 @@ _gnutls_x509_read_int (ASN1_TYPE node, const char *value, mpi_t * ret_mpi) return _gnutls_asn2err (result); } - s_len = tmpstr_size; - if (_gnutls_mpi_scan (ret_mpi, tmpstr, &s_len) != 0) + result = _gnutls_mpi_scan (ret_mpi, tmpstr, tmpstr_size); + gnutls_free (tmpstr); + + if (result < 0) { gnutls_assert (); - gnutls_free (tmpstr); - return GNUTLS_E_MPI_SCAN_FAILED; + return result; } - gnutls_free (tmpstr); - return 0; } /* Writes the specified integer into the specified node. */ int -_gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi, int lz) +_gnutls_x509_write_int (ASN1_TYPE node, const char *value, bigint_t mpi, int lz) { opaque *tmpstr; size_t s_len; @@ -248,9 +309,9 @@ _gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi, int lz) s_len = 0; if (lz) - result = _gnutls_mpi_print_lz (NULL, &s_len, mpi); + result = _gnutls_mpi_print_lz (mpi, NULL, &s_len); else - result = _gnutls_mpi_print (NULL, &s_len, mpi); + result = _gnutls_mpi_print (mpi, NULL, &s_len); tmpstr = gnutls_malloc (s_len); if (tmpstr == NULL) @@ -260,9 +321,9 @@ _gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi, int lz) } if (lz) - result = _gnutls_mpi_print_lz (tmpstr, &s_len, mpi); + result = _gnutls_mpi_print_lz (mpi, tmpstr, &s_len); else - result = _gnutls_mpi_print (tmpstr, &s_len, mpi); + result = _gnutls_mpi_print (mpi, tmpstr, &s_len); if (result != 0) { diff --git a/lib/gnutls_mpi.h b/lib/gnutls_mpi.h index d0b7d3c975..16726b9c94 100644 --- a/lib/gnutls_mpi.h +++ b/lib/gnutls_mpi.h @@ -26,52 +26,50 @@ # define GNUTLS_MPI_H # include <gnutls_int.h> -# include <gcrypt.h> -# include <gc.h> # include <libtasn1.h> -typedef gcry_mpi_t mpi_t; +# include <gnutls/crypto.h> -#define _gnutls_mpi_cmp gcry_mpi_cmp -#define _gnutls_mpi_cmp_ui gcry_mpi_cmp_ui -#define _gnutls_mpi_mod gcry_mpi_mod -#define _gnutls_mpi_new gcry_mpi_new -#define _gnutls_mpi_snew gcry_mpi_snew -#define _gnutls_mpi_copy gcry_mpi_copy -#define _gnutls_mpi_set_ui gcry_mpi_set_ui -#define _gnutls_mpi_set gcry_mpi_set -#define _gnutls_mpi_randomize gcry_mpi_randomize -#define _gnutls_mpi_get_nbits gcry_mpi_get_nbits -#define _gnutls_mpi_powm gcry_mpi_powm -#define _gnutls_mpi_invm gcry_mpi_invm -#define _gnutls_mpi_addm gcry_mpi_addm -#define _gnutls_mpi_subm gcry_mpi_subm -#define _gnutls_mpi_sub_ui gcry_mpi_sub_ui -#define _gnutls_mpi_mulm gcry_mpi_mulm -#define _gnutls_mpi_mul gcry_mpi_mul -#define _gnutls_mpi_add gcry_mpi_add -#define _gnutls_mpi_add_ui gcry_mpi_add_ui -#define _gnutls_mpi_sub_ui gcry_mpi_sub_ui -#define _gnutls_mpi_mul_ui gcry_mpi_mul_ui -#define _gnutls_prime_check gcry_prime_check -#define _gnutls_mpi_div gcry_mpi_div +extern int crypto_bigint_prio; +extern gnutls_crypto_bigint_st _gnutls_mpi_ops; -# define _gnutls_mpi_alloc_like(x) _gnutls_mpi_new(_gnutls_mpi_get_nbits(x)) -# define _gnutls_mpi_salloc_like(x) _gnutls_mpi_snew(_gnutls_mpi_get_nbits(x)) +bigint_t _gnutls_mpi_randomize( bigint_t, unsigned int bits, gnutls_rnd_level_t level); -void _gnutls_mpi_release (mpi_t * x); +#define _gnutls_mpi_new(x) _gnutls_mpi_ops.bigint_new(x) +#define _gnutls_mpi_cmp(x,y) _gnutls_mpi_ops.bigint_cmp(x,y) +#define _gnutls_mpi_cmp_ui(x,y) _gnutls_mpi_ops.bigint_cmp_ui(x,y) +#define _gnutls_mpi_mod(x,y) _gnutls_mpi_ops.bigint_mod(x,y) +#define _gnutls_mpi_set(x,y) _gnutls_mpi_ops.bigint_set(x,y) +#define _gnutls_mpi_set_ui(x,y) _gnutls_mpi_ops.bigint_set_ui(x,y) +#define _gnutls_mpi_get_nbits(x) _gnutls_mpi_ops.bigint_get_nbits(x) +#define _gnutls_mpi_alloc_like(x) _gnutls_mpi_new(_gnutls_mpi_get_nbits(x)) +#define _gnutls_mpi_powm(x,y,z,w) _gnutls_mpi_ops.bigint_powm(x,y,z,w) +#define _gnutls_mpi_addm(x,y,z,w) _gnutls_mpi_ops.bigint_addm(x,y,z,w) +#define _gnutls_mpi_subm(x,y,z,w) _gnutls_mpi_ops.bigint_subm(x,y,z,w) +#define _gnutls_mpi_mulm(x,y,z,w) _gnutls_mpi_ops.bigint_mulm(x,y,z,w) +#define _gnutls_mpi_add(x,y,z) _gnutls_mpi_ops.bigint_add(x,y,z) +#define _gnutls_mpi_sub(x,y,z) _gnutls_mpi_ops.bigint_sub(x,y,z) +#define _gnutls_mpi_mul(x,y,z) _gnutls_mpi_ops.bigint_mul(x,y,z) +#define _gnutls_mpi_div(x,y,z) _gnutls_mpi_ops.bigint_div(x,y,z) +#define _gnutls_mpi_add_ui(x,y,z) _gnutls_mpi_ops.bigint_add_ui(x,y,z) +#define _gnutls_mpi_sub_ui(x,y,z) _gnutls_mpi_ops.bigint_sub_ui(x,y,z) +#define _gnutls_mpi_mul_ui(x,y,z) _gnutls_mpi_ops.bigint_mul_ui(x,y,z) +#define _gnutls_prime_check(z) _gnutls_mpi_ops.bigint_prime_check(z) +#define _gnutls_mpi_print(x,y,z) _gnutls_mpi_ops.bigint_print(x,y,z,GNUTLS_MPI_FORMAT_USG) +#define _gnutls_mpi_print_lz(x,y,z) _gnutls_mpi_ops.bigint_print(x,y,z,GNUTLS_MPI_FORMAT_STD) +#define _gnutls_mpi_print_pgp(x,y,z) _gnutls_mpi_ops.bigint_print(x,y,z,GNUTLS_MPI_FORMAT_PGP) +#define _gnutls_mpi_copy( a) _gnutls_mpi_set( NULL, a) -int _gnutls_mpi_scan_nz (mpi_t * ret_mpi, const opaque * buffer, - size_t * nbytes); -int _gnutls_mpi_scan (mpi_t * ret_mpi, const opaque * buffer, - size_t * nbytes); -int _gnutls_mpi_scan_pgp (mpi_t * ret_mpi, const opaque * buffer, - size_t * nbytes); +void _gnutls_mpi_release (bigint_t * x); -int _gnutls_mpi_print (void *buffer, size_t * nbytes, const mpi_t a); -int _gnutls_mpi_print_lz (void *buffer, size_t * nbytes, const mpi_t a); +int _gnutls_mpi_scan (bigint_t * ret_mpi, const void * buffer, size_t nbytes); +int _gnutls_mpi_scan_nz (bigint_t * ret_mpi, const void * buffer, size_t nbytes); +int _gnutls_mpi_scan_pgp (bigint_t * ret_mpi, const void * buffer, size_t nbytes); -int _gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a); -int _gnutls_mpi_dprint (gnutls_datum_t * dest, const mpi_t a); +int _gnutls_mpi_dprint_lz ( const bigint_t a, gnutls_datum_t * dest); +int _gnutls_mpi_dprint ( const bigint_t a, gnutls_datum_t * dest); +int _gnutls_mpi_dprint_size (const bigint_t a, gnutls_datum_t * dest, size_t size); + +#define _gnutls_mpi_generate_group( gg, bits) _gnutls_mpi_ops.bigint_generate_group( gg, bits) #endif diff --git a/lib/gnutls_openpgp.c b/lib/gnutls_openpgp.c index de64fddcb6..1a57dc2e67 100644 --- a/lib/gnutls_openpgp.c +++ b/lib/gnutls_openpgp.c @@ -34,7 +34,6 @@ #include <gnutls_str.h> #include <gnutls_sig.h> #include <stdio.h> -#include <gcrypt.h> #include <time.h> #include <sys/stat.h> @@ -262,7 +261,7 @@ gnutls_openpgp_get_key (gnutls_datum_t * key, rc = cdk_kbnode_write_to_mem_alloc (knode, &buf, &len); if (!rc) datum_append (key, buf, len); - cdk_free (buf); + gnutls_free (buf); leave: cdk_kbnode_release (knode); @@ -893,7 +892,7 @@ gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key, gnutls_datum_t * signature) { int result, i; - mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; int params_size = MAX_PUBLIC_PARAMS_SIZE; int pk_algorithm; gnutls_openpgp_keyid_t keyid; diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c index 5e31804419..8794207382 100644 --- a/lib/gnutls_pk.c +++ b/lib/gnutls_pk.c @@ -38,31 +38,25 @@ #include <x509/common.h> #include <random.h> -static int _gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data, - mpi_t * pkey, int pkey_len); -static int _gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash, - mpi_t * pkey, int); -static int _gnutls_pk_verify (int algo, mpi_t hash, mpi_t * data, - mpi_t * pkey, int); -static int _gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data, - mpi_t * pkey, int); - - /* Do PKCS-1 RSA encryption. * params is modulus, public exp. */ int _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, const gnutls_datum_t * plaintext, - mpi_t * params, unsigned params_len, + bigint_t * params, unsigned params_len, unsigned btype) { unsigned int i, pad; int ret; - mpi_t m, res; opaque *edata, *ps; size_t k, psize; size_t mod_bits; + gnutls_pk_params_st pk_params; + gnutls_datum to_encrypt, encrypted; + + pk_params.params = params; + pk_params.params_nr = params_len; mod_bits = _gnutls_mpi_get_nbits (params[0]); k = mod_bits / 8; @@ -143,20 +137,15 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, ps[psize] = 0; memcpy (&ps[psize + 1], plaintext->data, plaintext->size); - if (_gnutls_mpi_scan_nz (&m, edata, &k) != 0) - { - gnutls_assert (); - gnutls_free (edata); - return GNUTLS_E_MPI_SCAN_FAILED; - } - gnutls_free (edata); + to_encrypt.data = edata; + to_encrypt.size = k; if (btype == 2) /* encrypt */ - ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, m, params, params_len); + ret = _gnutls_pk_encrypt (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params); else /* sign */ - ret = _gnutls_pk_sign (GCRY_PK_RSA, &res, m, params, params_len); + ret = _gnutls_pk_sign (GNUTLS_PK_RSA, &encrypted, &to_encrypt, &pk_params); - _gnutls_mpi_release (&m); + gnutls_free (edata); if (ret < 0) { @@ -164,8 +153,7 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, return ret; } - _gnutls_mpi_print (NULL, &psize, res); - + psize = encrypted.size; if (psize < k) { /* padding psize */ @@ -174,13 +162,18 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, } else if (psize == k) { - pad = 0; + /* pad = 0; + * no need to do anything else + */ + ciphertext->data = encrypted.data; + ciphertext->size = encrypted.size; + return 0; } else { /* psize > k !!! */ /* This is an impossible situation */ gnutls_assert (); - _gnutls_mpi_release (&res); + _gnutls_free_datum (&encrypted); return GNUTLS_E_INTERNAL_ERROR; } @@ -188,16 +181,17 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, if (ciphertext->data == NULL) { gnutls_assert (); - _gnutls_mpi_release (&res); + _gnutls_free_datum (&encrypted); return GNUTLS_E_MEMORY_ERROR; } - _gnutls_mpi_print (&ciphertext->data[pad], &psize, res); + + memcpy( &ciphertext->data[pad], encrypted.data, encrypted.size); for (i = 0; i < pad; i++) ciphertext->data[i] = 0; ciphertext->size = k; - _gnutls_mpi_release (&res); + _gnutls_free_datum (&encrypted); return 0; } @@ -210,14 +204,16 @@ _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, int _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, const gnutls_datum_t * ciphertext, - mpi_t * params, unsigned params_len, + bigint_t * params, unsigned params_len, unsigned btype) { unsigned k, i; int ret; - mpi_t c, res; - opaque *edata; size_t esize, mod_bits; + gnutls_pk_params_st pk_params; + + pk_params.params = params; + pk_params.params_nr = params_len; mod_bits = _gnutls_mpi_get_nbits (params[0]); k = mod_bits / 8; @@ -232,22 +228,17 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, return GNUTLS_E_PK_DECRYPTION_FAILED; } - if (_gnutls_mpi_scan_nz (&c, ciphertext->data, &esize) != 0) - { - gnutls_assert (); - return GNUTLS_E_MPI_SCAN_FAILED; - } - /* we can use btype to see if the private key is * available. */ if (btype == 2) - ret = _gnutls_pk_decrypt (GCRY_PK_RSA, &res, c, params, params_len); + { + ret = _gnutls_pk_decrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params); + } else { - ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, c, params, params_len); + ret = _gnutls_pk_encrypt (GNUTLS_PK_RSA, plaintext, ciphertext, &pk_params); } - _gnutls_mpi_release (&c); if (ret < 0) { @@ -255,18 +246,6 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, return ret; } - _gnutls_mpi_print (NULL, &esize, res); - edata = gnutls_malloc (esize + 1); - if (edata == NULL) - { - gnutls_assert (); - _gnutls_mpi_release (&res); - return GNUTLS_E_MEMORY_ERROR; - } - _gnutls_mpi_print (&edata[1], &esize, res); - - _gnutls_mpi_release (&res); - /* EB = 00||BT||PS||00||D * (use block type 'btype') * @@ -275,15 +254,9 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, * "Chosen Ciphertext Attacks against Protocols Based on RSA * Encryption Standard PKCS #1". */ - - - edata[0] = 0; - esize++; - - if (edata[0] != 0 || edata[1] != btype) + if (plaintext->data[0] != 0 || plaintext->data[1] != btype) { gnutls_assert (); - gnutls_free (edata); return GNUTLS_E_DECRYPTION_FAILED; } @@ -291,9 +264,9 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, switch (btype) { case 2: - for (i = 2; i < esize; i++) + for (i = 2; i < plaintext->size; i++) { - if (edata[i] == 0) + if (plaintext->data[i] == 0) { ret = 0; break; @@ -301,16 +274,17 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, } break; case 1: - for (i = 2; i < esize; i++) + for (i = 2; i < plaintext->size; i++) { - if (edata[i] == 0 && i > 2) + if (plaintext->data[i] == 0 && i > 2) { ret = 0; break; } - if (edata[i] != 0xff) + if (plaintext->data[i] != 0xff) { _gnutls_handshake_log ("PKCS #1 padding error"); + _gnutls_free_datum( plaintext); /* PKCS #1 padding error. Don't use GNUTLS_E_PKCS1_WRONG_PAD here. */ break; @@ -319,7 +293,7 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, break; default: gnutls_assert (); - gnutls_free (edata); + _gnutls_free_datum( plaintext); break; } i++; @@ -327,18 +301,12 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, if (ret < 0) { gnutls_assert (); - gnutls_free (edata); + _gnutls_free_datum( plaintext); return GNUTLS_E_DECRYPTION_FAILED; } - - if (_gnutls_sset_datum (plaintext, &edata[i], esize - i) < 0) - { - gnutls_assert (); - gnutls_free (edata); - return GNUTLS_E_MEMORY_ERROR; - } - - gnutls_free (edata); + + memmove(plaintext->data, &plaintext->data[i], esize - i); + plaintext->size = esize - i; return 0; } @@ -346,7 +314,7 @@ _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, int _gnutls_rsa_verify (const gnutls_datum_t * vdata, - const gnutls_datum_t * ciphertext, mpi_t * params, + const gnutls_datum_t * ciphertext, bigint_t * params, int params_len, int btype) { @@ -383,8 +351,8 @@ _gnutls_rsa_verify (const gnutls_datum_t * vdata, /* encodes the Dss-Sig-Value structure */ -static int -encode_ber_rs (gnutls_datum_t * sig_value, mpi_t r, mpi_t s) +int +_gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s) { ASN1_TYPE sig; int result, tot_len; @@ -434,12 +402,15 @@ encode_ber_rs (gnutls_datum_t * sig_value, mpi_t r, mpi_t s) */ int _gnutls_dsa_sign (gnutls_datum_t * signature, - const gnutls_datum_t * hash, mpi_t * params, + const gnutls_datum_t * hash, bigint_t * params, unsigned params_len) { - mpi_t rs[2], mdata; int ret; size_t k; + gnutls_pk_params_st pk_params; + + pk_params.params = params; + pk_params.params_nr = params_len; k = hash->size; if (k < 20) @@ -448,15 +419,8 @@ _gnutls_dsa_sign (gnutls_datum_t * signature, return GNUTLS_E_PK_SIGN_FAILED; } - if (_gnutls_mpi_scan_nz (&mdata, hash->data, &k) != 0) - { - gnutls_assert (); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - ret = _gnutls_pk_sign (GCRY_PK_DSA, rs, mdata, params, params_len); + ret = _gnutls_pk_sign (GNUTLS_PK_DSA, signature, hash, &pk_params); /* rs[0], rs[1] now hold r,s */ - _gnutls_mpi_release (&mdata); if (ret < 0) { @@ -464,25 +428,13 @@ _gnutls_dsa_sign (gnutls_datum_t * signature, return ret; } - ret = encode_ber_rs (signature, rs[0], rs[1]); - - /* free r,s */ - _gnutls_mpi_release (&rs[0]); - _gnutls_mpi_release (&rs[1]); - - if (ret != 0) - { - gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - return 0; } /* decodes the Dss-Sig-Value structure */ -static int -decode_ber_rs (const gnutls_datum_t * sig_value, mpi_t * r, mpi_t * s) +int +_gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r, bigint_t * s) { ASN1_TYPE sig; int result; @@ -530,14 +482,15 @@ decode_ber_rs (const gnutls_datum_t * sig_value, mpi_t * r, mpi_t * s) */ int _gnutls_dsa_verify (const gnutls_datum_t * vdata, - const gnutls_datum_t * sig_value, mpi_t * params, + const gnutls_datum_t * sig_value, bigint_t * params, int params_len) { - mpi_t mdata; int ret; - size_t k; - mpi_t rs[2]; + gnutls_pk_params_st pk_params; + + pk_params.params = params; + pk_params.params_nr = params_len; if (vdata->size != 20) { /* sha-1 only */ @@ -545,26 +498,8 @@ _gnutls_dsa_verify (const gnutls_datum_t * vdata, return GNUTLS_E_PK_SIG_VERIFY_FAILED; } - if (decode_ber_rs (sig_value, &rs[0], &rs[1]) != 0) - { - gnutls_assert (); - return GNUTLS_E_MPI_SCAN_FAILED; - } - - k = vdata->size; - if (_gnutls_mpi_scan_nz (&mdata, vdata->data, &k) != 0) - { - gnutls_assert (); - _gnutls_mpi_release (&rs[0]); - _gnutls_mpi_release (&rs[1]); - return GNUTLS_E_MPI_SCAN_FAILED; - } - /* decrypt signature */ - ret = _gnutls_pk_verify (GCRY_PK_DSA, mdata, rs, params, params_len); - _gnutls_mpi_release (&mdata); - _gnutls_mpi_release (&rs[0]); - _gnutls_mpi_release (&rs[1]); + ret = _gnutls_pk_verify (GNUTLS_PK_DSA, vdata, sig_value, &pk_params); if (ret < 0) { @@ -575,341 +510,79 @@ _gnutls_dsa_verify (const gnutls_datum_t * vdata, return 0; /* ok */ } - -/* this is taken from gnupg - */ - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -static int -_gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data, - mpi_t * pkey, int pkey_len) +/* some generic pk functions */ +static +int _generate_params(int algo, bigint_t * resarr, unsigned int *resarr_len, int bits) { - gcry_sexp_t s_ciph, s_data, s_pkey; - int rc = -1; - - /* make a sexp from pkey */ - switch (algo) - { - case GCRY_PK_RSA: - if (pkey_len >= 2) - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(rsa(n%m)(e%m)))", - pkey[0], pkey[1]); - break; - - default: - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - if (rc != 0) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - /* put the data into a simple list */ - if (gcry_sexp_build (&s_data, NULL, "%m", data)) - { - gnutls_assert (); - gcry_sexp_release (s_pkey); - return GNUTLS_E_INTERNAL_ERROR; - } - - /* pass it to libgcrypt */ - rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - - if (rc != 0) - { - gnutls_assert (); - return GNUTLS_E_PK_ENCRYPTION_FAILED; - - } - else - { /* add better error handling or make gnupg use S-Exp directly */ - gcry_sexp_t list = gcry_sexp_find_token (s_ciph, "a", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (s_ciph); - return GNUTLS_E_INTERNAL_ERROR; +gnutls_pk_params_st params; +int ret; +unsigned int i; + + ret = _gnutls_pk_ops.generate( GNUTLS_PK_RSA, bits, ¶ms); + + if (ret < 0) { + gnutls_assert(); + return ret; } - resarr[0] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); - - if (resarr[0] == NULL) - { - gnutls_assert (); - gcry_sexp_release (s_ciph); - return GNUTLS_E_INTERNAL_ERROR; + if (resarr && resarr_len && *resarr_len > params.params_nr) { + *resarr_len = params.params_nr; + for (i=0;i<params.params_nr;i++) + resarr[i] = params.params[i]; + } else { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; } - } - - gcry_sexp_release (s_ciph); - return rc; + return 0; } -static int -_gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey, - int pkey_len) -{ - gcry_sexp_t s_plain, s_data, s_pkey; - int rc = -1; - - /* make a sexp from pkey */ - switch (algo) - { - case GCRY_PK_RSA: - if (pkey_len >= 6) - rc = gcry_sexp_build (&s_pkey, NULL, - "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))", - pkey[0], pkey[1], pkey[2], pkey[3], - pkey[4], pkey[5]); - break; - - default: - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - if (rc != 0) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - /* put the data into a simple list */ - if (gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data)) - { - gnutls_assert (); - gcry_sexp_release (s_pkey); - return GNUTLS_E_INTERNAL_ERROR; - } - - /* pass it to libgcrypt */ - rc = gcry_pk_decrypt (&s_plain, s_data, s_pkey); - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - - if (rc != 0) - { - gnutls_assert (); - return GNUTLS_E_PK_DECRYPTION_FAILED; - - } - else - { /* add better error handling or make gnupg use S-Exp directly */ - resarr[0] = gcry_sexp_nth_mpi (s_plain, 0, 0); - - if (resarr[0] == NULL) - { - gnutls_assert (); - gcry_sexp_release (s_plain); - return GNUTLS_E_INTERNAL_ERROR; - } - } - - gcry_sexp_release (s_plain); - return rc; +int _gnutls_rsa_generate_params (bigint_t * resarr, unsigned int *resarr_len, int bits) +{ + return _generate_params( GNUTLS_PK_RSA, resarr, resarr_len, bits); } - -/* in case of DSA puts into data, r,s - */ -static int -_gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash, mpi_t * pkey, - int pkey_len) +int _gnutls_dsa_generate_params (bigint_t * resarr, unsigned int *resarr_len, int bits) { - gcry_sexp_t s_hash, s_key, s_sig; - int rc = -1; - - /* make a sexp from pkey */ - switch (algo) - { - case GCRY_PK_DSA: - if (pkey_len >= 5) - rc = gcry_sexp_build (&s_key, NULL, - "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]); - else - { - gnutls_assert (); - } - - break; - case GCRY_PK_RSA: - if (pkey_len >= 6) - rc = gcry_sexp_build (&s_key, NULL, - "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))", - pkey[0], pkey[1], pkey[2], pkey[3], - pkey[4], pkey[5]); - else - { - gnutls_assert (); - } - break; - - default: - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - if (rc != 0) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - /* put the data into a simple list */ - if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - /* pass it to libgcrypt */ - rc = gcry_pk_sign (&s_sig, s_hash, s_key); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_key); - - if (rc != 0) - { - gnutls_assert (); - return GNUTLS_E_PK_SIGN_FAILED; - - } - else - { - gcry_sexp_t list; - - if (algo == GCRY_PK_DSA) - { - list = gcry_sexp_find_token (s_sig, "r", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (s_sig); - return GNUTLS_E_INTERNAL_ERROR; - } - - data[0] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); + return _generate_params( GNUTLS_PK_DSA, resarr, resarr_len, bits); +} - list = gcry_sexp_find_token (s_sig, "s", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (s_sig); - return GNUTLS_E_INTERNAL_ERROR; - } +int _gnutls_pk_params_copy( gnutls_pk_params_st* dst, bigint_t* params, int params_len) +{ +int i,j; + dst->params_nr = 0; - data[1] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); + dst->params = gnutls_malloc( sizeof(bigint_t)*params_len); + if (dst->params == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; } - else - { /* GCRY_PK_RSA */ - list = gcry_sexp_find_token (s_sig, "s", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (s_sig); - return GNUTLS_E_INTERNAL_ERROR; - } - data[0] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); + for (i=0;i<params_len;i++) { + dst->params[i] = _gnutls_mpi_set( NULL, params[i]); + if (dst->params[i] == NULL) { + for (j=0;j<i;j++) + _gnutls_mpi_release( &dst->params[j]); + return GNUTLS_E_MEMORY_ERROR; + } + dst->params_nr++; } - } - - gcry_sexp_release (s_sig); - return 0; + + return 0; } - -static int -_gnutls_pk_verify (int algo, mpi_t hash, mpi_t * data, - mpi_t * pkey, int pkey_len) +void gnutls_pk_params_init( gnutls_pk_params_st* p) { - gcry_sexp_t s_sig, s_hash, s_pkey; - int rc = -1; - - /* make a sexp from pkey */ - switch (algo) - { - case GCRY_PK_DSA: - if (pkey_len >= 4) - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", - pkey[0], pkey[1], pkey[2], pkey[3]); - break; - case GCRY_PK_RSA: - if (pkey_len >= 2) - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(rsa(n%m)(e%m)))", - pkey[0], pkey[1]); - break; - - default: - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - if (rc != 0) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - /* put the data into a simple list */ - if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) - { - gnutls_assert (); - gcry_sexp_release (s_pkey); - return GNUTLS_E_INTERNAL_ERROR; - } - - switch (algo) - { - case GCRY_PK_DSA: - rc = gcry_sexp_build (&s_sig, NULL, - "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]); - break; - case GCRY_PK_RSA: - rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%m)))", data[0]); - break; - - default: - gnutls_assert (); - gcry_sexp_release (s_pkey); - gcry_sexp_release (s_hash); - return GNUTLS_E_INTERNAL_ERROR; - } - - if (rc != 0) - { - gnutls_assert (); - gcry_sexp_release (s_pkey); - gcry_sexp_release (s_hash); - return GNUTLS_E_INTERNAL_ERROR; - } - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_pkey); - - if (rc != 0) - { - gnutls_assert (); - return GNUTLS_E_PK_SIG_VERIFY_FAILED; - } + memset( p, 0, sizeof(gnutls_pk_params_st)); +} - return 0; +void gnutls_pk_params_release( gnutls_pk_params_st* p) +{ +unsigned int i; + for (i=0;i<p->params_nr;i++) { + _gnutls_mpi_release( &p->params[i]); + } + gnutls_free( p->params); + p->params = NULL; } diff --git a/lib/gnutls_pk.h b/lib/gnutls_pk.h index e6f37b0e7f..c145a5e0f3 100644 --- a/lib/gnutls_pk.h +++ b/lib/gnutls_pk.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation + * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008 Free Software Foundation * * Author: Nikos Mavrogiannopoulos * @@ -25,22 +25,51 @@ #ifndef GNUTLS_PK_H # define GNUTLS_PK_H +extern int crypto_pk_prio; +extern gnutls_crypto_pk_st _gnutls_pk_ops; + +#define _gnutls_pk_encrypt( algo, ciphertext, plaintext, params) _gnutls_pk_ops.encrypt( algo, ciphertext, plaintext, params) +#define _gnutls_pk_decrypt( algo, ciphertext, plaintext, params) _gnutls_pk_ops.decrypt( algo, ciphertext, plaintext, params) +#define _gnutls_pk_sign( algo, sig, data, params) _gnutls_pk_ops.sign( algo, sig, data, params) +#define _gnutls_pk_verify( algo, data, sig, params) _gnutls_pk_ops.verify( algo, data, sig, params) + +inline static int +_gnutls_pk_fixup( gnutls_pk_algorithm_t algo, gnutls_direction_t direction, gnutls_pk_params_st* params) +{ + if (_gnutls_pk_ops.pk_fixup_private_params) return _gnutls_pk_ops.pk_fixup_private_params(algo, direction, params); + return 0; +} + +int _gnutls_pk_params_copy( gnutls_pk_params_st* dst, bigint_t* params, int params_len); +void gnutls_pk_params_release( gnutls_pk_params_st* p); +void gnutls_pk_params_init( gnutls_pk_params_st* p); + +int _gnutls_rsa_generate_params (bigint_t * resarr, unsigned int *resarr_len, int bits); +int _gnutls_dsa_generate_params (bigint_t * resarr, unsigned int *resarr_len, int bits); + +/* The internal PK interface */ int _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext, const gnutls_datum_t * plaintext, - mpi_t * params, unsigned params_len, + bigint_t * params, unsigned params_len, unsigned btype); int _gnutls_dsa_sign (gnutls_datum_t * signature, - const gnutls_datum_t * plaintext, mpi_t * params, + const gnutls_datum_t * plaintext, bigint_t * params, unsigned params_len); int _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext, const gnutls_datum_t * ciphertext, - mpi_t * params, unsigned params_len, + bigint_t * params, unsigned params_len, unsigned btype); int _gnutls_rsa_verify (const gnutls_datum_t * vdata, - const gnutls_datum_t * ciphertext, mpi_t * params, + const gnutls_datum_t * ciphertext, bigint_t * params, int params_len, int btype); int _gnutls_dsa_verify (const gnutls_datum_t * vdata, - const gnutls_datum_t * sig_value, mpi_t * params, + const gnutls_datum_t * sig_value, bigint_t * params, int params_len); +int +_gnutls_encode_ber_rs (gnutls_datum_t * sig_value, bigint_t r, bigint_t s); + +int +_gnutls_decode_ber_rs (const gnutls_datum_t * sig_value, bigint_t * r, bigint_t * s); + #endif /* GNUTLS_PK_H */ diff --git a/lib/gnutls_priority.c b/lib/gnutls_priority.c index e3264c3f58..870526a628 100644 --- a/lib/gnutls_priority.c +++ b/lib/gnutls_priority.c @@ -357,10 +357,10 @@ static int cert_type_priority[] = { 0 }; -typedef void (rmadd_func) (priority_st * priority_list, int alg); +typedef void (rmadd_func) (priority_st * priority_list, unsigned int alg); static void -prio_remove (priority_st * priority_list, int algo) +prio_remove (priority_st * priority_list, unsigned int algo) { int i = 0; int pos = -1; /* the position of the cipher to remove */ @@ -383,7 +383,7 @@ prio_remove (priority_st * priority_list, int algo) } static void -prio_add (priority_st * priority_list, int algo) +prio_add (priority_st * priority_list, unsigned int algo) { register int i = 0; while (priority_list->priority[i] != 0) diff --git a/lib/gnutls_psk_netconf.c b/lib/gnutls_psk_netconf.c index 7e6b6a710c..52392f3011 100644 --- a/lib/gnutls_psk_netconf.c +++ b/lib/gnutls_psk_netconf.c @@ -66,22 +66,23 @@ gnutls_psk_netconf_derive_key (const char *password, */ rc = _gnutls_hash_init (&dig, GNUTLS_DIG_SHA1); - if (rc) + if (rc < 0) { gnutls_assert (); return rc; } rc = _gnutls_hash (&dig, psk_identity, strlen (psk_identity)); - if (rc) + if (rc < 0) { gnutls_assert (); _gnutls_hash_deinit (&dig, NULL); + fprintf(stderr, "rc: %d\n", rc); return rc; } rc = _gnutls_hash (&dig, netconf_key_pad, strlen (netconf_key_pad)); - if (rc) + if (rc < 0) { gnutls_assert (); _gnutls_hash_deinit (&dig, NULL); @@ -89,7 +90,7 @@ gnutls_psk_netconf_derive_key (const char *password, } rc = _gnutls_hash (&dig, password, strlen (password)); - if (rc) + if (rc < 0) { gnutls_assert (); _gnutls_hash_deinit (&dig, NULL); @@ -108,7 +109,7 @@ gnutls_psk_netconf_derive_key (const char *password, memcpy (inner + sha1len, psk_identity_hint, hintlen); rc = _gnutls_hash_init (&dig, GNUTLS_DIG_SHA1); - if (rc) + if (rc < 0) { gnutls_assert (); gnutls_free (inner); @@ -117,7 +118,7 @@ gnutls_psk_netconf_derive_key (const char *password, rc = _gnutls_hash (&dig, inner, innerlen); gnutls_free (inner); - if (rc) + if (rc < 0) { gnutls_assert (); _gnutls_hash_deinit (&dig, NULL); diff --git a/lib/gnutls_rsa_export.c b/lib/gnutls_rsa_export.c index 33c27d4c7d..1ea83b7803 100644 --- a/lib/gnutls_rsa_export.c +++ b/lib/gnutls_rsa_export.c @@ -43,7 +43,7 @@ /* returns e and m, depends on the requested bits. * We only support limited key sizes. */ -const mpi_t * +const bigint_t * _gnutls_rsa_params_to_mpi (gnutls_rsa_params_t rsa_params) { if (rsa_params == NULL) @@ -55,116 +55,6 @@ _gnutls_rsa_params_to_mpi (gnutls_rsa_params_t rsa_params) } -/* resarr will contain: modulus(0), public exponent(1), private exponent(2), - * prime1 - p (3), prime2 - q(4), u (5). - */ -int -_gnutls_rsa_generate_params (mpi_t * resarr, int *resarr_len, int bits) -{ - - int ret; - gcry_sexp_t parms, key, list; - - ret = gcry_sexp_build (&parms, NULL, "(genkey(rsa(nbits %d)))", bits); - if (ret != 0) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - /* generate the RSA key */ - ret = gcry_pk_genkey (&key, parms); - gcry_sexp_release (parms); - - if (ret != 0) - { - gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - } - - list = gcry_sexp_find_token (key, "n", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (key); - return GNUTLS_E_INTERNAL_ERROR; - } - - resarr[0] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); - - list = gcry_sexp_find_token (key, "e", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (key); - return GNUTLS_E_INTERNAL_ERROR; - } - - resarr[1] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); - - list = gcry_sexp_find_token (key, "d", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (key); - return GNUTLS_E_INTERNAL_ERROR; - } - - resarr[2] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); - - list = gcry_sexp_find_token (key, "p", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (key); - return GNUTLS_E_INTERNAL_ERROR; - } - - resarr[3] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); - - - list = gcry_sexp_find_token (key, "q", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (key); - return GNUTLS_E_INTERNAL_ERROR; - } - - resarr[4] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); - - - list = gcry_sexp_find_token (key, "u", 0); - if (list == NULL) - { - gnutls_assert (); - gcry_sexp_release (key); - return GNUTLS_E_INTERNAL_ERROR; - } - - resarr[5] = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); - - gcry_sexp_release (key); - - _gnutls_dump_mpi ("n: ", resarr[0]); - _gnutls_dump_mpi ("e: ", resarr[1]); - _gnutls_dump_mpi ("d: ", resarr[2]); - _gnutls_dump_mpi ("p: ", resarr[3]); - _gnutls_dump_mpi ("q: ", resarr[4]); - _gnutls_dump_mpi ("u: ", resarr[5]); - - *resarr_len = 6; - - return 0; - -} - /** * gnutls_rsa_params_import_raw - set the RSA parameters diff --git a/lib/gnutls_rsa_export.h b/lib/gnutls_rsa_export.h index b39e5e9325..4fb85ea14d 100644 --- a/lib/gnutls_rsa_export.h +++ b/lib/gnutls_rsa_export.h @@ -22,6 +22,5 @@ * */ -const mpi_t *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t); +const bigint_t *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t); int _gnutls_peers_cert_less_512 (gnutls_session_t session); -int _gnutls_rsa_generate_params (mpi_t * resarr, int *resarr_len, int bits); diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c index 1c931e8a56..e62d43fe02 100644 --- a/lib/gnutls_sig.c +++ b/lib/gnutls_sig.c @@ -219,7 +219,7 @@ _gnutls_tls_sign_params (gnutls_session_t session, gnutls_cert * cert, * given data. The output will be allocated and be put in signature. */ int -_gnutls_sign (gnutls_pk_algorithm_t algo, mpi_t * params, +_gnutls_sign (gnutls_pk_algorithm_t algo, bigint_t * params, int params_size, const gnutls_datum_t * data, gnutls_datum_t * signature) { diff --git a/lib/gnutls_sig.h b/lib/gnutls_sig.h index 4d77071624..f16114c7f2 100644 --- a/lib/gnutls_sig.h +++ b/lib/gnutls_sig.h @@ -45,7 +45,7 @@ int _gnutls_verify_sig_params (gnutls_session_t session, gnutls_datum_t * signature); int _gnutls_sign (gnutls_pk_algorithm_t algo, - mpi_t * params, int params_size, + bigint_t * params, int params_size, const gnutls_datum_t * data, gnutls_datum_t * signature); #endif diff --git a/lib/gnutls_srp.c b/lib/gnutls_srp.c index 84eb1fd151..35df9dceea 100644 --- a/lib/gnutls_srp.c +++ b/lib/gnutls_srp.c @@ -43,12 +43,12 @@ int _gnutls_srp_gx (opaque * text, size_t textsize, opaque ** result, - mpi_t g, mpi_t prime, gnutls_alloc_function galloc_func) + bigint_t g, bigint_t prime, gnutls_alloc_function galloc_func) { - mpi_t x, e; + bigint_t x, e; size_t result_size; - if (_gnutls_mpi_scan_nz (&x, text, &textsize)) + if (_gnutls_mpi_scan_nz (&x, text, textsize)) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; @@ -66,14 +66,14 @@ _gnutls_srp_gx (opaque * text, size_t textsize, opaque ** result, _gnutls_mpi_powm (e, g, x, prime); _gnutls_mpi_release (&x); - _gnutls_mpi_print (NULL, &result_size, e); + _gnutls_mpi_print (e, NULL, &result_size); if (result != NULL) { *result = galloc_func (result_size); if ((*result) == NULL) return GNUTLS_E_MEMORY_ERROR; - _gnutls_mpi_print (*result, &result_size, e); + _gnutls_mpi_print (e, *result, &result_size); } _gnutls_mpi_release (&e); @@ -88,23 +88,17 @@ _gnutls_srp_gx (opaque * text, size_t textsize, opaque ** result, * where k == SHA1(N|g) * Return: B and if ret_b is not NULL b. */ -mpi_t -_gnutls_calc_srp_B (mpi_t * ret_b, mpi_t g, mpi_t n, mpi_t v) +bigint_t +_gnutls_calc_srp_B (bigint_t * ret_b, bigint_t g, bigint_t n, bigint_t v) { - mpi_t tmpB = NULL, tmpV = NULL; - mpi_t b = NULL, B = NULL, k = NULL; + bigint_t tmpB = NULL, tmpV = NULL; + bigint_t b = NULL, B = NULL, k = NULL; int bits; /* calculate: B = (k*v + g^b) % N */ bits = _gnutls_mpi_get_nbits (n); - b = _gnutls_mpi_snew (bits); - if (b == NULL) - { - gnutls_assert (); - return NULL; - } tmpV = _gnutls_mpi_alloc_like (n); @@ -114,16 +108,16 @@ _gnutls_calc_srp_B (mpi_t * ret_b, mpi_t g, mpi_t n, mpi_t v) goto error; } - _gnutls_mpi_randomize (b, bits, GCRY_STRONG_RANDOM); + b = _gnutls_mpi_randomize (NULL, bits, GNUTLS_RND_RANDOM); - tmpB = _gnutls_mpi_snew (bits); + tmpB = _gnutls_mpi_new (bits); if (tmpB == NULL) { gnutls_assert (); goto error; } - B = _gnutls_mpi_snew (bits); + B = _gnutls_mpi_new (bits); if (B == NULL) { gnutls_assert (); @@ -166,21 +160,21 @@ error: /* This calculates the SHA1(A | B) * A and B will be left-padded with zeros to fill n_size. */ -mpi_t -_gnutls_calc_srp_u (mpi_t A, mpi_t B, mpi_t n) +bigint_t +_gnutls_calc_srp_u (bigint_t A, bigint_t B, bigint_t n) { size_t b_size, a_size; opaque *holder, hd[MAX_HASH_SIZE]; size_t holder_size, hash_size, n_size; digest_hd_st td; int ret; - mpi_t res; + bigint_t res; /* get the size of n in bytes */ - _gnutls_mpi_print (NULL, &n_size, n); + _gnutls_mpi_print (n, NULL, &n_size); - _gnutls_mpi_print (NULL, &a_size, A); - _gnutls_mpi_print (NULL, &b_size, B); + _gnutls_mpi_print (A, NULL, &a_size); + _gnutls_mpi_print (B, NULL, &b_size); if (a_size > n_size || b_size > n_size) { @@ -194,8 +188,8 @@ _gnutls_calc_srp_u (mpi_t A, mpi_t B, mpi_t n) if (holder == NULL) return NULL; - _gnutls_mpi_print (&holder[n_size - a_size], &a_size, A); - _gnutls_mpi_print (&holder[n_size + n_size - b_size], &b_size, B); + _gnutls_mpi_print (A, &holder[n_size - a_size], &a_size); + _gnutls_mpi_print (B, &holder[n_size + n_size - b_size], &b_size); ret = _gnutls_hash_init (&td, GNUTLS_MAC_SHA1); if (ret < 0) @@ -210,7 +204,7 @@ _gnutls_calc_srp_u (mpi_t A, mpi_t B, mpi_t n) /* convert the bytes of hd to integer */ hash_size = 20; /* SHA */ - ret = _gnutls_mpi_scan_nz (&res, hd, &hash_size); + ret = _gnutls_mpi_scan_nz (&res, hd, hash_size); gnutls_free (holder); if (ret < 0) @@ -225,11 +219,11 @@ _gnutls_calc_srp_u (mpi_t A, mpi_t B, mpi_t n) /* S = (A * v^u) ^ b % N * this is our shared key (server premaster secret) */ -mpi_t -_gnutls_calc_srp_S1 (mpi_t A, mpi_t b, mpi_t u, mpi_t v, mpi_t n) +bigint_t +_gnutls_calc_srp_S1 (bigint_t A, bigint_t b, bigint_t u, bigint_t v, bigint_t n) { - mpi_t tmp1 = NULL, tmp2 = NULL; - mpi_t S = NULL; + bigint_t tmp1 = NULL, tmp2 = NULL; + bigint_t S = NULL; S = _gnutls_mpi_alloc_like (n); if (S == NULL) @@ -259,24 +253,17 @@ freeall: /* A = g^a % N * returns A and a (which is random) */ -mpi_t -_gnutls_calc_srp_A (mpi_t * a, mpi_t g, mpi_t n) +bigint_t +_gnutls_calc_srp_A (bigint_t * a, bigint_t g, bigint_t n) { - mpi_t tmpa; - mpi_t A; + bigint_t tmpa; + bigint_t A; int bits; bits = _gnutls_mpi_get_nbits (n); - tmpa = _gnutls_mpi_snew (bits); - if (tmpa == NULL) - { - gnutls_assert (); - return NULL; - } - - _gnutls_mpi_randomize (tmpa, bits, GCRY_STRONG_RANDOM); + tmpa = _gnutls_mpi_randomize (NULL, bits, GNUTLS_RND_RANDOM); - A = _gnutls_mpi_snew (bits); + A = _gnutls_mpi_new (bits); if (A == NULL) { gnutls_assert (); @@ -345,11 +332,11 @@ _gnutls_calc_srp_x (char *username, char *password, opaque * salt, /* S = (B - k*g^x) ^ (a + u * x) % N * this is our shared key (client premaster secret) */ -mpi_t -_gnutls_calc_srp_S2 (mpi_t B, mpi_t g, mpi_t x, mpi_t a, mpi_t u, mpi_t n) +bigint_t +_gnutls_calc_srp_S2 (bigint_t B, bigint_t g, bigint_t x, bigint_t a, bigint_t u, bigint_t n) { - mpi_t S = NULL, tmp1 = NULL, tmp2 = NULL; - mpi_t tmp4 = NULL, tmp3 = NULL, k = NULL; + bigint_t S = NULL, tmp1 = NULL, tmp2 = NULL; + bigint_t tmp4 = NULL, tmp3 = NULL, k = NULL; S = _gnutls_mpi_alloc_like (n); if (S == NULL) @@ -696,7 +683,7 @@ gnutls_srp_verifier (const char *username, const char *password, const gnutls_datum_t * generator, const gnutls_datum_t * prime, gnutls_datum_t * res) { - mpi_t _n, _g; + bigint_t _n, _g; int ret; size_t digest_size = 20, size; opaque digest[20]; @@ -710,14 +697,14 @@ gnutls_srp_verifier (const char *username, const char *password, } size = prime->size; - if (_gnutls_mpi_scan_nz (&_n, prime->data, &size)) + if (_gnutls_mpi_scan_nz (&_n, prime->data, size)) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; } size = generator->size; - if (_gnutls_mpi_scan_nz (&_g, generator->data, &size)) + if (_gnutls_mpi_scan_nz (&_g, generator->data, size)) { gnutls_assert (); return GNUTLS_E_MPI_SCAN_FAILED; diff --git a/lib/gnutls_srp.h b/lib/gnutls_srp.h index 1bf36e9432..7cf2c14b5c 100644 --- a/lib/gnutls_srp.h +++ b/lib/gnutls_srp.h @@ -25,13 +25,13 @@ #ifdef ENABLE_SRP int _gnutls_srp_gx (opaque * text, size_t textsize, opaque ** result, - mpi_t g, mpi_t prime, gnutls_alloc_function); -mpi_t _gnutls_calc_srp_B (mpi_t * ret_b, mpi_t g, mpi_t n, mpi_t v); -mpi_t _gnutls_calc_srp_u (mpi_t A, mpi_t B, mpi_t N); -mpi_t _gnutls_calc_srp_S1 (mpi_t A, mpi_t b, mpi_t u, mpi_t v, mpi_t n); -mpi_t _gnutls_calc_srp_A (mpi_t * a, mpi_t g, mpi_t n); -mpi_t _gnutls_calc_srp_S2 (mpi_t B, mpi_t g, mpi_t x, mpi_t a, mpi_t u, - mpi_t n); + bigint_t g, bigint_t prime, gnutls_alloc_function); +bigint_t _gnutls_calc_srp_B (bigint_t * ret_b, bigint_t g, bigint_t n, bigint_t v); +bigint_t _gnutls_calc_srp_u (bigint_t A, bigint_t B, bigint_t N); +bigint_t _gnutls_calc_srp_S1 (bigint_t A, bigint_t b, bigint_t u, bigint_t v, bigint_t n); +bigint_t _gnutls_calc_srp_A (bigint_t * a, bigint_t g, bigint_t n); +bigint_t _gnutls_calc_srp_S2 (bigint_t B, bigint_t g, bigint_t x, bigint_t a, bigint_t u, + bigint_t n); int _gnutls_calc_srp_x (char *username, char *password, opaque * salt, size_t salt_size, size_t * size, void *digest); int _gnutls_srp_gn (opaque ** ret_g, opaque ** ret_n, int bits); diff --git a/lib/gnutls_state.c b/lib/gnutls_state.c index 5d3c61be02..ece4835652 100644 --- a/lib/gnutls_state.c +++ b/lib/gnutls_state.c @@ -438,7 +438,7 @@ _gnutls_dh_get_allowed_prime_bits (gnutls_session_t session) } int -_gnutls_dh_set_peer_public (gnutls_session_t session, mpi_t public) +_gnutls_dh_set_peer_public (gnutls_session_t session, bigint_t public) { dh_info_st *dh; int ret; @@ -481,7 +481,7 @@ _gnutls_dh_set_peer_public (gnutls_session_t session, mpi_t public) return GNUTLS_E_INTERNAL_ERROR; } - ret = _gnutls_mpi_dprint_lz (&dh->public_key, public); + ret = _gnutls_mpi_dprint_lz (public, &dh->public_key); if (ret < 0) { gnutls_assert (); @@ -538,7 +538,7 @@ _gnutls_dh_set_secret_bits (gnutls_session_t session, unsigned bits) */ int _gnutls_rsa_export_set_pubkey (gnutls_session_t session, - mpi_t exponent, mpi_t modulus) + bigint_t exponent, bigint_t modulus) { cert_auth_info_t info; int ret; @@ -547,14 +547,14 @@ _gnutls_rsa_export_set_pubkey (gnutls_session_t session, if (info == NULL) return GNUTLS_E_INTERNAL_ERROR; - ret = _gnutls_mpi_dprint_lz (&info->rsa_export.modulus, modulus); + ret = _gnutls_mpi_dprint_lz (modulus, &info->rsa_export.modulus); if (ret < 0) { gnutls_assert (); return ret; } - ret = _gnutls_mpi_dprint_lz (&info->rsa_export.exponent, exponent); + ret = _gnutls_mpi_dprint_lz (exponent, &info->rsa_export.exponent); if (ret < 0) { gnutls_assert (); @@ -569,7 +569,7 @@ _gnutls_rsa_export_set_pubkey (gnutls_session_t session, /* Sets the prime and the generator in the auth info structure. */ int -_gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime) +_gnutls_dh_set_group (gnutls_session_t session, bigint_t gen, bigint_t prime) { dh_info_st *dh; int ret; @@ -614,7 +614,7 @@ _gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime) /* prime */ - ret = _gnutls_mpi_dprint_lz (&dh->prime, prime); + ret = _gnutls_mpi_dprint_lz (prime, &dh->prime); if (ret < 0) { gnutls_assert (); @@ -623,7 +623,7 @@ _gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime) /* generator */ - ret = _gnutls_mpi_dprint_lz (&dh->generator, gen); + ret = _gnutls_mpi_dprint_lz (gen, &dh->generator); if (ret < 0) { gnutls_assert (); diff --git a/lib/gnutls_state.h b/lib/gnutls_state.h index c611491520..2e99ec0a29 100644 --- a/lib/gnutls_state.h +++ b/lib/gnutls_state.h @@ -47,14 +47,14 @@ int _gnutls_session_cert_type_supported (gnutls_session_t, int _gnutls_dh_set_secret_bits (gnutls_session_t session, unsigned bits); -int _gnutls_dh_set_peer_public (gnutls_session_t session, mpi_t public); -int _gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime); +int _gnutls_dh_set_peer_public (gnutls_session_t session, bigint_t public); +int _gnutls_dh_set_group (gnutls_session_t session, bigint_t gen, bigint_t prime); int _gnutls_dh_get_allowed_prime_bits (gnutls_session_t session); void _gnutls_handshake_internal_state_clear (gnutls_session_t); int _gnutls_rsa_export_set_pubkey (gnutls_session_t session, - mpi_t exponent, mpi_t modulus); + bigint_t exponent, bigint_t modulus); int _gnutls_session_is_resumable (gnutls_session_t session); int _gnutls_session_is_export (gnutls_session_t session); diff --git a/lib/gnutls_supplemental.c b/lib/gnutls_supplemental.c index 945582759f..f8a5510133 100644 --- a/lib/gnutls_supplemental.c +++ b/lib/gnutls_supplemental.c @@ -162,7 +162,7 @@ _gnutls_parse_supplemental (gnutls_session_t session, total_size = _gnutls_read_uint24 (p); p += 3; - if (dsize != total_size) + if (dsize != (ssize_t)total_size) { gnutls_assert(); return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; diff --git a/lib/gnutls_x509.h b/lib/gnutls_x509.h index 3aa0d915f8..9db8f99b11 100644 --- a/lib/gnutls_x509.h +++ b/lib/gnutls_x509.h @@ -39,8 +39,8 @@ int _gnutls_x509_cert_verify_peers (gnutls_session_t session, int _gnutls_check_key_usage (const gnutls_cert * cert, gnutls_kx_algorithm_t alg); -int _gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params); -int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params); +int _gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params); +int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params); int _gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey, const gnutls_datum_t * raw_key, diff --git a/lib/mac-libgcrypt.c b/lib/mac-libgcrypt.c new file mode 100644 index 0000000000..0443a75342 --- /dev/null +++ b/lib/mac-libgcrypt.c @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2008 Free Software Foundation + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +/* This file provides is the backend hash/mac API for libgcrypt. + */ + +#include <gnutls_int.h> +#include <gnutls_hash_int.h> +#include <gnutls_errors.h> +#include <gcrypt.h> + +static int wrap_gcry_mac_init( gnutls_mac_algorithm_t algo, void** ctx) +{ +int err; +unsigned int flags = GCRY_MD_FLAG_HMAC; + + switch (algo) + { + case GNUTLS_MAC_MD5: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_MD5, flags); + break; + case GNUTLS_MAC_SHA1: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_SHA1, flags); + break; + case GNUTLS_MAC_RMD160: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_RMD160, flags); + break; + case GNUTLS_MAC_MD2: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_MD2, flags); + break; + case GNUTLS_MAC_SHA256: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_SHA256, flags); + break; + case GNUTLS_MAC_SHA384: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_SHA384, flags); + break; + case GNUTLS_MAC_SHA512: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_SHA512, flags); + break; + default: + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + if (err == 0) return 0; + + gnutls_assert(); + return GNUTLS_E_ENCRYPTION_FAILED; +} + +static int wrap_gcry_hash_init( gnutls_digest_algorithm_t algo, void** ctx) +{ +int err; +unsigned int flags = 0; + + switch (algo) + { + case GNUTLS_DIG_MD5: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_MD5, flags); + break; + case GNUTLS_DIG_SHA1: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_SHA1, flags); + break; + case GNUTLS_DIG_RMD160: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_RMD160, flags); + break; + case GNUTLS_DIG_MD2: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_MD2, flags); + break; + case GNUTLS_DIG_SHA256: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_SHA256, flags); + break; + case GNUTLS_DIG_SHA224: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_SHA224, flags); + break; + case GNUTLS_DIG_SHA384: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_SHA384, flags); + break; + case GNUTLS_DIG_SHA512: + err = gcry_md_open( (gcry_md_hd_t*)ctx, GCRY_MD_SHA512, flags); + break; + default: + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + if (err == 0) return 0; + + gnutls_assert(); + return GNUTLS_E_ENCRYPTION_FAILED; +} + +int wrap_gcry_mac_output( void* src_ctx, void* digest, size_t digestsize) +{ +opaque *_digest = gcry_md_read (src_ctx, 0); + + if (_digest != NULL) + { + int len = gcry_md_get_algo_dlen(gcry_md_get_algo(src_ctx)); + + if (len <= digestsize && digest != NULL) + memcpy( digest, _digest, len); + + return 0; + } + + gnutls_assert(); + return GNUTLS_E_HASH_FAILED; +} + +int crypto_mac_prio = INT_MAX; + +gnutls_crypto_mac_st _gnutls_mac_ops = { + .init = wrap_gcry_mac_init, + .setkey = gcry_md_setkey, + .hash = gcry_md_write, + .copy = gcry_md_copy, + .output = wrap_gcry_mac_output, + .deinit = gcry_md_close, +}; + +int crypto_digest_prio = INT_MAX; + +gnutls_crypto_digest_st _gnutls_digest_ops = { + .init = wrap_gcry_hash_init, + .setkey = NULL, + .hash = gcry_md_write, + .copy = gcry_md_copy, + .output = wrap_gcry_mac_output, + .deinit = gcry_md_close, +}; diff --git a/lib/mpi-libgcrypt.c b/lib/mpi-libgcrypt.c new file mode 100644 index 0000000000..5e20ab7971 --- /dev/null +++ b/lib/mpi-libgcrypt.c @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008 Free Software Foundation + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +/* Here lie everything that has to do with large numbers, libgcrypt and + * other stuff that didn't fit anywhere else. + */ + +#include <gnutls_int.h> +#include <libtasn1.h> +#include <gnutls_errors.h> +#include <gnutls_num.h> +#include <gnutls_mpi.h> +#include <gcrypt.h> + +/* Functions that refer to the libgcrypt library. + */ + +static inline int _format_conv( gnutls_bigint_format_t format) +{ + if (format == GNUTLS_MPI_FORMAT_USG) return GCRYMPI_FMT_USG; + else if (format == GNUTLS_MPI_FORMAT_STD) return GCRYMPI_FMT_STD; + else return GCRYMPI_FMT_PGP; +} + +/* returns zero on success + */ +bigint_t +wrap_gcry_mpi_scan (const void * buffer, size_t nbytes, gnutls_bigint_format_t format) +{ + gcry_mpi_t ret_mpi = NULL; + int ret; + + ret = gcry_mpi_scan (&ret_mpi, _format_conv(format), buffer, nbytes, NULL); + if (ret != 0) + return NULL; + + return ret_mpi; +} + +int +wrap_gcry_mpi_print (const bigint_t a, void *buffer, size_t * nbytes, gnutls_bigint_format_t format) +{ + int ret; + + format = _format_conv(format); + + if (nbytes == NULL || a == NULL) + return GNUTLS_E_INVALID_REQUEST; + + ret = gcry_mpi_print( format, buffer, *nbytes, nbytes, a); + if (!ret) + return 0; + + return GNUTLS_E_MPI_PRINT_FAILED; +} + +#undef _gnutls_mpi_alloc_like +#define _gnutls_mpi_alloc_like(x) gcry_mpi_new(gcry_mpi_get_nbits(x)) + +bigint_t wrap_gcry_mpi_mod( const bigint_t a, const bigint_t b) +{ + bigint_t r = _gnutls_mpi_alloc_like (b); + + if (r == NULL) + return NULL; + + gcry_mpi_mod( r, a, b); + + return r; +} + +bigint_t wrap_gcry_mpi_powm( bigint_t w, const bigint_t b, const bigint_t e, const bigint_t m) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (m); + + if (w == NULL) + return NULL; + + gcry_mpi_powm( w, b, e, m); + + return w; +} + +bigint_t wrap_gcry_mpi_addm( bigint_t w, const bigint_t a, const bigint_t b, const bigint_t m) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (m); + + if (w == NULL) + return NULL; + + gcry_mpi_addm( w, a, b, m); + + return w; +} + +bigint_t wrap_gcry_mpi_subm( bigint_t w, const bigint_t a, const bigint_t b, const bigint_t m) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (m); + + if (w == NULL) + return NULL; + + gcry_mpi_subm( w, a, b, m); + + return w; +} + +bigint_t wrap_gcry_mpi_mulm( bigint_t w, const bigint_t a, const bigint_t b, const bigint_t m) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (m); + + if (w == NULL) + return NULL; + + gcry_mpi_mulm( w, a, b, m); + + return w; +} + +bigint_t wrap_gcry_mpi_add( bigint_t w, const bigint_t a, const bigint_t b) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (b); + + if (w == NULL) + return NULL; + + gcry_mpi_add( w, a, b); + + return w; +} + +bigint_t wrap_gcry_mpi_sub( bigint_t w, const bigint_t a, const bigint_t b) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (b); + + if (w == NULL) + return NULL; + + gcry_mpi_sub( w, a, b); + + return w; +} + +bigint_t wrap_gcry_mpi_mul( bigint_t w, const bigint_t a, const bigint_t b) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (b); + + if (w == NULL) + return NULL; + + gcry_mpi_mul( w, a, b); + + return w; +} + +/* q = a / b */ +bigint_t wrap_gcry_mpi_div( bigint_t q, const bigint_t a, const bigint_t b) +{ + if (q == NULL) + q = _gnutls_mpi_alloc_like (a); + + if (q == NULL) + return NULL; + + gcry_mpi_div( q, NULL, a, b, 0); + + return q; +} + +bigint_t wrap_gcry_mpi_add_ui( bigint_t w, const bigint_t a, unsigned long b) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (a); + + if (w == NULL) + return NULL; + + gcry_mpi_add_ui( w, a, b); + + return w; +} + +bigint_t wrap_gcry_mpi_sub_ui( bigint_t w, const bigint_t a, unsigned long b) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (a); + + if (w == NULL) + return NULL; + + gcry_mpi_sub_ui( w, a, b); + + return w; +} + +bigint_t wrap_gcry_mpi_mul_ui( bigint_t w, const bigint_t a, unsigned long b) +{ + if (w == NULL) + w = _gnutls_mpi_alloc_like (a); + + if (w == NULL) + return NULL; + + gcry_mpi_mul_ui( w, a, b); + + return w; +} + +int wrap_gcry_prime_check( bigint_t pp) +{ + return gcry_prime_check( pp, 0); +} + +int wrap_gcry_generate_group( gnutls_group_st *group, unsigned int bits) +{ + bigint_t g = NULL, prime = NULL; + gcry_error_t err; + int result, times = 0, qbits; + gcry_mpi_t *factors = NULL; + + /* Calculate the size of a prime factor of (prime-1)/2. + * This is an emulation of the values in "Selecting Cryptographic Key Sizes" paper. + */ + if (bits < 256) + qbits = bits / 2; + else + { + qbits = (bits/40) + 105; + } + + if (qbits & 1) /* better have an even number */ + qbits++; + + /* find a prime number of size bits. + */ + do + { + + if (times) + { + _gnutls_mpi_release (&prime); + gcry_prime_release_factors (factors); + } + + err = gcry_prime_generate ((gcry_mpi_t*)&prime, bits, qbits, + &factors, NULL, NULL, GCRY_STRONG_RANDOM, + GCRY_PRIME_FLAG_SPECIAL_FACTOR); + + if (err != 0) + { + gnutls_assert (); + result = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + err = gcry_prime_check (prime, 0); + + times++; + } + while (err != 0 && times < 10); + + if (err != 0) + { + gnutls_assert (); + result = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + /* generate the group generator. + */ + err = gcry_prime_group_generator ((gcry_mpi_t*)&g, prime, factors, NULL); + if (err != 0) + { + gnutls_assert (); + result = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + gcry_prime_release_factors (factors); + factors = NULL; + + group->g = g; + group->p = prime; + + return 0; + +cleanup: + gcry_prime_release_factors (factors); + _gnutls_mpi_release (&g); + _gnutls_mpi_release (&prime); + + return result; + +} + +int crypto_bigint_prio = INT_MAX; + +gnutls_crypto_bigint_st _gnutls_mpi_ops = { + .bigint_new = gcry_mpi_new, + .bigint_cmp = gcry_mpi_cmp, + .bigint_cmp_ui = gcry_mpi_cmp_ui, + .bigint_mod = wrap_gcry_mpi_mod, + .bigint_set = gcry_mpi_set, + .bigint_set_ui = gcry_mpi_set_ui, + .bigint_get_nbits = gcry_mpi_get_nbits, + .bigint_powm = wrap_gcry_mpi_powm, + .bigint_addm = wrap_gcry_mpi_addm, + .bigint_subm = wrap_gcry_mpi_subm, + .bigint_add = wrap_gcry_mpi_add, + .bigint_sub = wrap_gcry_mpi_sub, + .bigint_add_ui = wrap_gcry_mpi_add_ui, + .bigint_sub_ui = wrap_gcry_mpi_sub_ui, + .bigint_mul = wrap_gcry_mpi_mul, + .bigint_mulm = wrap_gcry_mpi_mulm, + .bigint_mul_ui = wrap_gcry_mpi_mul_ui, + .bigint_div = wrap_gcry_mpi_div, + .bigint_prime_check = wrap_gcry_prime_check, + .bigint_release = gcry_mpi_release, + .bigint_print = wrap_gcry_mpi_print, + .bigint_scan = wrap_gcry_mpi_scan, + .bigint_generate_group = wrap_gcry_generate_group +}; diff --git a/lib/opencdk/Makefile.am b/lib/opencdk/Makefile.am index a612c101bb..ae04f7c184 100644 --- a/lib/opencdk/Makefile.am +++ b/lib/opencdk/Makefile.am @@ -20,7 +20,7 @@ # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, # MA 02110-1301, USA -INCLUDES = -I$(top_srcdir)/lib \ +INCLUDES = -I$(top_srcdir)/lib -I$(top_srcdir)/includes \ -I$(top_srcdir)/lgl -I$(top_builddir)/lgl noinst_LTLIBRARIES = libminiopencdk.la diff --git a/lib/opencdk/armor.c b/lib/opencdk/armor.c index f5317ed07c..8c5eb5ed63 100644 --- a/lib/opencdk/armor.c +++ b/lib/opencdk/armor.c @@ -278,7 +278,6 @@ is_armored (int ctb) switch (pkttype) { case CDK_PKT_MARKER: - case CDK_PKT_SYMKEY_ENC: case CDK_PKT_ONEPASS_SIG: case CDK_PKT_PUBLIC_KEY: case CDK_PKT_SECRET_KEY: @@ -286,7 +285,6 @@ is_armored (int ctb) case CDK_PKT_SIGNATURE: case CDK_PKT_LITERAL: case CDK_PKT_COMPRESSED: - case CDK_PKT_ENCRYPTED: return 0; /* seems to be a regular packet: not armored */ } return 1; @@ -296,7 +294,7 @@ is_armored (int ctb) static u32 update_crc (u32 crc, const byte *buf, size_t buflen) { - int j; + unsigned int j; if (!crc) crc = CRCINIT; @@ -320,8 +318,8 @@ armor_encode (void *opaque, FILE *in, FILE *out) if (!afx) return CDK_Inv_Value; - if (afx->idx < 0 || afx->idx > DIM (armor_begin) || - afx->idx2 < 0 || afx->idx2 > DIM (armor_end)) + if (afx->idx < 0 || afx->idx > (int)DIM (armor_begin) || + afx->idx2 < 0 || afx->idx2 > (int)DIM (armor_end)) return CDK_Inv_Value; _cdk_log_debug ("armor filter: encode\n"); @@ -424,7 +422,7 @@ armor_decode (void *opaque, FILE *in, FILE *out) char buf[127]; byte raw[128], crcbuf[4]; u32 crc2 = 0; - size_t nread = 0; + ssize_t nread = 0; int i, pgp_data = 0; cdk_error_t rc = 0; diff --git a/lib/opencdk/context.h b/lib/opencdk/context.h index e70fc57340..71595a907a 100644 --- a/lib/opencdk/context.h +++ b/lib/opencdk/context.h @@ -74,7 +74,6 @@ struct cdk_ctx_s { cdk_pkt_seckey_t sk; unsigned on:1; } cache; - cdk_dek_t dek; struct { cdk_keydb_hd_t sec; cdk_keydb_hd_t pub; diff --git a/lib/opencdk/dummy.c b/lib/opencdk/dummy.c index e21e927d43..4fd2596cc3 100644 --- a/lib/opencdk/dummy.c +++ b/lib/opencdk/dummy.c @@ -9,7 +9,7 @@ cdk_error_t _cdk_proc_packets (cdk_ctx_t hd, cdk_stream_t inp, cdk_stream_t data, const char *output, cdk_stream_t outstream, - gcry_md_hd_t md) + digest_hd_st* md) { return 0; } diff --git a/lib/opencdk/filters.h b/lib/opencdk/filters.h index ebbb4afb27..d5a63afd4d 100644 --- a/lib/opencdk/filters.h +++ b/lib/opencdk/filters.h @@ -31,10 +31,9 @@ enum { }; typedef struct { - gcry_cipher_hd_t hd; - gcry_md_hd_t mdc; + cipher_hd_st hd; + digest_hd_st mdc; int mdc_method; - cdk_dek_t dek; u32 datalen; struct { size_t on; @@ -46,7 +45,8 @@ typedef struct { typedef struct { int digest_algo; - gcry_md_hd_t md; + digest_hd_st md; + int md_initialized; } md_filter_t; typedef struct { @@ -61,7 +61,8 @@ typedef struct { cdk_lit_format_t mode; char *orig_filename; /* This original name of the input file. */ char *filename; - gcry_md_hd_t md; + digest_hd_st md; + int md_initialized; struct { size_t on; off_t size; diff --git a/lib/opencdk/hash.c b/lib/opencdk/hash.c index 4a18b8600e..a5c5dc05a8 100644 --- a/lib/opencdk/hash.c +++ b/lib/opencdk/hash.c @@ -37,7 +37,7 @@ hash_encode (void *opaque, FILE *in, FILE *out) { md_filter_t *mfx = opaque; byte buf[BUFSIZE]; - gcry_error_t err; + int err; int nread; if (!mfx) @@ -45,11 +45,13 @@ hash_encode (void *opaque, FILE *in, FILE *out) _cdk_log_debug ("hash filter: encode algo=%d\n", mfx->digest_algo); - if (!mfx->md) + if (!mfx->md_initialized) { - err = gcry_md_open (&mfx->md, mfx->digest_algo, 0); - if (err) - return map_gcry_error (err); + err = _gnutls_hash_init (&mfx->md, mfx->digest_algo); + if (err < 0) + return map_gnutls_error (err); + + mfx->md_initialized = 1; } while (!feof (in)) @@ -57,7 +59,7 @@ hash_encode (void *opaque, FILE *in, FILE *out) nread = fread (buf, 1, BUFSIZE, in); if (!nread) break; - gcry_md_write (mfx->md, buf, nread); + _gnutls_hash (&mfx->md, buf, nread); } wipemem (buf, sizeof (buf)); @@ -75,8 +77,8 @@ _cdk_filter_hash (void *opaque, int ctl, FILE *in, FILE *out) if (mfx) { _cdk_log_debug ("free hash filter\n"); - gcry_md_close (mfx->md); - mfx->md = NULL; + _gnutls_hash_deinit (&mfx->md, NULL); + mfx->md_initialized = 0; return 0; } } diff --git a/lib/opencdk/kbnode.c b/lib/opencdk/kbnode.c index fc76b94fb7..466213c66c 100644 --- a/lib/opencdk/kbnode.c +++ b/lib/opencdk/kbnode.c @@ -121,7 +121,7 @@ _cdk_kbnode_add (cdk_kbnode_t root, cdk_kbnode_t node) * type @pkttype (only if @pkttype != 0). **/ void -cdk_kbnode_insert (cdk_kbnode_t root, cdk_kbnode_t node, int pkttype) +cdk_kbnode_insert (cdk_kbnode_t root, cdk_kbnode_t node, cdk_packet_type_t pkttype) { if (!pkttype) { @@ -156,7 +156,7 @@ cdk_kbnode_insert (cdk_kbnode_t root, cdk_kbnode_t node, int pkttype) * with pkttype @pkttype in the list starting with @root of @node. **/ cdk_kbnode_t -cdk_kbnode_find_prev (cdk_kbnode_t root, cdk_kbnode_t node, int pkttype) +cdk_kbnode_find_prev (cdk_kbnode_t root, cdk_kbnode_t node, cdk_packet_type_t pkttype) { cdk_kbnode_t n1; @@ -182,7 +182,7 @@ cdk_kbnode_find_prev (cdk_kbnode_t root, cdk_kbnode_t node, int pkttype) * a user-id. **/ cdk_kbnode_t -cdk_kbnode_find_next (cdk_kbnode_t node, int pkttype) +cdk_kbnode_find_next (cdk_kbnode_t node, cdk_packet_type_t pkttype) { for (node = node->next; node; node = node->next) { @@ -212,7 +212,7 @@ cdk_kbnode_find_next (cdk_kbnode_t node, int pkttype) * Tries to find the next node with the packettype @pkttype. **/ cdk_kbnode_t -cdk_kbnode_find (cdk_kbnode_t node, int pkttype) +cdk_kbnode_find (cdk_kbnode_t node, cdk_packet_type_t pkttype) { for (; node; node = node->next) { @@ -231,7 +231,7 @@ cdk_kbnode_find (cdk_kbnode_t node, int pkttype) * Same as cdk_kbnode_find but it returns the packet instead of the node. **/ cdk_packet_t -cdk_kbnode_find_packet (cdk_kbnode_t node, int pkttype) +cdk_kbnode_find_packet (cdk_kbnode_t node, cdk_packet_type_t pkttype) { cdk_kbnode_t res; @@ -419,6 +419,8 @@ cdk_kbnode_read_from_mem (cdk_kbnode_t *ret_node, if (rc) return rc; rc = cdk_keydb_get_keyblock (inp, ret_node); + if (rc) + gnutls_assert(); cdk_stream_close (inp); return rc; } @@ -559,8 +561,8 @@ cdk_kbnode_write_to_mem (cdk_kbnode_t node, byte *buf, size_t *r_nbytes) * is extracted from it. **/ cdk_error_t -cdk_kbnode_hash (cdk_kbnode_t node, gcry_md_hd_t md, int is_v4, - int pkttype, int flags) +cdk_kbnode_hash (cdk_kbnode_t node, digest_hd_st* md, int is_v4, + cdk_packet_type_t pkttype, int flags) { cdk_packet_t pkt; diff --git a/lib/opencdk/keydb.c b/lib/opencdk/keydb.c index 3eb35697ee..0580c58ebb 100644 --- a/lib/opencdk/keydb.c +++ b/lib/opencdk/keydb.c @@ -42,7 +42,6 @@ #define KEYDB_CACHE_ENTRIES 8 static void keydb_cache_free (key_table_t cache); -static int keydb_search_copy (cdk_keydb_search_t *r_dst, cdk_keydb_search_t src); static int classify_data (const byte * buf, size_t len); static cdk_kbnode_t find_selfsig_node (cdk_kbnode_t key, cdk_pkt_pubkey_t pk); @@ -401,7 +400,7 @@ cdk_keydb_free (cdk_keydb_hd_t hd) cdk_error_t _cdk_keydb_open (cdk_keydb_hd_t hd, cdk_stream_t *ret_kr) { - cdk_error_t rc, ec; + cdk_error_t rc; cdk_stream_t kr; if (!hd || !ret_kr) @@ -612,45 +611,6 @@ keydb_cache_add ( cdk_keydb_search_t dbs, off_t offset) return 0; } - -static cdk_error_t -keydb_search_copy (cdk_keydb_search_t *r_dst, cdk_keydb_search_t src) -{ - cdk_keydb_search_t dst; - - if (!r_dst || !src) - return CDK_Inv_Value; - - *r_dst = NULL; - dst = cdk_calloc (1, sizeof *dst); - if (!dst) - return CDK_Out_Of_Core; - - dst->off = src->off; - dst->type = src->type; - switch (src->type) - { - case CDK_DBSEARCH_EXACT: - case CDK_DBSEARCH_SUBSTR: - dst->u.pattern = cdk_strdup (src->u.pattern); - if (!dst->u.pattern) - return CDK_Out_Of_Core; - break; - - case CDK_DBSEARCH_SHORT_KEYID: - case CDK_DBSEARCH_KEYID: - dst->u.keyid[0] = src->u.keyid[0]; - dst->u.keyid[1] = src->u.keyid[1]; - break; - - case CDK_DBSEARCH_FPR: - memcpy (dst->u.fpr, src->u.fpr, KEY_FPR_LEN); - break; - } - *r_dst = dst; - return 0; -} - static cdk_error_t idx_init( cdk_keydb_hd_t db, cdk_keydb_search_t dbs) { cdk_error_t ec, rc = 0; @@ -675,7 +635,9 @@ cdk_error_t ec, rc = 0; if (!rc) rc = cdk_stream_open (dbs->idx_name, &dbs->idx); if (!rc) + { _cdk_log_debug ("create key index table\n"); + } else { /* This is no real error, it just means we can't create @@ -1071,7 +1033,7 @@ keydb_check_key (cdk_packet_t pkt) /* Find the first kbnode with the requested packet type that represents a valid key. */ static cdk_kbnode_t -kbnode_find_valid (cdk_kbnode_t root, int pkttype) +kbnode_find_valid (cdk_kbnode_t root, cdk_packet_type_t pkttype) { cdk_kbnode_t n; @@ -1871,7 +1833,7 @@ static int classify_data (const byte *buf, size_t len) { int type; - int i; + unsigned int i; if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X')) { /* Skip hex prefix. */ @@ -1954,7 +1916,7 @@ cdk_keydb_export (cdk_keydb_hd_t hd, cdk_stream_t out, cdk_strlist_t remusr) continue; /* Filter out invalid signatures */ if (node->pkt->pkttype == CDK_PKT_SIGNATURE && - !KEY_CAN_SIGN (node->pkt->pkt.signature->pubkey_algo)) + (!KEY_CAN_SIGN (node->pkt->pkt.signature->pubkey_algo))) continue; /* Adjust the ctb flag if needed. */ diff --git a/lib/opencdk/literal.c b/lib/opencdk/literal.c index 0932019441..7a0a43453b 100644 --- a/lib/opencdk/literal.c +++ b/lib/opencdk/literal.c @@ -56,7 +56,7 @@ literal_decode (void *opaque, FILE *in, FILE *out) cdk_packet_t pkt; cdk_pkt_literal_t pt; byte buf[BUFSIZE]; - size_t nread; + ssize_t nread; int bufsize; cdk_error_t rc; @@ -131,14 +131,14 @@ literal_decode (void *opaque, FILE *in, FILE *out) rc = CDK_File_Error; break; } - if (pfx->md) - gcry_md_write (pfx->md, buf, nread); + if (pfx->md_initialized) + _gnutls_hash (&pfx->md, buf, nread); cdk_stream_write (so, buf, nread); pt->len -= nread; if (pfx->blkmode.on) { pfx->blkmode.size = _cdk_pkt_read_len (in, &pfx->blkmode.on); - if (pfx->blkmode.size == (size_t)EOF) + if ((ssize_t)pfx->blkmode.size == EOF) return CDK_Inv_Packet; } if (pt->len <= 0 && !pfx->blkmode.on) diff --git a/lib/opencdk/main.c b/lib/opencdk/main.c index 8d504f765a..cb89a471e9 100644 --- a/lib/opencdk/main.c +++ b/lib/opencdk/main.c @@ -41,27 +41,7 @@ /* Set a default cipher algorithm and a digest algorithm. Even if AES and SHA-256 are not 'MUST' in the latest OpenPGP draft, AES seems to be a good choice. */ -#define DEFAULT_CIPHER_ALGO GCRY_CIPHER_AES -#define DEFAULT_DIGEST_ALGO GCRY_MD_SHA256 - -/* The site of the secure memory which is allocated in gcrypt. */ -#define SECMEM_SIZE 16384 - - -/* Hooks to custom memory allocation functions. */ -static void *(*alloc_func) (size_t n) = gcry_xmalloc; -static void *(*alloc_secure_func) (size_t n) = gcry_malloc_secure; -static void *(*realloc_func) (void *p, size_t n) = gcry_realloc; -static void *(*calloc_func) (size_t m, size_t n) = gcry_calloc; -static void (*free_func) (void *) = gcry_free; -static int malloc_hooks = 0; -static int secmem_init = 0; - -/* Global settings for the logging. */ -static cdk_log_fnc_t log_handler = NULL; -static void *log_handler_value = NULL; -static int log_level = CDK_LOG_NONE; - +#define DEFAULT_DIGEST_ALGO GNUTLS_DIG_SHA256 /** * cdk_strerror: @@ -110,307 +90,6 @@ cdk_strerror (int ec) return NULL; } - -static void -out_of_core (size_t n) -{ - fprintf (stderr, "\n ** fatal error: out of memory (%d bytes) **\n", n); -} - - -/** - * cdk_set_malloc_hooks: - * @new_alloc_func: malloc replacement - * @new_alloc_secure_func: secure malloc replacement - * @new_realloc_func: realloc replacement - * @new_calloc_func: calloc replacement - * @new_free_func: free replacement - * - * Set private memory hooks for the library. - */ -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 *)) -{ - alloc_func = new_alloc_func; - alloc_secure_func = new_alloc_secure_func; - realloc_func = new_realloc_func; - calloc_func = new_calloc_func; - free_func = new_free_func; - malloc_hooks = 1; -} - - -/** - * cdk_malloc_hook_initialized: - * - * Return if the malloc hooks are already initialized. - **/ -int -cdk_malloc_hook_initialized (void) -{ - return malloc_hooks; -} - - -void* -cdk_malloc (size_t size) -{ - void *p = alloc_func (size); - if (!p) - out_of_core (size); - return p; -} - - -/** - * cdk_calloc: - * @n: amount of elements - * @m: size of one element - * - * Safe wrapper around the c-function calloc. - **/ -void* -cdk_calloc (size_t n, size_t m) -{ - void * p = calloc_func (n, m); - if (!p) - out_of_core (m); - return p; -} - - -/* Things which need to be done after the secure memory initialisation. */ -static void -_secmem_finish (void) -{ - gcry_control (GCRYCTL_DROP_PRIVS); -} - - -/* Initialize the secure memory. */ -static void -_secmem_init (size_t size) -{ - if (secmem_init == 1) - return; - if (size >= SECMEM_SIZE) - size = SECMEM_SIZE; - - /* Check if no other library has already initialized gcrypt. */ - if (!gcry_control (GCRYCTL_ANY_INITIALIZATION_P)) - { - _cdk_log_debug ("init: libgcrypt initialize.\n"); - gcry_control (GCRYCTL_INIT_SECMEM, size, 0); - gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); - gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0); - secmem_init = 1; - } -} - - -/* Things which needs to be done to deinit the secure memory. */ -static void -_secmem_end (void) -{ - gcry_control (GCRYCTL_TERM_SECMEM); - secmem_init = 0; -} - - -/* The Windows system needs to startup the Winsock interface first - before we can use any socket related function. */ -#ifdef _WIN32 -static void -init_sockets (void) -{ - static int initialized = 0; - WSADATA wsdata; - - if (initialized) - return; - if (WSAStartup (0x202, &wsdata)) - _cdk_log_debug ("winsock init failed.\n"); - - initialized = 1; -} - -static void -deinit_sockets (void) -{ - WSACleanup (); -} -#else -void init_sockets (void) {} -void deinit_sockets (void) {} -#endif - - -/** - * cdk_lib_startup: - * - * Prepare the internal structures of the library. - * This function should be called before any other CDK function. - */ -void -cdk_lib_startup (void) -{ - _secmem_init (SECMEM_SIZE); - _secmem_finish (); - init_sockets (); -} - - -/** - * cdk_lib_shutdown: - * - * Shutdown the library and free all internal and globally used - * memory and structures. This function should be called in the - * exit handler of the calling program. - */ -void -cdk_lib_shutdown (void) -{ - deinit_sockets (); - _secmem_end (); -} - -/** - * cdk_salloc: - * @size: how much bytes should be allocated. - * @clear: shall the buffer cleared after the allocation? - * - * Allocated the requested amount of bytes in 'secure' memory. - */ -void* -cdk_salloc (size_t size, int clear) -{ - void *p; - - if (!secmem_init) - _secmem_init (SECMEM_SIZE); - - p = alloc_secure_func (size); - if (!p) - out_of_core (size); - if (clear) - memset (p, 0, size); - return p; -} - - -void * -cdk_realloc (void *ptr, size_t size) -{ - void * p = realloc_func (ptr, size); - if (!p) - out_of_core (size); - return p; -} - - -char * -cdk_strdup (const char * ptr) -{ - char * p = cdk_malloc (strlen (ptr) + 1); - if (p) - strcpy (p, ptr); - return p; -} - - -void -cdk_free (void * ptr) -{ - if (ptr) - free_func (ptr); -} - - -/* Internal logging routine. */ -static void -_cdk_logv (int level, const char *fmt, va_list arg_ptr) -{ - - if (log_handler) - log_handler (log_handler_value, level, fmt, arg_ptr); - else - { - if (level == CDK_LOG_NONE) - return; - if (level == CDK_LOG_DEBUG) - fputs ("DBG: ", stderr); - vfprintf (stderr, fmt, arg_ptr); - } -} - - -/** - * cdk_set_log_handler: - * @logfnc: the function pointer - * @opaque: a private values for the function - * - * Set a custom handler for logging. - **/ -void -cdk_set_log_handler (cdk_log_fnc_t logfnc, void *opaque) -{ - log_handler = logfnc; - log_handler_value = opaque; -} - - -/** - * cdk_set_log_level: - * @lvl: the level - * - * Set the verbosity level. - **/ -void -cdk_set_log_level (int level) -{ - log_level = level; -} - - -/* Return the current log level of the lib. */ -int -_cdk_get_log_level (void) -{ - return log_level; -} - - -void -_cdk_log_info (const char *fmt, ...) -{ - va_list arg; - - if (log_level == CDK_LOG_NONE) - return; - va_start (arg, fmt); - _cdk_logv (CDK_LOG_INFO, fmt, arg); - va_end (arg); -} - - -void -_cdk_log_debug (const char *fmt, ...) -{ - va_list arg; - - if (log_level < CDK_LOG_DEBUG) - return; - va_start (arg, fmt); - _cdk_logv (CDK_LOG_DEBUG, fmt, arg); - va_end (arg); -} - - /* Use the passphrase callback in the handle HD or return NULL if there is no valid callback. */ char* @@ -423,35 +102,22 @@ _cdk_passphrase_get (cdk_ctx_t hd, const char *prompt) static void -handle_set_cipher (cdk_ctx_t hd, int cipher) -{ - if (!hd) - return; - if (gcry_cipher_test_algo (cipher)) - cipher = DEFAULT_CIPHER_ALGO; - hd->cipher_algo = cipher; -} - - -static void handle_set_digest (cdk_ctx_t hd, int digest) { if (!hd) return; - if (gcry_md_test_algo (digest)) + if (_gnutls_hash_get_algo_len (digest) <= 0) digest = DEFAULT_DIGEST_ALGO; hd->digest_algo = digest; } static void -handle_set_s2k (cdk_ctx_t hd, int mode, int digest, int cipher) +handle_set_s2k (cdk_ctx_t hd, int mode, int digest) { if (!hd) return; - if (gcry_cipher_test_algo (cipher)) - cipher = DEFAULT_CIPHER_ALGO; - if (gcry_md_test_algo (digest)) + if (_gnutls_hash_get_algo_len (digest) <= 0) digest = DEFAULT_DIGEST_ALGO; if (mode != CDK_S2K_SIMPLE && mode != CDK_S2K_SALTED && @@ -511,13 +177,6 @@ cdk_handle_control (cdk_ctx_t hd, int action, int cmd, ...) val = hd->opt.armor; break; - case CDK_CTL_CIPHER: - if (set) - handle_set_cipher (hd, va_arg (arg_ptr, int)); - else - val = hd->cipher_algo; - break; - case CDK_CTL_DIGEST: if (set) handle_set_digest( hd, va_arg( arg_ptr, int ) ); @@ -547,8 +206,7 @@ cdk_handle_control (cdk_ctx_t hd, int action, int cmd, ...) if( set ) { int mode = va_arg( arg_ptr, int ); int digest = va_arg( arg_ptr, int ); - int cipher = va_arg( arg_ptr, int ); - handle_set_s2k( hd, mode, digest, cipher ); + handle_set_s2k( hd, mode, digest); } else val = hd->_s2k.mode; @@ -609,7 +267,6 @@ cdk_handle_new (cdk_ctx_t *r_ctx) c->opt.textmode = 0; c->digest_algo = DEFAULT_DIGEST_ALGO; - c->cipher_algo = DEFAULT_CIPHER_ALGO; c->compress.algo = CDK_COMPRESS_ZIP; c->compress.level = 6; @@ -744,6 +401,5 @@ cdk_handle_free (cdk_ctx_t hd) cdk_keydb_free (hd->db.sec); hd->db.pub = hd->db.sec = NULL; } - cdk_free (hd->dek); cdk_free (hd); } diff --git a/lib/opencdk/main.h b/lib/opencdk/main.h index ae9de7bf16..6ff4176f26 100644 --- a/lib/opencdk/main.h +++ b/lib/opencdk/main.h @@ -24,9 +24,23 @@ #ifndef CDK_MAIN_H #define CDK_MAIN_H -#include <gcrypt.h> #include "types.h" +#define _cdk_log_debug _gnutls_debug_log +#define _cdk_log_info _gnutls_x509_log +#define _cdk_get_log_level() _gnutls_log_level + +#define cdk_malloc gnutls_malloc +#define cdk_free gnutls_free +#define cdk_calloc gnutls_calloc +#define cdk_realloc gnutls_realloc_fast +#define cdk_strdup gnutls_strdup +#define cdk_salloc gnutls_secure_calloc + +#define map_gnutls_error _cdk_map_gnutls_error + +cdk_error_t map_gnutls_error(int err); + /* The general size of a buffer for the variou modules. */ #define BUFSIZE 8192 @@ -58,9 +72,9 @@ #define DEBUG_PKT (_cdk_get_log_level () == (CDK_LOG_DEBUG+1)) /* Helper to find out if a key has the requested capability. */ -#define KEY_CAN_ENCRYPT(a) (_cdk_pk_algo_usage ((a)) & CDK_KEY_USG_ENCR) -#define KEY_CAN_SIGN(a) (_cdk_pk_algo_usage ((a)) & CDK_KEY_USG_SIGN) -#define KEY_CAN_AUTH(a) (_cdk_pk_algo_usage ((a)) & CDK_KEY_USG_AUTH) +#define KEY_CAN_ENCRYPT(a) ((_cdk_pk_algo_usage ((a))) & CDK_KEY_USG_ENCR) +#define KEY_CAN_SIGN(a) ((_cdk_pk_algo_usage ((a))) & CDK_KEY_USG_SIGN) +#define KEY_CAN_AUTH(a) ((_cdk_pk_algo_usage ((a))) & CDK_KEY_USG_AUTH) /* Helper macro to make sure the buffer is overwritten. */ #define wipemem(_ptr,_len) do { \ @@ -77,9 +91,6 @@ const char * _cdk_armor_get_lineend (void); /*-- main.c --*/ -int _cdk_get_log_level (void); -void _cdk_log_info (const char * fmt, ...); -void _cdk_log_debug (const char * fmt, ...); char * _cdk_passphrase_get (cdk_ctx_t hd, const char *prompt); /*-- misc.c --*/ @@ -87,8 +98,6 @@ int _cdk_check_args( int overwrite, const char * in, const char * out ); u32 _cdk_buftou32 (const byte * buf); void _cdk_u32tobuf (u32 u, byte * buf); const char *_cdk_memistr (const char * buf, size_t buflen, const char * sub); -cdk_error_t _cdk_map_gcry_error (gcry_error_t err); -#define map_gcry_error(err) _cdk_map_gcry_error (err) /* Helper to provide case insentensive strstr version. */ #define stristr(haystack, needle) \ @@ -98,7 +107,7 @@ cdk_error_t _cdk_map_gcry_error (gcry_error_t err); cdk_error_t _cdk_proc_packets (cdk_ctx_t hd, cdk_stream_t inp, cdk_stream_t data, const char *output, cdk_stream_t outstream, - gcry_md_hd_t md); + digest_hd_st*md); cdk_error_t _cdk_pkt_write2 (cdk_stream_t out, int pkttype, void *pktctx); /*-- pubkey.c --*/ @@ -115,10 +124,10 @@ void _cdk_pkt_detach_free (cdk_packet_t pkt, int *r_pkttype, void **ctx); /*-- sig-check.c --*/ cdk_error_t _cdk_sig_check (cdk_pkt_pubkey_t pk, cdk_pkt_signature_t sig, - gcry_md_hd_t digest, int * r_expired); -cdk_error_t _cdk_hash_sig_data (cdk_pkt_signature_t sig, gcry_md_hd_t hd); -cdk_error_t _cdk_hash_userid (cdk_pkt_userid_t uid, int sig_version, gcry_md_hd_t md); -cdk_error_t _cdk_hash_pubkey (cdk_pkt_pubkey_t pk, gcry_md_hd_t md, + digest_hd_st*digest, int * r_expired); +cdk_error_t _cdk_hash_sig_data (cdk_pkt_signature_t sig, digest_hd_st*hd); +cdk_error_t _cdk_hash_userid (cdk_pkt_userid_t uid, int sig_version, digest_hd_st*md); +cdk_error_t _cdk_hash_pubkey (cdk_pkt_pubkey_t pk, digest_hd_st *md, int use_fpr); cdk_error_t _cdk_pk_check_sig (cdk_keydb_hd_t hd, cdk_kbnode_t knode, @@ -149,7 +158,7 @@ int _cdk_sig_hash_for (cdk_pkt_pubkey_t pk); void _cdk_trim_string (char * s, int canon); cdk_error_t _cdk_sig_create (cdk_pkt_pubkey_t pk, cdk_pkt_signature_t sig); cdk_error_t _cdk_sig_complete (cdk_pkt_signature_t sig, cdk_pkt_seckey_t sk, - gcry_md_hd_t hd); + digest_hd_st *hd); /*-- stream.c --*/ void _cdk_stream_set_compress_algo (cdk_stream_t s, int algo); @@ -180,12 +189,12 @@ cdk_error_t _cdk_pkt_write_fp( FILE * out, cdk_packet_t pkt ); /*-- seskey.c --*/ cdk_error_t _cdk_s2k_copy (cdk_s2k_t *r_dst, cdk_s2k_t src); - -cdk_error_t cdk_dek_encode_pkcs1 (cdk_dek_t dek, size_t nbits, - gcry_mpi_t *r_enc); -cdk_error_t cdk_dek_decode_pkcs1 (cdk_dek_t * ret_dek, gcry_mpi_t esk); -cdk_error_t cdk_dek_extract (cdk_dek_t * ret_dek, cdk_ctx_t hd, - cdk_pkt_pubkey_enc_t enc, - cdk_pkt_seckey_t sk ); +#define _cdk_pub_algo_to_pgp(algo) (algo) +#define _pgp_pub_algo_to_cdk(algo) (algo) +int _gnutls_hash_algo_to_pgp(int algo); +int _pgp_hash_algo_to_gnutls(int algo); +int _gnutls_cipher_to_pgp(int cipher); +int _pgp_cipher_to_gnutls(int cipher); + #endif /* CDK_MAIN_H */ diff --git a/lib/opencdk/misc.c b/lib/opencdk/misc.c index 97302475a7..be8e074f9b 100644 --- a/lib/opencdk/misc.c +++ b/lib/opencdk/misc.c @@ -31,6 +31,7 @@ #include "opencdk.h" #include "main.h" +#include "../random.h" u32 @@ -149,29 +150,16 @@ _cdk_memistr (const char *buf, size_t buflen, const char *sub) return NULL; } - -/* Map the gcrypt error to a valid opencdk error constant. */ cdk_error_t -_cdk_map_gcry_error (gcry_error_t err) +_cdk_map_gnutls_error (int err) { - /* FIXME: We need to catch them all. */ - switch (gpg_err_code (err)) + switch (err) { - case GPG_ERR_NO_ERROR: return CDK_Success; - case GPG_ERR_INV_VALUE: return CDK_Inv_Value; - case GPG_ERR_GENERAL: return CDK_General_Error; - case GPG_ERR_INV_PACKET: return CDK_Inv_Packet; - case GPG_ERR_TOO_SHORT: return CDK_Too_Short; - case GPG_ERR_TOO_LARGE: return CDK_Inv_Value; - case GPG_ERR_NO_PUBKEY: - case GPG_ERR_NO_SECKEY: return CDK_Error_No_Key; - case GPG_ERR_BAD_SIGNATURE: return CDK_Bad_Sig; - case GPG_ERR_NO_DATA: return CDK_No_Data; + case 0: return CDK_Success; + case GNUTLS_E_INVALID_REQUEST: return CDK_Inv_Value; default: - break; + return CDK_General_Error; } - - return (cdk_error_t)err; } @@ -209,7 +197,7 @@ _cdk_check_args (int overwrite, const char *in, const char *out) #include <fcntl.h> FILE * -my_tmpfile (void) +_cdk_tmpfile (void) { /* Because the tmpfile() version of wine is not really useful, we implement our own version to avoid problems with 'make check'. */ @@ -218,7 +206,7 @@ my_tmpfile (void) FILE *fp; int fd, i; - gcry_create_nonce (rnd, DIM (rnd)); + _gnutls_rnd( GNUTLS_RND_NONCE, rnd, DIM(rnd)); for (i=0; i < DIM (rnd)-1; i++) { char c = letters[(unsigned char)rnd[i] % 26]; @@ -243,8 +231,114 @@ my_tmpfile (void) } #else FILE* -my_tmpfile (void) +_cdk_tmpfile (void) { return tmpfile (); } #endif + +int _gnutls_hash_algo_to_pgp(int algo) +{ + switch(algo) { + case GNUTLS_DIG_MD5: + return 0x01; + case GNUTLS_DIG_MD2: + return 0x05; + case GNUTLS_DIG_SHA1: + return 0x02; + case GNUTLS_DIG_RMD160: + return 0x03; + case GNUTLS_DIG_SHA256: + return 0x08; + case GNUTLS_DIG_SHA384: + return 0x09; + case GNUTLS_DIG_SHA512: + return 0x0A; + case GNUTLS_DIG_SHA224: + return 0x0B; + default: + gnutls_assert(); + return 0x00; + } +} + +int _pgp_hash_algo_to_gnutls(int algo) +{ + switch(algo) { + case 0x01: + return GNUTLS_DIG_MD5; + case 0x02: + return GNUTLS_DIG_SHA1; + case 0x03: + return GNUTLS_DIG_RMD160; + case 0x05: + return GNUTLS_DIG_MD2; + case 0x08: + return GNUTLS_DIG_SHA256; + case 0x09: + return GNUTLS_DIG_SHA384; + case 0x0A: + return GNUTLS_DIG_SHA512; + case 0x0B: + return GNUTLS_DIG_SHA224; + default: + gnutls_assert(); + return GNUTLS_DIG_NULL; + } +} + +int _pgp_cipher_to_gnutls(int cipher) +{ + switch (cipher) { + case 1: + return GNUTLS_CIPHER_IDEA_PGP_CFB; + case 2: + return GNUTLS_CIPHER_3DES_PGP_CFB; + case 3: + return GNUTLS_CIPHER_CAST5_PGP_CFB; + case 4: + return GNUTLS_CIPHER_BLOWFISH_PGP_CFB; + case 5: + return GNUTLS_CIPHER_SAFER_SK128_PGP_CFB; + case 7: + return GNUTLS_CIPHER_AES128_PGP_CFB; + case 8: + return GNUTLS_CIPHER_AES192_PGP_CFB; + case 9: + return GNUTLS_CIPHER_AES256_PGP_CFB; + case 10: + return GNUTLS_CIPHER_TWOFISH_PGP_CFB; + + default: + gnutls_assert(); + return GNUTLS_CIPHER_NULL; + } +} + +int _gnutls_cipher_to_pgp(int cipher) +{ + switch (cipher) { + + case GNUTLS_CIPHER_IDEA_PGP_CFB: + return 1; + case GNUTLS_CIPHER_3DES_PGP_CFB: + return 2; + case GNUTLS_CIPHER_CAST5_PGP_CFB: + return 3; + case GNUTLS_CIPHER_BLOWFISH_PGP_CFB: + return 4; + case GNUTLS_CIPHER_SAFER_SK128_PGP_CFB: + return 5; + case GNUTLS_CIPHER_AES128_PGP_CFB: + return 7; + case GNUTLS_CIPHER_AES192_PGP_CFB: + return 8; + case GNUTLS_CIPHER_AES256_PGP_CFB: + return 9; + case GNUTLS_CIPHER_TWOFISH_PGP_CFB: + return 10; + default: + gnutls_assert(); + return 0; + } +} diff --git a/lib/opencdk/new-packet.c b/lib/opencdk/new-packet.c index 5bd452e3e2..497ac9f8df 100644 --- a/lib/opencdk/new-packet.c +++ b/lib/opencdk/new-packet.c @@ -35,12 +35,11 @@ /* Release an array of MPI values. */ void -_cdk_free_mpibuf (size_t n, gcry_mpi_t *array) +_cdk_free_mpibuf (size_t n, bigint_t *array) { while (n--) { - gcry_mpi_release (array[n]); - array[n] = NULL; + _gnutls_mpi_release (&array[n]); } } @@ -67,16 +66,6 @@ cdk_pkt_new (cdk_packet_t *r_pkt) static void -free_symkey_enc (cdk_pkt_symkey_enc_t enc) -{ - if (!enc) - return; - cdk_s2k_free (enc->s2k); - cdk_free (enc); -} - - -static void free_pubkey_enc (cdk_pkt_pubkey_enc_t enc) { size_t nenc; @@ -179,21 +168,6 @@ cdk_sk_release (cdk_seckey_t sk) } -static void -free_encrypted (cdk_pkt_encrypted_t enc) -{ - if (!enc) - return; - - /* This is just a reference for the filters to know where - the encrypted data starts and to read from the sream. It - us closed elsewhere and to close it here would double close it. */ - /*cdk_stream_close (enc->buf);*/ - enc->buf = NULL; - cdk_free (enc); -} - - /* Detach the openpgp packet from the packet structure and release the packet structure itself. */ void @@ -242,10 +216,7 @@ cdk_pkt_free (cdk_packet_t pkt) case CDK_PKT_SECRET_SUBKEY: cdk_sk_release (pkt->pkt.secret_key); break; case CDK_PKT_SIGNATURE : _cdk_free_signature (pkt->pkt.signature);break; case CDK_PKT_PUBKEY_ENC : free_pubkey_enc (pkt->pkt.pubkey_enc); break; - case CDK_PKT_SYMKEY_ENC : free_symkey_enc (pkt->pkt.symkey_enc); break; case CDK_PKT_MDC : cdk_free (pkt->pkt.mdc); break; - case CDK_PKT_ENCRYPTED : - case CDK_PKT_ENCRYPTED_MDC: free_encrypted (pkt->pkt.encrypted); break; case CDK_PKT_ONEPASS_SIG : cdk_free (pkt->pkt.onepass_sig); break; case CDK_PKT_LITERAL : free_literal (pkt->pkt.literal); break; case CDK_PKT_COMPRESSED : cdk_free (pkt->pkt.compressed); break; @@ -283,7 +254,7 @@ cdk_pkt_release (cdk_packet_t pkt) * Allocate a new packet structure with the given packet type. **/ cdk_error_t -cdk_pkt_alloc (cdk_packet_t *r_pkt, int pkttype) +cdk_pkt_alloc (cdk_packet_t *r_pkt, cdk_packet_type_t pkttype) { cdk_packet_t pkt; int rc; @@ -325,12 +296,6 @@ cdk_pkt_alloc (cdk_packet_t *r_pkt, int pkttype) return CDK_Out_Of_Core; break; - case CDK_PKT_SYMKEY_ENC: - pkt->pkt.symkey_enc = cdk_calloc (1, sizeof *pkt->pkt.symkey_enc); - if (!pkt->pkt.symkey_enc) - return CDK_Out_Of_Core; - break; - case CDK_PKT_PUBKEY_ENC: pkt->pkt.pubkey_enc = cdk_calloc (1, sizeof *pkt->pkt.pubkey_enc); if (!pkt->pkt.pubkey_enc) @@ -343,13 +308,6 @@ cdk_pkt_alloc (cdk_packet_t *r_pkt, int pkttype) return CDK_Out_Of_Core; break; - case CDK_PKT_ENCRYPTED_MDC: - case CDK_PKT_ENCRYPTED: - pkt->pkt.symkey_enc = cdk_calloc (1, sizeof *pkt->pkt.symkey_enc); - if (!pkt->pkt.symkey_enc) - return CDK_Out_Of_Core; - break; - case CDK_PKT_ONEPASS_SIG: pkt->pkt.onepass_sig = cdk_calloc (1, sizeof *pkt->pkt.onepass_sig); if (!pkt->pkt.onepass_sig) @@ -437,7 +395,7 @@ _cdk_copy_pubkey (cdk_pkt_pubkey_t* dst, cdk_pkt_pubkey_t src) if (src->prefs) k->prefs = _cdk_copy_prefs (src->prefs); for (i = 0; i < cdk_pk_get_npkey (src->pubkey_algo); i++) - k->mpi[i] = gcry_mpi_copy (src->mpi[i]); + k->mpi[i] = _gnutls_mpi_copy (src->mpi[i]); *dst = k; return 0; @@ -469,11 +427,9 @@ _cdk_copy_seckey (cdk_pkt_seckey_t* dst, cdk_pkt_seckey_t src) } _cdk_s2k_copy (&k->protect.s2k, src->protect.s2k); - for (i = 0; i < cdk_pk_get_nskey (src->pubkey_algo); i++) { - k->mpi[i] = gcry_mpi_copy (src->mpi[i]); - gcry_mpi_set_flag (k->mpi[i], GCRYMPI_FLAG_SECURE); + k->mpi[i] = _gnutls_mpi_copy (src->mpi[i]); } *dst = k; @@ -489,7 +445,7 @@ _cdk_copy_pk_to_sk (cdk_pkt_pubkey_t pk, cdk_pkt_seckey_t sk) sk->version = pk->version; sk->expiredate = pk->expiredate; - sk->pubkey_algo = pk->pubkey_algo; + sk->pubkey_algo = _pgp_pub_algo_to_cdk(pk->pubkey_algo); sk->has_expired = pk->has_expired; sk->is_revoked = pk->is_revoked; sk->main_keyid[0] = pk->main_keyid[0]; @@ -539,7 +495,7 @@ _cdk_pubkey_compare (cdk_pkt_pubkey_t a, cdk_pkt_pubkey_t b) for (i = 0; i < na; i++) { - if (gcry_mpi_cmp (a->mpi[i], b->mpi[i])) + if (_gnutls_mpi_cmp (a->mpi[i], b->mpi[i])) return -1; } diff --git a/lib/opencdk/opencdk.h b/lib/opencdk/opencdk.h index df5ea06d76..9df17ffa9f 100644 --- a/lib/opencdk/opencdk.h +++ b/lib/opencdk/opencdk.h @@ -27,7 +27,11 @@ #include <stddef.h> /* for size_t */ #include <stdarg.h> -#include <gcrypt.h> +#include <gnutls_int.h> +#include <gnutls_mem.h> +#include <gnutls/gnutls.h> +#include <gnutls_errors.h> +#include <gnutls_hash_int.h> /* The OpenCDK version as a string. */ #define OPENCDK_VERSION "0.6.6" @@ -59,10 +63,6 @@ typedef struct cdk_strlist_s *cdk_strlist_t; struct cdk_listkey_s; typedef struct cdk_listkey_s *cdk_listkey_t; -/* Opaque Data Encryption Key (DEK) context. */ -struct cdk_dek_s; -typedef struct cdk_dek_s *cdk_dek_t; - /* Opaque String to Key (S2K) handle. */ struct cdk_s2k_s; typedef struct cdk_s2k_s *cdk_s2k_t; @@ -103,7 +103,7 @@ struct cdk_desig_revoker_s; typedef struct cdk_desig_revoker_s *cdk_desig_revoker_t; /* Alias for backward compatibility. */ -typedef gcry_mpi_t cdk_mpi_t; +typedef bigint_t cdk_mpi_t; /* All valid error constants. */ @@ -144,7 +144,6 @@ 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_CIPHER = 11, /* Option to set the cipher 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. */ @@ -172,9 +171,9 @@ enum cdk_compress_algo_t { 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. */ @@ -182,34 +181,6 @@ enum cdk_pubkey_algo_t { CDK_PK_DSA = 17 }; - -/* All valid message digest algorithms in OpenPGP. */ -enum cdk_digest_algo_t { - CDK_MD_NONE = 0, - CDK_MD_MD5 = 1, - CDK_MD_SHA1 = 2, - CDK_MD_RMD160 = 3, - CDK_MD_SHA256 = 8, - CDK_MD_SHA384 = 9, - CDK_MD_SHA512 = 10, - CDK_MD_SHA224 = 11 /* This algorithm is NOT available. */ -}; - - -/* All valid symmetric cipher algorithms in OpenPGP */ -enum cdk_cipher_algo_t { - CDK_CIPHER_NONE = 0, - CDK_CIPHER_IDEA = 1, /* This algorithm is NOT available */ - CDK_CIPHER_3DES = 2, - CDK_CIPHER_CAST5 = 3, - CDK_CIPHER_BLOWFISH = 4, - CDK_CIPHER_AES = 7, - CDK_CIPHER_AES192 = 8, - CDK_CIPHER_AES256 = 9, - CDK_CIPHER_TWOFISH = 10 -}; - - /* The valid 'String-To-Key' modes */ enum cdk_s2k_type_t { CDK_S2K_SIMPLE = 0, @@ -217,7 +188,6 @@ enum cdk_s2k_type_t { CDK_S2K_ITERSALTED = 3 }; - /* The different kind of user ID preferences. */ enum cdk_pref_type_t { CDK_PREFTYPE_NONE = 0, @@ -368,13 +338,11 @@ 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_LITERAL = 11, CDK_PKT_RING_TRUST = 12, @@ -382,7 +350,6 @@ typedef enum { 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_type_t; @@ -414,7 +381,7 @@ struct cdk_pkt_signature_s { cdk_subpkt_t hashed; unsigned short unhashed_size; cdk_subpkt_t unhashed; - gcry_mpi_t mpi[MAX_CDK_DATA_PARTS]; + bigint_t mpi[MAX_CDK_DATA_PARTS]; cdk_desig_revoker_t revkeys; struct { unsigned exportable:1; @@ -454,7 +421,7 @@ struct cdk_pkt_pubkey_s { unsigned int main_keyid[2]; unsigned int timestamp; unsigned int expiredate; - gcry_mpi_t mpi[MAX_CDK_PK_PARTS]; + bigint_t mpi[MAX_CDK_PK_PARTS]; unsigned is_revoked:1; unsigned is_invalid:1; unsigned has_expired:1; @@ -486,7 +453,7 @@ struct cdk_pkt_seckey_s { unsigned char ivlen; } protect; unsigned short csum; - gcry_mpi_t mpi[MAX_CDK_PK_PARTS]; + bigint_t mpi[MAX_CDK_PK_PARTS]; unsigned char * encdata; size_t enclen; unsigned char is_protected; @@ -516,21 +483,10 @@ struct cdk_pkt_pubkey_enc_s { unsigned int keyid[2]; int throw_keyid; unsigned char pubkey_algo; - gcry_mpi_t mpi[MAX_CDK_DATA_PARTS]; + bigint_t mpi[MAX_CDK_DATA_PARTS]; }; typedef struct cdk_pkt_pubkey_enc_s * cdk_pkt_pubkey_enc_t; - -struct cdk_pkt_symkey_enc_s { - unsigned char version; - unsigned char cipher_algo; - cdk_s2k_t s2k; - unsigned char seskeylen; - unsigned char seskey[32]; -}; -typedef struct cdk_pkt_symkey_enc_s *cdk_pkt_symkey_enc_t; - - struct cdk_pkt_encrypted_s { unsigned int len; int extralen; @@ -578,7 +534,6 @@ struct cdk_packet_s { cdk_pkt_seckey_t secret_key; cdk_pkt_signature_t signature; cdk_pkt_pubkey_enc_t pubkey_enc; - cdk_pkt_symkey_enc_t symkey_enc; cdk_pkt_compressed_t compressed; cdk_pkt_encrypted_t encrypted; cdk_pkt_literal_t literal; @@ -587,49 +542,9 @@ struct cdk_packet_s { }; typedef struct cdk_packet_s *cdk_packet_t; -/* memory routines */ -typedef void (*cdk_log_fnc_t) (void *, int, const char *, va_list); - -/* Set the log level. */ -void cdk_set_log_level (int lvl); - -/* Set a custom log handler which is used for logging. */ -void cdk_set_log_handler (cdk_log_fnc_t logfnc, void *opaque); - /* Return a human readable error description of the given error coe. */ const char* cdk_strerror (int ec); -/* Allow the user to set custom hooks for memory allocation. - If this function is not used, the standard allocation functions - will be used. Extra care must be taken for the 'secure' alloc - function. */ -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 *)); - -/* Return 1 if the malloc hooks were already set via the function above. */ -int cdk_malloc_hook_initialized (void); - -/* Standard memory wrapper. */ -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); - -/* Startup routines. */ - -/* This function has to be called before any other - CDK function is executed. */ -void cdk_lib_startup (void); - -/* This function should be called before the application exists - to allow the lib to cleanup its internal structures. */ -void cdk_lib_shutdown (void); - /* Session handle routines */ cdk_error_t cdk_handle_new (cdk_ctx_t *r_ctx); void cdk_handle_free (cdk_ctx_t c); @@ -670,10 +585,6 @@ void cdk_handle_set_passphrase_cb (cdk_ctx_t hd, #define cdk_handle_set_blockmode(a, val) \ cdk_handle_control ((a), CDK_CTLF_SET, CDK_CTL_BLOCKMODE_ON, (val)) -/* Set the symmetric cipher for encryption. */ -#define cdk_handle_set_cipher(a, val) \ - cdk_handle_control ((a), CDK_CTLF_SET, CDK_CTL_CIPHER, (val)) - /* Set the digest for the PK signing operation. */ #define cdk_handle_set_digest(a, val) \ cdk_handle_control ((a), CDK_CTLF_SET, CDK_CTL_DIGEST, (val)) @@ -707,7 +618,7 @@ cdk_verify_result_t cdk_handle_verify_get_result (cdk_ctx_t hd); /* 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, int pkttype); +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); @@ -746,12 +657,12 @@ const unsigned char* cdk_key_desig_revoker_walk (cdk_desig_revoker_t root, /* 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, - gcry_mpi_t sk); + 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, - gcry_mpi_t *r_sk); + bigint_t *r_sk); /* Sign the given message digest @MD with the secret key @SK and store the signature in the packet @SIG. */ @@ -813,10 +724,6 @@ unsigned int cdk_sig_get_keyid (cdk_pkt_signature_t sig, void cdk_pk_release (cdk_pubkey_t pk); void cdk_sk_release (cdk_seckey_t sk); -/* Secret key related functions. */ -cdk_error_t cdk_sk_unprotect (cdk_seckey_t sk, const char *pw); -cdk_error_t cdk_sk_protect (cdk_seckey_t sk, const char *pw); - /* 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); @@ -828,36 +735,6 @@ cdk_error_t cdk_seckey_to_sexp (cdk_seckey_t sk, char **sexp, size_t *len); -/* Data Encryption Key (DEK) routines */ -cdk_error_t cdk_dek_new (cdk_dek_t *r_dek); -void cdk_dek_free (cdk_dek_t dek); - -/* Set the symmetric cipher algorithm which shall be used for this - DEK object. */ -cdk_error_t cdk_dek_set_cipher (cdk_dek_t dek, int cipher_algo); - -/* Return the symmetric cipher which is used for this DEK object. */ -cdk_error_t cdk_dek_get_cipher (cdk_dek_t dek, int *r_cipher_algo); - - -/* Set the session key for the given DEK object. - If @KEY and @KEYLEN are both NULL/0, a random key will be generated - and stored in the DEK object. */ -cdk_error_t cdk_dek_set_key (cdk_dek_t dek, const unsigned char *key, - size_t keylen); - -/* Enable the MDC feature for the current DEK object. */ -void cdk_dek_set_mdc_flag (cdk_dek_t dek, int val); - -/* Return if the MDC feature is enabled for the current DEK object.*/ -int cdk_dek_get_mdc_flag (cdk_dek_t dek); - -/* Transform the given passphrase into a DEK. - If @rndsalt is set, a random salt will be generated. */ -cdk_error_t cdk_dek_from_passphrase (cdk_dek_t *ret_dek, int cipher_algo, - cdk_s2k_t s2k, int rndsalt, - const char *passphrase); - /* String to Key routines. */ cdk_error_t cdk_s2k_new (cdk_s2k_t *ret_s2k, int mode, int digest_algo, const unsigned char *salt); @@ -931,8 +808,6 @@ 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_cipher_flag (cdk_stream_t s, cdk_dek_t dek, - int use_mdc); 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); @@ -1035,17 +910,17 @@ cdk_error_t cdk_kbnode_write_to_mem (cdk_kbnode_t node, 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); 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, int pkttype); +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, int pkttype); +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, - int pkttype); -cdk_kbnode_t cdk_kbnode_find_next (cdk_kbnode_t node, int pkttype); -cdk_error_t cdk_kbnode_hash (cdk_kbnode_t node, gcry_md_hd_t md, int is_v4, - int pkttype, int flags); + 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. */ @@ -1066,11 +941,6 @@ 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); -/* Encrypt the given DEK key with the list of public keys given - in @PKL. The result will be written to the stream output @OUT. */ -cdk_error_t cdk_pklist_encrypt (cdk_keylist_t pkl, cdk_dek_t dek, - cdk_stream_t out); - /* Secret key lists */ cdk_error_t cdk_sklist_build (cdk_keylist_t * ret_skl, cdk_keydb_hd_t db, cdk_ctx_t hd, @@ -1078,7 +948,7 @@ cdk_error_t cdk_sklist_build (cdk_keylist_t * ret_skl, 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, - gcry_md_hd_t mdctx, + 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); @@ -1146,38 +1016,6 @@ const char * cdk_check_version (const char * req_version); char* cdk_utf8_encode (const char * string); char* cdk_utf8_decode (const char * string, size_t length, int delim); -/* Try to receive the key, which has the key ID @KEYID, from the - keyserver host @HOST and the port @PORT. */ -cdk_error_t cdk_keyserver_recv_key (const char *host, int port, - const unsigned char *keyid, int kid_type, - cdk_kbnode_t *r_key); - -cdk_error_t cdk_keygen_new (cdk_keygen_ctx_t * r_hd); -void cdk_keygen_free (cdk_keygen_ctx_t hd); - -/* Set the preferences of the given type for the new key. - @ARRAY is an array which list of algorithm IDs. */ -cdk_error_t cdk_keygen_set_prefs (cdk_keygen_ctx_t hd, - enum cdk_pref_type_t type, - const unsigned char * array, size_t n); -cdk_error_t cdk_keygen_set_algo_info (cdk_keygen_ctx_t hd, int type, - int usage, enum cdk_pubkey_algo_t algo, - unsigned int bits); -int cdk_keygen_set_keyserver_flags (cdk_keygen_ctx_t hd, int no_modify, - const char *pref_url); -int cdk_keygen_set_expire_date (cdk_keygen_ctx_t hd, int type, - long timestamp); - -/* Set the user ID specifc parts for the new key. - It is suggested to use a name in the form of - 'First Name' 'Last Name' <email-address@host.domain> */ -void cdk_keygen_set_name (cdk_keygen_ctx_t hd, const char * name); -void cdk_keygen_set_passphrase (cdk_keygen_ctx_t hd, const char * pass); -cdk_error_t cdk_keygen_start (cdk_keygen_ctx_t hd); -cdk_error_t cdk_keygen_save (cdk_keygen_ctx_t hd, - const char * pubf, - const char * secf); - #ifdef __cplusplus } #endif diff --git a/lib/opencdk/packet.h b/lib/opencdk/packet.h index ab0c8a58fb..a2dc7fba07 100644 --- a/lib/opencdk/packet.h +++ b/lib/opencdk/packet.h @@ -33,7 +33,7 @@ struct cdk_kbnode_s }; /*-- new-packet.c --*/ -void _cdk_free_mpibuf (size_t n, gcry_mpi_t *array); +void _cdk_free_mpibuf (size_t n, bigint_t *array); void _cdk_free_userid (cdk_pkt_userid_t uid); void _cdk_free_signature( cdk_pkt_signature_t sig ); cdk_prefitem_t _cdk_copy_prefs( const cdk_prefitem_t prefs ); diff --git a/lib/opencdk/pubkey.c b/lib/opencdk/pubkey.c index acb4117804..0384e00563 100644 --- a/lib/opencdk/pubkey.c +++ b/lib/opencdk/pubkey.c @@ -24,432 +24,43 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <stdio.h> -#include <gcrypt.h> +#include <gnutls_int.h> +#include <gnutls_datum.h> #include "opencdk.h" #include "main.h" #include "packet.h" - -/* Convert the given secret key into a gcrypt SEXP object. */ -static int -seckey_to_sexp (gcry_sexp_t *r_skey, cdk_seckey_t sk) -{ - gcry_sexp_t sexp = NULL; - gcry_mpi_t *mpk = NULL, *msk = NULL; - gcry_error_t err; - cdk_pubkey_t pk; - const char *fmt; - - if (!r_skey || !sk || !sk->pk) - return CDK_Inv_Value; - - pk = sk->pk; - mpk = pk->mpi; - msk = sk->mpi; - - *r_skey = NULL; - if (is_RSA (sk->pubkey_algo)) - { - fmt = "(private-key(openpgp-rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))"; - err = gcry_sexp_build (&sexp, NULL, fmt, mpk[0], mpk[1], - msk[0], msk[1], msk[2], msk[3]); - } - else if (is_ELG (sk->pubkey_algo)) - { - fmt = "(private-key(openpgp-elg(p%m)(g%m)(y%m)(x%m)))"; - err = gcry_sexp_build (&sexp, NULL, fmt, mpk[0], mpk[1], - mpk[2], msk[0]); - } - else if (is_DSA (sk->pubkey_algo)) - { - fmt = "(private-key(openpgp-dsa(p%m)(q%m)(g%m)(y%m)(x%m)))"; - err = gcry_sexp_build (&sexp, NULL, fmt, mpk[0], mpk[1], mpk[2], - mpk[3], msk[0]); - } - else - return CDK_Inv_Algo; - if (err) - return map_gcry_error (err); - *r_skey = sexp; - return 0; -} - - -/* Convert the given public key to a gcrypt SEXP object. */ -static cdk_error_t -pubkey_to_sexp (gcry_sexp_t *r_key_sexp, cdk_pubkey_t pk) -{ - gcry_mpi_t *m; - gcry_error_t err; - const char *fmt = NULL; - cdk_error_t rc = 0; - - if (!r_key_sexp || !pk) - return CDK_Inv_Value; - - m = pk->mpi; - if (is_RSA (pk->pubkey_algo)) - { - fmt = "(public-key(openpgp-rsa(n%m)(e%m)))"; - err = gcry_sexp_build (r_key_sexp, NULL, fmt, m[0], m[1]); - if (err) - rc = map_gcry_error (err); - } - else if (is_ELG (pk->pubkey_algo)) - { - fmt = "(public-key(openpgp-elg(p%m)(g%m)(y%m)))"; - err = gcry_sexp_build (r_key_sexp, NULL, fmt, m[0], m[1], m[2]); - if (err) - rc = map_gcry_error (err); - } - else if (is_DSA (pk->pubkey_algo)) - { - fmt = "(public-key(openpgp-dsa(p%m)(q%m)(g%m)(y%m)))"; - err = gcry_sexp_build (r_key_sexp, NULL, fmt, m[0], m[1], m[2], m[3]); - if (err) - rc = map_gcry_error (err); - } - else - rc = CDK_Inv_Algo; - return rc; -} - - -static cdk_error_t -enckey_to_sexp (gcry_sexp_t *r_sexp, gcry_mpi_t esk) -{ - gcry_error_t err; - - if (!r_sexp || !esk) - return CDK_Inv_Value; - err = gcry_sexp_build (r_sexp, NULL, "%m", esk); - if (err) - return map_gcry_error (err); - return 0; -} - - -static cdk_error_t -digest_to_sexp (gcry_sexp_t *r_md_sexp, int digest_algo, - const byte *md, size_t mdlen) -{ - gcry_mpi_t m; - gcry_error_t err; - - if (!r_md_sexp || !md) - return CDK_Inv_Value; - - if (!mdlen) - mdlen = gcry_md_get_algo_dlen (digest_algo); - if (!mdlen) - return CDK_Inv_Algo; - - err = gcry_mpi_scan (&m, GCRYMPI_FMT_USG, md, mdlen, &mdlen); - if (err) - return map_gcry_error (err); - - err = gcry_sexp_build (r_md_sexp, NULL, "%m", m); - gcry_mpi_release (m); - if (err) - return map_gcry_error (err); - return 0; -} - - -static cdk_error_t -sexp_to_mpi (gcry_sexp_t sexp, const char *val, gcry_mpi_t *ret_buf) -{ - gcry_sexp_t list; - - if (!sexp || !val || !ret_buf) - return CDK_Inv_Value; - - list = gcry_sexp_find_token (sexp, val, 0); - if (!list) - return CDK_Inv_Value; - - *ret_buf = gcry_sexp_nth_mpi (list, 1, 0); - gcry_sexp_release (list); - if (! *ret_buf) - return CDK_Inv_Value; - return 0; -} - - -static cdk_error_t -sexp_to_sig (cdk_pkt_signature_t sig, gcry_sexp_t sexp) -{ - if (!sig || !sexp) - return CDK_Inv_Value; - - /* ElGamal signatures are not supported any longer. */ - if (is_ELG (sig->pubkey_algo)) - { - _cdk_log_debug ("sexp_to_sig: unsupported signature type (ElGamal)\n"); - return CDK_Not_Implemented; - } - - if (is_RSA (sig->pubkey_algo)) - return sexp_to_mpi (sexp, "s", &sig->mpi[0]); - else if (is_DSA (sig->pubkey_algo)) - { - cdk_error_t rc; - - rc = sexp_to_mpi (sexp, "r", &sig->mpi[0]); - if (!rc) - rc = sexp_to_mpi (sexp, "s", &sig->mpi[1]); - return rc; - } - return CDK_Inv_Algo; -} - - +/* This function gets the signature parameters and encodes + * them into a way for _gnutls_pk_verify to use. + */ static cdk_error_t -sig_to_sexp (gcry_sexp_t *r_sig_sexp, cdk_pkt_signature_t sig) +sig_to_datum (gnutls_datum_t *r_sig, cdk_pkt_signature_t sig) { - gcry_error_t err; + int err; cdk_error_t rc; - const char *fmt; - if (!r_sig_sexp || !sig) + if (!r_sig || !sig) return CDK_Inv_Value; - if (is_ELG (sig->pubkey_algo)) - return CDK_Not_Implemented; rc = 0; if (is_RSA (sig->pubkey_algo)) { - fmt = "(sig-val(openpgp-rsa(s%m)))"; - err = gcry_sexp_build (r_sig_sexp, NULL, fmt, sig->mpi[0]); - if (err) - rc = map_gcry_error (err); + err = _gnutls_mpi_dprint( sig->mpi[0], r_sig); + if (err < 0) + rc = map_gnutls_error (err); } else if (is_DSA (sig->pubkey_algo)) { - fmt = "(sig-val(openpgp-dsa(r%m)(s%m)))"; - err = gcry_sexp_build (r_sig_sexp, NULL, fmt, sig->mpi[0], sig->mpi[1]); - if (err) - rc = map_gcry_error (err); + err = _gnutls_encode_ber_rs( r_sig, sig->mpi[0], sig->mpi[1]); + if (err < 0) + rc = map_gnutls_error (err); } else rc = CDK_Inv_Algo; return rc; } - -static cdk_error_t -sexp_to_pubenc (cdk_pkt_pubkey_enc_t enc, gcry_sexp_t sexp) -{ - if (!sexp || !enc) - return CDK_Inv_Value; - - if (is_RSA (enc->pubkey_algo)) - return sexp_to_mpi (sexp, "a", &enc->mpi[0]); - else if (is_ELG (enc->pubkey_algo)) - { - cdk_error_t rc = sexp_to_mpi (sexp, "a", &enc->mpi[0]); - if (!rc) - rc = sexp_to_mpi (sexp, "b", &enc->mpi[1]); - return rc; - } - return CDK_Inv_Algo; -} - - -static cdk_error_t -pubenc_to_sexp (gcry_sexp_t * r_sexp, cdk_pkt_pubkey_enc_t enc) -{ - gcry_sexp_t sexp = NULL; - gcry_error_t err; - const char *fmt; - - if (!r_sexp || !enc) - return CDK_Inv_Value; - - *r_sexp = NULL; - if (is_RSA (enc->pubkey_algo)) - { - fmt = "(enc-val(openpgp-rsa((a%m))))"; - err = gcry_sexp_build (&sexp, NULL, fmt, enc->mpi[0]); - } - else if (is_ELG (enc->pubkey_algo)) - { - fmt = "(enc-val(openpgp-elg((a%m)(b%m))))"; - err = gcry_sexp_build (&sexp, NULL, fmt, enc->mpi[0], enc->mpi[1]); - } - else - return CDK_Inv_Algo; - if (err) - return map_gcry_error (err); - *r_sexp = sexp; - return 0; -} - - -static int -is_unprotected (cdk_seckey_t sk) -{ - if (sk->is_protected && !sk->mpi[0]) - return 0; - return 1; -} - - -/** - * cdk_pk_encrypt: - * @pk: the public key - * @pke: the public key encrypted packet - * @esk: the actual session key - * - * Encrypt the session key in @esk and write its encrypted content - * into the @pke struct. - **/ -cdk_error_t -cdk_pk_encrypt (cdk_pubkey_t pk, cdk_pkt_pubkey_enc_t pke, - gcry_mpi_t esk) -{ - gcry_sexp_t s_data = NULL, s_pkey = NULL, s_ciph = NULL; - gcry_error_t err; - cdk_error_t rc; - - if (!pk || !esk || !pke) - return CDK_Inv_Value; - - if (!KEY_CAN_ENCRYPT (pk->pubkey_algo)) - return CDK_Inv_Algo; - - rc = enckey_to_sexp (&s_data, esk); - if (!rc) - rc = pubkey_to_sexp (&s_pkey, pk); - if (!rc) - { - err = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); - if (err) - return map_gcry_error (err); - } - if (!rc) - rc = sexp_to_pubenc (pke, s_ciph); - - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - gcry_sexp_release (s_ciph); - return rc; -} - - -/** - * cdk_pk_decrypt: - * @sk: the secret key - * @pke: public key encrypted packet - * @r_sk: the object to store the plain session key - * - * Decrypt the encrypted session key from @pke into @r_sk. - **/ -cdk_error_t -cdk_pk_decrypt (cdk_seckey_t sk, cdk_pkt_pubkey_enc_t pke, - gcry_mpi_t *r_sk) -{ - gcry_sexp_t s_data = NULL, s_skey = NULL, s_plain = NULL; - cdk_error_t rc; - gcry_error_t err; - - if (!sk || !r_sk || !pke) - return CDK_Inv_Value; - - if (!is_unprotected (sk)) - return CDK_Inv_Mode; - - *r_sk = NULL; - rc = seckey_to_sexp (&s_skey, sk); - if (rc) - return rc; - - rc = pubenc_to_sexp (&s_data, pke); - if (rc) - { - gcry_sexp_release (s_skey); - return rc; - } - - err = gcry_pk_decrypt (&s_plain, s_data, s_skey); - if (err) - rc = map_gcry_error (err); - else - *r_sk = gcry_sexp_nth_mpi (s_plain, 0, 0); - - gcry_sexp_release (s_data); - gcry_sexp_release (s_skey); - gcry_sexp_release (s_plain); - return rc; -} - - -/** - * cdk_pk_sign: - * @sk: secret key - * @sig: signature - * @md: the message digest - * - * Sign the message digest from @md and write the result into @sig. - **/ -cdk_error_t -cdk_pk_sign (cdk_seckey_t sk, cdk_pkt_signature_t sig, const byte *md) -{ - gcry_sexp_t s_skey = NULL, s_sig = NULL, s_hash = NULL; - byte *encmd = NULL; - size_t enclen = 0; - int nbits; - cdk_error_t rc; - gcry_error_t err; - - if (!sk || !sk->pk || !sig || !md) - return CDK_Inv_Value; - - if (!is_unprotected (sk)) - return CDK_Inv_Mode; - - if (!KEY_CAN_SIGN (sig->pubkey_algo)) - return CDK_Inv_Algo; - - nbits = cdk_pk_get_nbits (sk->pk); - rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, sk->pk->pubkey_algo, md, - sig->digest_algo, nbits); - if (rc) - return rc; - - rc = seckey_to_sexp (&s_skey, sk); - if (!rc) - rc = digest_to_sexp (&s_hash, sig->digest_algo, encmd, enclen); - if (rc) - { - cdk_free (encmd); - gcry_sexp_release (s_skey); - return rc; - } - - err = gcry_pk_sign (&s_sig, s_hash, s_skey); - if (err) - rc = map_gcry_error (err); - else - { - rc = sexp_to_sig (sig, s_sig); - if (!rc) - { - sig->digest_start[0] = md[0]; - sig->digest_start[1] = md[1]; - } - } - - gcry_sexp_release (s_skey); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_sig); - cdk_free (encmd); - return rc; -} - - /** * cdk_pk_verify: * @pk: the public key @@ -461,38 +72,59 @@ cdk_pk_sign (cdk_seckey_t sk, cdk_pkt_signature_t sig, const byte *md) cdk_error_t cdk_pk_verify (cdk_pubkey_t pk, cdk_pkt_signature_t sig, const byte *md) { - gcry_sexp_t s_pkey = NULL, s_sig = NULL, s_hash = NULL; + gnutls_datum s_sig; byte *encmd = NULL; size_t enclen; cdk_error_t rc; - - if (!pk || !sig || !md) + int ret, algo; + gnutls_datum data; + gnutls_pk_params_st params; + + if (!pk || !sig || !md) { + gnutls_assert(); return CDK_Inv_Value; + } + + if (is_DSA (pk->pubkey_algo)) algo = GNUTLS_PK_DSA; + else if (is_RSA( pk->pubkey_algo)) algo = GNUTLS_PK_RSA; + else + { + gnutls_assert(); + return CDK_Inv_Value; + } - rc = pubkey_to_sexp (&s_pkey, pk); - if (rc) - return rc; - - rc = sig_to_sexp (&s_sig, sig); - if (rc) + rc = sig_to_datum (&s_sig, sig); + if (rc) { + gnutls_assert(); goto leave; + } rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, pk->pubkey_algo, md, sig->digest_algo, cdk_pk_get_nbits (pk)); - if (rc) - goto leave; - - rc = digest_to_sexp (&s_hash, sig->digest_algo, encmd, enclen); - if (rc) + if (rc) { + gnutls_assert(); goto leave; + } - if (gcry_pk_verify (s_sig, s_hash, s_pkey)) - rc = CDK_Bad_Sig; + data.data = encmd; + data.size = enclen; + params.params = pk->mpi; + params.params_nr = cdk_pk_get_npkey( pk->pubkey_algo); + params.flags = 0; + ret = _gnutls_pk_verify( algo, &data, &s_sig, ¶ms); + + if (ret < 0) + { + gnutls_assert(); + rc = map_gnutls_error( ret); + goto leave; + } + + rc = 0; + leave: - gcry_sexp_release (s_sig); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_pkey); + _gnutls_free_datum( &s_sig); cdk_free (encmd); return rc; } @@ -512,7 +144,7 @@ cdk_pk_get_nbits (cdk_pubkey_t pk) { if (!pk || !pk->mpi[0]) return 0; - return gcry_mpi_get_nbits (pk->mpi[0]); + return _gnutls_mpi_get_nbits (pk->mpi[0]); } @@ -526,13 +158,13 @@ cdk_pk_get_nbits (cdk_pubkey_t pk) int cdk_pk_get_npkey (int algo) { - size_t bytes; - - if (algo == 16) - algo = 20; /* FIXME: libgcrypt returns 0 for 16 */ - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &bytes)) - return 0; - return bytes; + if (is_RSA(algo)) return RSA_PUBLIC_PARAMS; + else if (is_DSA(algo)) return DSA_PUBLIC_PARAMS; + else if (is_ELG(algo)) return 3; + else { + gnutls_assert(); + return 0; + } } @@ -545,13 +177,19 @@ cdk_pk_get_npkey (int algo) **/ int cdk_pk_get_nskey (int algo) -{ - size_t bytes; +{ +int ret; + + if (is_RSA(algo)) ret = RSA_PRIVATE_PARAMS; + else if (is_DSA(algo)) ret = DSA_PRIVATE_PARAMS; + else if (is_ELG(algo)) ret = 4; + else { + gnutls_assert(); + return 0; + } - if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &bytes)) - return 0; - bytes -= cdk_pk_get_npkey (algo); - return bytes; + ret -= cdk_pk_get_npkey(algo); + return ret; } @@ -564,11 +202,9 @@ cdk_pk_get_nskey (int algo) int cdk_pk_get_nsig (int algo) { - size_t bytes; - - if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &bytes)) - return 0; - return bytes; + if (is_RSA(algo)) return 1; + else if (is_DSA(algo)) return 2; + else return 0; } @@ -581,11 +217,9 @@ cdk_pk_get_nsig (int algo) int cdk_pk_get_nenc (int algo) { - size_t bytes; - - if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NENCR, NULL, &bytes)) - return 0; - return bytes; + if (is_RSA(algo)) return 1; + else if (is_ELG(algo)) return 2; + else return 0; } @@ -610,15 +244,18 @@ _cdk_pk_algo_usage (int algo) /* You can use a NULL buf to get the output size only */ static cdk_error_t -mpi_to_buffer (gcry_mpi_t a, byte *buf, size_t buflen, +mpi_to_buffer (bigint_t a, byte *buf, size_t buflen, size_t *r_nwritten, size_t *r_nbits) { size_t nbits; + int err; - if (!a || !r_nwritten) + if (!a || !r_nwritten) { + gnutls_assert(); return CDK_Inv_Value; + } - nbits = gcry_mpi_get_nbits (a); + nbits = _gnutls_mpi_get_nbits (a); if (r_nbits) *r_nbits = nbits; @@ -628,8 +265,13 @@ mpi_to_buffer (gcry_mpi_t a, byte *buf, size_t buflen, if ((nbits+7)/8+2 > buflen) return CDK_Too_Short; - if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, buflen, r_nwritten, a)) - return CDK_Wrong_Format; + *r_nwritten = buflen; + err = _gnutls_mpi_print (a, buf, r_nwritten); + if (err < 0) { + gnutls_assert(); + return map_gnutls_error(err); + } + return 0; } @@ -650,7 +292,8 @@ cdk_pk_get_mpi (cdk_pubkey_t pk, size_t idx, { if (!pk || !r_nwritten) return CDK_Inv_Value; - if (idx > cdk_pk_get_npkey (pk->pubkey_algo)) + + if ((ssize_t)idx > cdk_pk_get_npkey (pk->pubkey_algo)) return CDK_Inv_Value; return mpi_to_buffer (pk->mpi[idx], buf, buflen, r_nwritten, r_nbits); } @@ -674,259 +317,31 @@ cdk_sk_get_mpi (cdk_pkt_seckey_t sk, size_t idx, { if (!sk || !r_nwritten) return CDK_Inv_Value; - if (idx > cdk_pk_get_nskey (sk->pubkey_algo)) + + if ((ssize_t)idx > cdk_pk_get_nskey (sk->pubkey_algo)) return CDK_Inv_Value; return mpi_to_buffer (sk->mpi[idx], buf, buflen, r_nwritten, r_nbits); } static u16 -checksum_mpi (gcry_mpi_t m) +checksum_mpi (bigint_t m) { byte buf[MAX_MPI_BYTES+2]; size_t nread; - int i; + unsigned int i; u16 chksum = 0; if (!m) return 0; - if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, DIM (buf), &nread, m)) + nread = DIM(buf); + if (_gnutls_mpi_print_pgp (m, buf, &nread) < 0) return 0; for (i=0; i < nread; i++) chksum += buf[i]; return chksum; } - -/** - * cdk_sk_unprotect: - * @sk: the secret key - * @pw: the passphrase - * - * Unprotect the given secret key with the passphrase. - **/ -cdk_error_t -cdk_sk_unprotect (cdk_pkt_seckey_t sk, const char *pw) -{ - gcry_cipher_hd_t hd; - cdk_dek_t dek = NULL; - byte *data = NULL; - u16 chksum = 0; - size_t ndata, nbits, nbytes; - int i, dlen, pos = 0, nskey; - cdk_error_t rc; - gcry_error_t err; - - if (!sk) - return CDK_Inv_Value; - - nskey = cdk_pk_get_nskey (sk->pubkey_algo); - if (!sk->is_protected) - { - chksum = 0; - for (i = 0; i < nskey; i++) - chksum += checksum_mpi (sk->mpi[i]); - if (chksum != sk->csum) - return CDK_Chksum_Error; - } - - rc = cdk_dek_from_passphrase (&dek, sk->protect.algo, - sk->protect.s2k, 0, pw); - if (rc) - return rc; - err = gcry_cipher_open (&hd, sk->protect.algo, GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_ENABLE_SYNC); - if (!err) - err = gcry_cipher_setiv (hd, sk->protect.iv, sk->protect.ivlen); - if (!err) - err = gcry_cipher_setkey (hd, dek->key, dek->keylen); - if (err) - { - cdk_free (dek); - return map_gcry_error (err); - } - cdk_dek_free (dek); - chksum = 0; - if (sk->version == 4) - { - ndata = sk->enclen; - data = cdk_salloc (ndata, 1); - if (!data) - return CDK_Out_Of_Core; - gcry_cipher_decrypt (hd, data, ndata, sk->encdata, ndata); - if (sk->protect.sha1chk) - { - /* This is the new SHA1 checksum method to detect tampering - with the key as used by the Klima/Rosa attack */ - sk->csum = 0; - chksum = 1; - dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1); - if (ndata < dlen) - { - cdk_free (data); - return CDK_Inv_Packet; - } - else - { - byte mdcheck[20]; - - gcry_md_hash_buffer (GCRY_MD_SHA1, - mdcheck, data, ndata-dlen); - if (!memcmp (mdcheck, data + ndata - dlen, dlen)) - chksum = 0; /* Digest does match */ - } - } - else - { - for (i = 0; i < ndata - 2; i++) - chksum += data[i]; - sk->csum = data[ndata - 2] << 8 | data[ndata - 1]; - } - if (sk->csum == chksum) - { - for (i = 0; i < nskey; i++) - { - nbits = data[pos] << 8 | data[pos + 1]; - - if (gcry_mpi_scan (&sk->mpi[i], GCRYMPI_FMT_PGP, data, - (nbits+7)/8+2, &nbytes)) - { - wipemem (data, sk->enclen); - cdk_free (data); - return CDK_Wrong_Format; - } - gcry_mpi_set_flag (sk->mpi[i], GCRYMPI_FLAG_SECURE); - pos += (nbits+7)/8+2; - } - } - wipemem (data, sk->enclen); - cdk_free (data); - } - else - { - byte buf[MAX_MPI_BYTES+2]; - - chksum = 0; - for (i = 0; i < nskey; i++) - { - gcry_cipher_sync (hd); - gcry_mpi_print (GCRYMPI_FMT_PGP, buf, DIM (buf), - &nbytes, sk->mpi[i]); - gcry_cipher_decrypt (hd, buf+2, nbytes-2, NULL, 0); - gcry_mpi_release (sk->mpi[i]); - if (gcry_mpi_scan (&sk->mpi[i], GCRYMPI_FMT_PGP, - buf, nbytes, &nbytes)) - return CDK_Wrong_Format; - chksum += checksum_mpi (sk->mpi[i]); - } - } - gcry_cipher_close (hd); - if (chksum != sk->csum) - return CDK_Chksum_Error; - sk->is_protected = 0; - return 0; -} - - -/** - * cdk_sk_protect: - * @sk: the secret key - * @pw: the passphrase to use - * - * Protect the given secret key with a passphrase. - **/ -cdk_error_t -cdk_sk_protect (cdk_pkt_seckey_t sk, const char *pw) -{ - gcry_cipher_hd_t hd = NULL; - cdk_dek_t dek = NULL; - cdk_s2k_t s2k; - byte *p = NULL, buf[MAX_MPI_BYTES+2]; - size_t enclen = 0, nskey, i, nbytes; - size_t dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1); - gcry_error_t err; - cdk_error_t rc; - - nskey = cdk_pk_get_nskey (sk->pubkey_algo); - if (!nskey) - return CDK_Inv_Algo; - - rc = cdk_s2k_new (&s2k, CDK_S2K_ITERSALTED, GCRY_MD_SHA256, NULL); - if (!rc) - rc = cdk_dek_from_passphrase (&dek, GCRY_CIPHER_AES, s2k, 1, pw); - if (rc) - { - cdk_s2k_free (s2k); - return rc; - } - - for (i = 0; i < nskey; i++) - { - enclen += 2; - enclen += (gcry_mpi_get_nbits (sk->mpi[i])+7)/8; - } - p = sk->encdata = cdk_calloc (1, enclen + dlen + 1); - if (!p) - { - cdk_s2k_free (s2k); - return CDK_Out_Of_Core; - } - - enclen = 0; - for (i = 0; i < nskey; i++) - { - if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, - DIM (buf), &nbytes, sk->mpi[i])) - { - cdk_free (p); - cdk_s2k_free (s2k); - return CDK_Wrong_Format; - } - memcpy (p + enclen, buf, nbytes); - enclen += nbytes; - } - - enclen += dlen; - sk->enclen = enclen; - sk->protect.s2k = s2k; - sk->protect.algo = GCRY_CIPHER_AES; - sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo); - gcry_randomize (sk->protect.iv, sk->protect.ivlen, GCRY_STRONG_RANDOM); - err = gcry_cipher_open (&hd, sk->protect.algo, GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_ENABLE_SYNC); - if (err) - { - cdk_dek_free (dek); - rc = map_gcry_error (err); - goto leave; - } - - err = gcry_cipher_setkey (hd, dek->key, dek->keylen); - if (!err) - err = gcry_cipher_setiv (hd, sk->protect.iv, sk->protect.ivlen); - cdk_dek_free (dek); - if (err) - { - rc = map_gcry_error (err); - goto leave; - } - - sk->protect.sha1chk = 1; - sk->is_protected = 1; - sk->csum = 0; - - gcry_md_hash_buffer (GCRY_MD_SHA1, buf, p, enclen-dlen); - memcpy (p + enclen - dlen, buf, dlen); - gcry_cipher_encrypt (hd, p, enclen, NULL, 0); - - /* FIXME: We should release all MPI's and set the elements to NULL. */ - - leave: - gcry_cipher_close (hd); - return rc; -} - - /** * cdk_pk_from_secret_key: * @sk: the secret key @@ -943,64 +358,6 @@ cdk_pk_from_secret_key (cdk_pkt_seckey_t sk, cdk_pubkey_t *ret_pk) } -#if 0 /* FIXME: Code is not finished yet. */ -cdk_error_t -cdk_pk_revoke_cert_create (cdk_pkt_seckey_t sk, int code, const char *inf, - char **ret_revcert) -{ - gcry_md_hd_t md; - cdk_subpkt_t node; - cdk_pkt_signature_t sig; - char *p = NULL, *dat; - gcry_error_t err; - cdk_error_t rc = 0; - size_t n; - - if (!sk || !ret_revcert) - return CDK_Inv_Value; - if(code < 0 || code > 3) - return CDK_Inv_Value; - - sig = cdk_calloc (1, sizeof *sig); - if (!sig) - return CDK_Out_Of_Core; - _cdk_sig_create (sk->pk, sig); - n = 1; - if (inf) - { - n += strlen (p); - p = cdk_utf8_encode (inf); - } - dat = cdk_calloc (1, n+1); - if (!dat) - { - _cdk_free_signature (sig); - return CDK_Out_Of_Core; - } - dat[0] = code; - if (inf) - memcpy (dat+1, p, strlen (p)); - cdk_free (p); - - node = cdk_subpkt_new (n); - if (node) - { - cdk_subpkt_init (node, CDK_SIGSUBPKT_REVOC_REASON, dat, n); - cdk_subpkt_add (sig->hashed, node); - } - cdk_free (dat); - - err = gcry_md_open (&md, GCRY_MD_SHA1, 0); - if (err) - rc = map_gcry_error (err); - else - _cdk_hash_pubkey (sk->pk, md, 0); - _cdk_free_signature (sig); - - return rc; -} -#endif - int _cdk_sk_get_csum (cdk_pkt_seckey_t sk) { @@ -1028,26 +385,24 @@ _cdk_sk_get_csum (cdk_pkt_seckey_t sk) cdk_error_t cdk_pk_get_fingerprint (cdk_pubkey_t pk, byte *fpr) { - gcry_md_hd_t hd; + digest_hd_st hd; int md_algo; int dlen = 0; - gcry_error_t err; + int err; if (!pk || !fpr) return CDK_Inv_Value; if (pk->version < 4 && is_RSA (pk->pubkey_algo)) - md_algo = GCRY_MD_MD5; /* special */ + md_algo = GNUTLS_DIG_MD5; /* special */ else - md_algo = GCRY_MD_SHA1; - dlen = gcry_md_get_algo_dlen (md_algo); - err = gcry_md_open (&hd, md_algo, 0); - if (err) - return map_gcry_error (err); - _cdk_hash_pubkey (pk, hd, 1); - gcry_md_final (hd); - memcpy (fpr, gcry_md_read (hd, md_algo), dlen); - gcry_md_close (hd); + md_algo = GNUTLS_DIG_SHA1; + dlen = _gnutls_hash_get_algo_len (md_algo); + err = _gnutls_hash_init (&hd, md_algo); + if (err < 0) + return map_gnutls_error (err); + _cdk_hash_pubkey (pk, &hd, 1); + _gnutls_hash_deinit( &hd, fpr); if (dlen == 16) memset (fpr + 16, 0, 4); return 0; @@ -1150,7 +505,8 @@ cdk_pk_get_keyid (cdk_pubkey_t pk, u32 *keyid) byte p[MAX_MPI_BYTES]; size_t n; - gcry_mpi_print (GCRYMPI_FMT_USG, p, MAX_MPI_BYTES, &n, pk->mpi[0]); + n = MAX_MPI_BYTES; + _gnutls_mpi_print (pk->mpi[0], p, &n); pk->keyid[0] = p[n-8] << 24 | p[n-7] << 16 | p[n-6] << 8 | p[n-5]; pk->keyid[1] = p[n-4] << 24 | p[n-3] << 16 | p[n-2] << 8 | p[n-1]; } @@ -1273,108 +629,3 @@ _cdk_pkt_get_fingerprint (cdk_packet_t pkt, byte *fpr) } return 0; } - - -/** - * cdk_pubkey_to_sexp: - * @pk: the public key - * @sexp: where to store the S-expression - * @len: the length of sexp - * - * Convert a public key to an S-expression. sexp is allocated by this - * function, but you have to cdk_free() it yourself. The S-expression - * is stored in canonical format as used by libgcrypt - * (GCRYSEXP_FMT_CANON). - **/ -cdk_error_t -cdk_pubkey_to_sexp (cdk_pubkey_t pk, char **sexp, size_t * len) -{ - char *buf; - size_t sexp_len; - gcry_sexp_t pk_sexp; - cdk_error_t rc; - - if (!pk || !sexp) - return CDK_Inv_Value; - - rc = pubkey_to_sexp (&pk_sexp, pk); - if (rc) - return rc; - - sexp_len = gcry_sexp_sprint (pk_sexp, GCRYSEXP_FMT_CANON, NULL, 0); - if (!sexp_len) - return CDK_Wrong_Format; - - buf = (char *)cdk_malloc (sexp_len); - if (!buf) - { - gcry_sexp_release (pk_sexp); - return CDK_Out_Of_Core; - } - - sexp_len = gcry_sexp_sprint (pk_sexp, GCRYSEXP_FMT_CANON, buf, sexp_len); - gcry_sexp_release (pk_sexp); - if (!sexp_len) - { - cdk_free (buf); - return CDK_Wrong_Format; - } - - if (len) - *len = sexp_len; - *sexp = buf; - return CDK_Success; -} - - -/** - * cdk_seckey_to_sexp: - * @sk: the secret key - * @sexp: where to store the S-expression - * @len: the length of sexp - * - * Convert a public key to an S-expression. sexp is allocated by this - * function, but you have to cdk_free() it yourself. The S-expression - * is stored in canonical format as used by libgcrypt - * (GCRYSEXP_FMT_CANON). - **/ -cdk_error_t -cdk_seckey_to_sexp (cdk_pkt_seckey_t sk, char **sexp, size_t * len) -{ - char *buf; - size_t sexp_len; - gcry_sexp_t sk_sexp; - cdk_error_t rc; - - if (!sk || !sexp) - return CDK_Inv_Value; - - rc = seckey_to_sexp (&sk_sexp, sk); - if (rc) - return rc; - - sexp_len = gcry_sexp_sprint (sk_sexp, GCRYSEXP_FMT_CANON, NULL, 0); - if (!sexp_len) - return CDK_Wrong_Format; - - buf = (char *) cdk_malloc (sexp_len); - if (!buf) - { - gcry_sexp_release (sk_sexp); - return CDK_Out_Of_Core; - } - - sexp_len = gcry_sexp_sprint (sk_sexp, GCRYSEXP_FMT_CANON, buf, sexp_len); - gcry_sexp_release (sk_sexp); - if (!sexp_len) - { - cdk_free (buf); - return CDK_Wrong_Format; - } - - if (len) - *len = sexp_len; - *sexp = buf; - - return CDK_Success; -} diff --git a/lib/opencdk/read-packet.c b/lib/opencdk/read-packet.c index e6dc8bffa1..4e47c63c1e 100644 --- a/lib/opencdk/read-packet.c +++ b/lib/opencdk/read-packet.c @@ -33,7 +33,7 @@ #include "main.h" #include "packet.h" #include "types.h" - +#include <gnutls_algorithms.h> /* The version of the MDC packet considering the lastest OpenPGP draft. */ #define MDC_PKT_VER 1 @@ -86,10 +86,10 @@ read_s2k (cdk_stream_t inp, cdk_s2k_t s2k) static cdk_error_t -read_mpi (cdk_stream_t inp, gcry_mpi_t *ret_m, int secure) +read_mpi (cdk_stream_t inp, bigint_t *ret_m, int secure) { - gcry_mpi_t m; - gcry_error_t err; + bigint_t m; + int err; byte buf[MAX_MPI_BYTES+2]; size_t nread, nbits; cdk_error_t rc; @@ -116,11 +116,11 @@ read_mpi (cdk_stream_t inp, gcry_mpi_t *ret_m, int secure) buf[0] = nbits >> 8; buf[1] = nbits >> 0; - err = gcry_mpi_scan (&m, GCRYMPI_FMT_PGP, buf, nread+2, &nread); - if (err) - return map_gcry_error (err); - if (secure) - gcry_mpi_set_flag (m, GCRYMPI_FLAG_SECURE); + nread+=2; + err = _gnutls_mpi_scan_pgp( &m, buf, nread); + if (err < 0) + return map_gnutls_error (err); + *ret_m = m; return rc; } @@ -163,98 +163,6 @@ _cdk_pkt_read_len (FILE *inp, size_t *ret_partial) static cdk_error_t -read_encrypted (cdk_stream_t inp, size_t pktlen, cdk_pkt_encrypted_t enc, - int is_partial, int is_mdc) -{ - if (!inp || !enc) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _cdk_log_debug ("read_encrypted: %d octets\n", pktlen); - - if (is_mdc) - { - int version = cdk_stream_getc (inp); - if (version != MDC_PKT_VER) - return CDK_Inv_Packet; - enc->mdc_method = CDK_MD_SHA1; - pktlen--; - } - /* The packet must at least contain blocksize + 2 octets. */ - if (pktlen < 10) - return CDK_Inv_Packet; - if (is_partial) - _cdk_stream_set_blockmode (inp, pktlen); - enc->len = pktlen; - enc->buf = inp; - return 0; -} - - -static cdk_error_t -read_symkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_symkey_enc_t ske) -{ - cdk_s2k_t s2k; - size_t minlen; - size_t nread, nleft; - - if (!inp || !ske) - return CDK_Inv_Value; - - if (DEBUG_PKT) - _cdk_log_debug ("read_symkey_enc: %d octets\n", pktlen); - - ske->version = cdk_stream_getc (inp); - if (ske->version != 4 || cdk_stream_eof (inp)) - return CDK_Inv_Packet; - - s2k = ske->s2k = cdk_calloc (1, sizeof *ske->s2k); - if (!ske->s2k) - return CDK_Out_Of_Core; - - ske->cipher_algo = cdk_stream_getc (inp); - s2k->mode = cdk_stream_getc (inp); - switch (s2k->mode) - { - case CDK_S2K_SIMPLE : minlen = 0; break; - case CDK_S2K_SALTED : minlen = 8; break; - case CDK_S2K_ITERSALTED: minlen = 9; break; - - default: - /* Invalid S2K mode. */ - return CDK_Inv_Packet; - } - - s2k->hash_algo = cdk_stream_getc (inp); - if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED) - { - if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread)) - return CDK_Inv_Packet; - if (nread != DIM (s2k->salt)) - return CDK_Inv_Packet; - - if (s2k->mode == CDK_S2K_ITERSALTED) - s2k->count = cdk_stream_getc (inp); - } - - ske->seskeylen = pktlen - 4 - minlen; - /* We check if there is an encrypted session key and if it fits into - the buffer. The maximal key length is 256-bit. */ - if (ske->seskeylen > DIM (ske->seskey)) - return CDK_Inv_Packet; - nleft = ske->seskeylen; - for (nread = 0; nread < ske->seskeylen; nread++) - { - ske->seskey[nread] = cdk_stream_getc (inp); - if (cdk_stream_eof (inp) && --nleft > 0) - return CDK_Inv_Packet; - } - - return 0; -} - - -static cdk_error_t read_pubkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_enc_t pke) { size_t i, nenc; @@ -274,7 +182,7 @@ read_pubkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_enc_t pke) pke->keyid[1] = read_32 (inp); if (!pke->keyid[0] && !pke->keyid[1]) pke->throw_keyid = 1; /* RFC2440 "speculative" keyID */ - pke->pubkey_algo = cdk_stream_getc (inp); + pke->pubkey_algo = _pgp_pub_algo_to_cdk(cdk_stream_getc (inp)); nenc = cdk_pk_get_nenc (pke->pubkey_algo); if (!nenc) return CDK_Inv_Algo; @@ -361,10 +269,11 @@ read_public_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_t pk) pk->expiredate = pk->timestamp + ndays * 86400L; } - pk->pubkey_algo = cdk_stream_getc (inp); + pk->pubkey_algo = _pgp_pub_algo_to_cdk(cdk_stream_getc (inp)); npkey = cdk_pk_get_npkey (pk->pubkey_algo); if (!npkey) { + gnutls_assert(); _cdk_log_debug ("invalid public key algorithm %d\n", pk->pubkey_algo); return CDK_Inv_Algo; } @@ -390,7 +299,6 @@ read_public_subkey (cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_t pk) return read_public_key (inp, pktlen, pk); } - static cdk_error_t read_secret_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk) { @@ -414,15 +322,15 @@ read_secret_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk) if (sk->s2k_usage == 254 || sk->s2k_usage == 255) { sk->protect.sha1chk = (sk->s2k_usage == 254); - sk->protect.algo = cdk_stream_getc (inp); + sk->protect.algo = _pgp_cipher_to_gnutls(cdk_stream_getc (inp)); sk->protect.s2k = cdk_calloc (1, sizeof *sk->protect.s2k); if (!sk->protect.s2k) return CDK_Out_Of_Core; rc = read_s2k (inp, sk->protect.s2k); if (rc) return rc; - sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo); - if (!sk->protect.ivlen) + sk->protect.ivlen = _gnutls_cipher_get_block_size (sk->protect.algo); + if (sk->protect.ivlen <= 0) return CDK_Inv_Packet; rc = stream_read (inp, sk->protect.iv, sk->protect.ivlen, &nread); if (rc) @@ -431,13 +339,15 @@ read_secret_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk) return CDK_Inv_Packet; } else - sk->protect.algo = sk->s2k_usage; - if (sk->protect.algo == GCRY_CIPHER_NONE) + sk->protect.algo = _pgp_cipher_to_gnutls(sk->s2k_usage); + if (sk->protect.algo == GNUTLS_CIPHER_NULL) { sk->csum = 0; nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo); - if (!nskey) + if (!nskey) { + gnutls_assert(); return CDK_Inv_Algo; + } for (i = 0; i < nskey; i++) { rc = read_mpi (inp, &sk->mpi[i], 1); @@ -447,12 +357,14 @@ read_secret_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk) sk->csum = read_16 (inp); sk->is_protected = 0; } - else if (sk->pk->version < 4) + else if (sk->pk->version < 4) { /* The length of each multiprecision integer is stored in plaintext. */ nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo); - if (!nskey) + if (!nskey) { + gnutls_assert(); return CDK_Inv_Algo; + } for (i = 0; i < nskey; i++) { rc = read_mpi (inp, &sk->mpi[i], 1); @@ -462,7 +374,7 @@ read_secret_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk) sk->csum = read_16 (inp); sk->is_protected = 1; } - else + else { /* We need to read the rest of the packet because we do not have any information how long the encrypted mpi's are */ @@ -477,8 +389,10 @@ read_secret_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk) if (stream_read (inp, sk->encdata, sk->enclen, &nread)) return CDK_Inv_Packet; nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo); - if (!nskey) + if (!nskey) { + gnutls_assert(); return CDK_Inv_Algo; + } /* We mark each MPI entry with NULL to indicate a protected key. */ for (i = 0; i < nskey; i++) sk->mpi[i] = NULL; @@ -668,8 +582,8 @@ read_onepass_sig (cdk_stream_t inp, size_t pktlen, cdk_pkt_onepass_sig_t sig) if (sig->version != 3) return CDK_Inv_Packet_Ver; sig->sig_class = cdk_stream_getc (inp); - sig->digest_algo = cdk_stream_getc (inp); - sig->pubkey_algo = cdk_stream_getc (inp); + sig->digest_algo = _pgp_hash_algo_to_gnutls(cdk_stream_getc (inp)); + sig->pubkey_algo = _pgp_pub_algo_to_cdk(cdk_stream_getc (inp)); sig->keyid[0] = read_32 (inp); sig->keyid[1] = read_32 (inp); sig->last = cdk_stream_getc (inp); @@ -780,8 +694,8 @@ read_signature (cdk_stream_t inp, size_t pktlen, cdk_pkt_signature_t sig) sig->timestamp = read_32 (inp); sig->keyid[0] = read_32 (inp); sig->keyid[1] = read_32 (inp); - sig->pubkey_algo = cdk_stream_getc (inp); - sig->digest_algo = cdk_stream_getc (inp); + sig->pubkey_algo = _pgp_pub_algo_to_cdk(cdk_stream_getc (inp)); + sig->digest_algo = _pgp_hash_algo_to_gnutls(cdk_stream_getc (inp)); sig->digest_start[0] = cdk_stream_getc (inp); sig->digest_start[1] = cdk_stream_getc (inp); nsig = cdk_pk_get_nsig (sig->pubkey_algo); @@ -797,8 +711,8 @@ read_signature (cdk_stream_t inp, size_t pktlen, cdk_pkt_signature_t sig) else { sig->sig_class = cdk_stream_getc (inp); - sig->pubkey_algo = cdk_stream_getc (inp); - sig->digest_algo = cdk_stream_getc (inp); + sig->pubkey_algo = _pgp_pub_algo_to_cdk(cdk_stream_getc (inp)); + sig->digest_algo = _pgp_hash_algo_to_gnutls(cdk_stream_getc (inp)); sig->hashed_size = read_16 (inp); size = sig->hashed_size; sig->hashed = NULL; @@ -870,7 +784,7 @@ read_literal (cdk_stream_t inp, size_t pktlen, rc = stream_read (inp, pt->name, pt->namelen, &nread); if (rc) return rc; - if (nread != pt->namelen) + if ((int)nread != pt->namelen) return CDK_Inv_Packet; pt->name[pt->namelen] = '\0'; } @@ -970,7 +884,6 @@ skip_packet (cdk_stream_t inp, size_t pktlen) cdk_error_t cdk_pkt_read (cdk_stream_t inp, cdk_packet_t pkt) { - int use_mdc = 0; int ctb, is_newctb; int pkttype; size_t pktlen = 0, pktsize = 0, is_partial = 0; @@ -1098,23 +1011,6 @@ cdk_pkt_read (cdk_stream_t inp, cdk_packet_t pkt) rc = read_signature (inp, pktlen, pkt->pkt.signature); break; - case CDK_PKT_ENCRYPTED_MDC: - case CDK_PKT_ENCRYPTED: - pkt->pkt.encrypted = cdk_calloc (1, sizeof *pkt->pkt.encrypted); - if (!pkt->pkt.encrypted) - return CDK_Out_Of_Core; - use_mdc = (pkt->pkttype == CDK_PKT_ENCRYPTED_MDC) ? 1 : 0; - rc = read_encrypted (inp, pktlen, pkt->pkt.encrypted, - is_partial, use_mdc); - break; - - case CDK_PKT_SYMKEY_ENC: - pkt->pkt.symkey_enc = cdk_calloc (1, sizeof *pkt->pkt.symkey_enc); - if (!pkt->pkt.symkey_enc) - return CDK_Out_Of_Core; - rc = read_symkey_enc (inp, pktlen, pkt->pkt.symkey_enc); - break; - case CDK_PKT_PUBKEY_ENC: pkt->pkt.pubkey_enc = cdk_calloc (1, sizeof *pkt->pkt.pubkey_enc); if (!pkt->pkt.pubkey_enc) diff --git a/lib/opencdk/seskey.c b/lib/opencdk/seskey.c index f8a9da8e59..f7d3af111d 100644 --- a/lib/opencdk/seskey.c +++ b/lib/opencdk/seskey.c @@ -40,618 +40,151 @@ * PAD consists of FF bytes. */ static cdk_error_t -do_encode_md (byte **r_frame, size_t *r_flen, const byte *md, int algo, - size_t len, unsigned nbits, const byte *asn, size_t asnlen) +do_encode_md(byte ** r_frame, size_t * r_flen, const byte * md, int algo, + size_t len, unsigned nbits, const byte * asn, size_t asnlen) { byte *frame = NULL; size_t nframe = (nbits + 7) / 8; - size_t i, n = 0; + ssize_t i; + size_t n = 0; if (!asn || !md || !r_frame || !r_flen) return CDK_Inv_Value; - + if (len + asnlen + 4 > nframe) return CDK_General_Error; - - frame = cdk_calloc (1, nframe); + + frame = cdk_calloc(1, nframe); if (!frame) return CDK_Out_Of_Core; frame[n++] = 0; frame[n++] = 1; i = nframe - len - asnlen - 3; - if (i < 0) - { - cdk_free (frame); - return CDK_Inv_Value; - } - memset (frame + n, 0xFF, i); + if (i < 0) { + cdk_free(frame); + return CDK_Inv_Value; + } + memset(frame + n, 0xFF, i); n += i; frame[n++] = 0; - memcpy (frame + n, asn, asnlen); + memcpy(frame + n, asn, asnlen); n += asnlen; - memcpy (frame + n, md, len); + memcpy(frame + n, md, len); n += len; - if (n != nframe) - { - cdk_free (frame); - return CDK_Inv_Value; - } + if (n != nframe) { + cdk_free(frame); + return CDK_Inv_Value; + } *r_frame = frame; *r_flen = n; return 0; } - - -/* RFC2437 format: - * - * 0 2 RND(n bytes) 0 [A DEK(k bytes) CSUM(2 bytes)] - * - * RND - randomized bytes for padding. - * A - cipher algorithm. - * DEK - random session key. - * CKSUM - algebraic checksum of the DEK. - */ - -/** - * cdk_dek_encode_pkcs1 - * @dek: DEK object - * @nbits: size of the multi precision integer frame - * @r_enc: output of the encoded multiprecision integer - * - * Encode the given random session key in the DEK object - * into a multiprecision integer. - **/ -cdk_error_t -cdk_dek_encode_pkcs1 (cdk_dek_t dek, size_t nbits, gcry_mpi_t *r_enc) -{ - gcry_mpi_t a = NULL; - gcry_error_t err; - byte *p, *frame; - size_t n; - size_t nframe; - size_t i; - u16 chksum; - - if (!r_enc || !dek) - return CDK_Inv_Value; - - *r_enc = NULL; - chksum = 0; - for (i = 0; i < dek->keylen; i++) - chksum += dek->key[i]; - nframe = (nbits + 7) / 8; - frame = cdk_salloc (nframe + 1, 1); - if (!frame) - return CDK_Out_Of_Core; - n = 0; - frame[n++] = 0x00; - frame[n++] = 0x02; - i = nframe - 6 - dek->keylen; - p = gcry_random_bytes (i, GCRY_STRONG_RANDOM); - /* Replace zero bytes by new values */ - for (;;) - { - size_t j, k; - byte *pp; - - /* count the zero bytes */ - for (j = k = 0; j < i; j++) - { - if (!p[j]) - k++; - } - if (!k) - break; /* No zeroes remain. */ - k += k / 128; /* better get some more */ - pp = gcry_random_bytes (k, GCRY_STRONG_RANDOM); - for (j = 0; j < i && k; j++) - { - if (!p[j]) - p[j] = pp[--k]; - } - cdk_free (pp); - } - memcpy (frame + n, p, i); - cdk_free (p); - n += i; - frame[n++] = 0; - frame[n++] = dek->algo; - memcpy (frame + n, dek->key, dek->keylen); - n += dek->keylen; - frame[n++] = chksum >> 8; - frame[n++] = chksum; - err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe); - cdk_free (frame); - if (err) - return map_gcry_error (err); - *r_enc = a; - return 0; -} - - -/** - * cdk_dek_decode_pkcs1: - * @ret_dek: the decoded DEK object - * @esk: the pkcs#1 encoded session key. - * - * Decode the given multi precision integer in pkcs#1 and - * store it into the DEK object. - **/ -cdk_error_t -cdk_dek_decode_pkcs1 (cdk_dek_t *ret_dek, gcry_mpi_t esk) -{ - cdk_dek_t dek; - byte frame[MAX_MPI_BYTES+2+1]; - size_t nframe, n; - u16 csum, csum2; - gcry_error_t err; - - if (!ret_dek || !esk) - return CDK_Inv_Value; - - *ret_dek = NULL; /* reset */ - nframe = DIM (frame)-1; - err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, esk); - if (err) - return map_gcry_error (err); - dek = cdk_salloc (sizeof *dek, 1); - if (!dek) - return CDK_Out_Of_Core; - - /* Now get the DEK (data encryption key) from the frame - * - * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) - * - * (gcry_mpi_print already removed the leading zero). - * - * RND are non-zero randow bytes. - * A is the cipher algorithm - * DEK is the encryption key (session key) with length k - * CSUM - */ - n = 0; - if (frame[n] != 2) - { - cdk_free (dek); - return CDK_Inv_Mode; - } - for (n++; n < nframe && frame[n]; n++) - ; - n++; - dek->keylen = nframe - (n + 1) - 2; - dek->algo = frame[n++]; - if (dek->keylen != gcry_cipher_get_algo_keylen (dek->algo)) - { - _cdk_log_debug ("pkcs1 decode: invalid cipher keylen %d\n", dek->keylen); - cdk_free (dek); - return CDK_Inv_Algo; +static const byte md5_asn[18] = /* Object ID is 1.2.840.113549.2.5 */ +{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 +}; + +static const byte sha1_asn[15] = /* Object ID is 1.3.14.3.2.26 */ +{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, + 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 +}; + +static const byte sha224_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */ +{ 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, + 0x1C +}; + +static const byte sha256_asn[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */ +{ 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, + 0x00, 0x04, 0x20 +}; + +static const byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */ +{ + 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, + 0x00, 0x04, 0x40 +}; + +static const byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */ +{ + 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, + 0x00, 0x04, 0x30 +}; + +static const byte rmd160_asn[15] = /* Object ID is 1.3.36.3.2.1 */ +{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, + 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 +}; + +static int _gnutls_get_digest_oid(gnutls_digest_algorithm_t algo, const byte** data) +{ + switch (algo) { + case GNUTLS_DIG_MD5: + *data = md5_asn; + return sizeof(md5_asn); + case GNUTLS_DIG_SHA1: + *data = sha1_asn; + return sizeof(sha1_asn); + case GNUTLS_DIG_RMD160: + *data = rmd160_asn; + return sizeof(rmd160_asn); + case GNUTLS_DIG_SHA256: + *data = sha256_asn; + return sizeof(sha256_asn); + case GNUTLS_DIG_SHA384: + *data = sha384_asn; + return sizeof(sha384_asn); + case GNUTLS_DIG_SHA512: + *data = sha512_asn; + return sizeof(sha512_asn); + case GNUTLS_DIG_SHA224: + *data = sha224_asn; + return sizeof(sha224_asn); + default: + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; } - csum = frame[nframe-2] << 8; - csum |= frame[nframe-1]; - memcpy (dek->key, frame + n, dek->keylen); - csum2 = 0; - for (n = 0; n < dek->keylen; n++) - csum2 += dek->key[n]; - if (csum != csum2) - { - _cdk_log_debug ("pkcs decode: checksum does not match\n"); - cdk_free (dek); - return CDK_Chksum_Error; - } - *ret_dek = dek; - return 0; } /* Encode the given digest into a pkcs#1 compatible format. */ cdk_error_t -_cdk_digest_encode_pkcs1 (byte **r_md, size_t *r_mdlen, int pk_algo, - const byte *md, int digest_algo, unsigned nbits) +_cdk_digest_encode_pkcs1(byte ** r_md, size_t * r_mdlen, int pk_algo, + const byte * md, int digest_algo, unsigned nbits) { - gcry_error_t err; size_t dlen; if (!md || !r_md || !r_mdlen) return CDK_Inv_Value; - - dlen = gcry_md_get_algo_dlen (digest_algo); - if (!dlen) - return CDK_Inv_Algo; - if (is_DSA (pk_algo)) /* DSS does not use a special encoding. */ - { - *r_md = cdk_malloc (dlen + 1); - if (!*r_md) - return CDK_Out_Of_Core; - *r_mdlen = dlen; - memcpy (*r_md, md, dlen); - return 0; - } - else - { - byte *asn; - size_t asnlen; - cdk_error_t rc; - - err = gcry_md_get_asnoid (digest_algo, NULL, &asnlen); - if (err) - return map_gcry_error (err); - asn = cdk_malloc (asnlen + 1); - if (!asn) - return CDK_Out_Of_Core; - err = gcry_md_get_asnoid (digest_algo, asn, &asnlen); - if (err) - { - cdk_free (asn); - return map_gcry_error (err); - } - rc = do_encode_md (r_md, r_mdlen, md, digest_algo, dlen, - nbits, asn, asnlen); - cdk_free (asn); - return rc; - } - return 0; -} - - -/* FIXME: The prompt should be provided in a more generic way. - Like: (keyid, algorithm, [user-id]) */ -static char* -passphrase_prompt (cdk_pkt_seckey_t sk) -{ - u32 keyid = cdk_pk_get_keyid (sk->pk, NULL); - int bits = cdk_pk_get_nbits (sk->pk), pk_algo = sk->pubkey_algo; - const char *algo = "???", *fmt; - char *p; - - if (is_RSA (pk_algo)) - algo = "RSA"; - else if (is_ELG (pk_algo)) - algo = "ELG"; - else if (is_DSA (pk_algo)) - algo = "DSA"; - - fmt = "%d-bit %s key, ID %08lX\nEnter Passphrase: "; - p = cdk_calloc (1, 64 + strlen (fmt) + strlen (algo) + 1); - if (!p) - return NULL; - sprintf (p, fmt, bits, algo, keyid); - return p; -} - - -/* Try to unprotect the secret key, if needed, automatically. - The passphrase callback is used to get the passphrase directly - from the user. */ -cdk_error_t -_cdk_sk_unprotect_auto (cdk_ctx_t hd, cdk_pkt_seckey_t sk) -{ - char *pw, *p; - cdk_error_t rc; - - if (!sk->is_protected) - return 0; - - p = passphrase_prompt (sk); - pw = _cdk_passphrase_get (hd, p); - cdk_free (p); - if (!pw) - return CDK_No_Passphrase; - - rc = cdk_sk_unprotect (sk, pw); - - wipemem (pw, strlen (pw)); - cdk_free (pw); - return rc; -} - - -/** - * cdk_dek_extract: - * @ret_dek: the raw DEK object - * @hd: the session handle - * @enc: the public key encrypted packet - * @sk: the secret key. - * - * Try to extract the DEK from the public key encrypted packet. - **/ -cdk_error_t -cdk_dek_extract (cdk_dek_t *ret_dek, cdk_ctx_t hd, - cdk_pkt_pubkey_enc_t enc, cdk_pkt_seckey_t sk) -{ - gcry_mpi_t skey = NULL; - cdk_dek_t dek; - cdk_error_t rc; - - if (!enc || !sk || !ret_dek) - return CDK_Inv_Value; - - /* FIXME: it is not very elegant that we need the session handle here. */ - if (sk->is_protected) - { - rc = _cdk_sk_unprotect_auto (hd, sk); - if (rc) - return rc; - } - - rc = cdk_pk_decrypt (sk, enc, &skey); - if (rc) - return rc; - - rc = cdk_dek_decode_pkcs1 (&dek, skey); - gcry_mpi_release (skey); - if (rc) - { - cdk_dek_free (dek); - dek = NULL; - } - *ret_dek = dek; - return rc; -} - - -/** - * cdk_dek_new: - * @r_dek: the new DEK object - * - * Create a new DEK object. - **/ -cdk_error_t -cdk_dek_new (cdk_dek_t *r_dek) -{ - cdk_dek_t dek; - - if (!r_dek) - return CDK_Inv_Value; - *r_dek = NULL; - dek = cdk_salloc (sizeof *dek, 1); - if (!dek) - return CDK_Out_Of_Core; - *r_dek = dek; - return 0; -} - -/** - * cdk_dek_set_cipher: - * @dek: the DEK object - * @algo: the cipher algorithm to use - * - * Set the cipher for the given DEK object. - **/ -cdk_error_t -cdk_dek_set_cipher (cdk_dek_t dek, int algo) -{ - if (!dek) - return CDK_Inv_Value; - - if (!algo) - algo = GCRY_CIPHER_AES128; - if (gcry_cipher_test_algo (algo)) + dlen = _gnutls_hash_get_algo_len(digest_algo); + if (dlen <= 0) return CDK_Inv_Algo; - dek->algo = algo; - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - return 0; -} - -cdk_error_t -cdk_dek_get_cipher (cdk_dek_t dek, int *r_algo) -{ - if (!dek || !r_algo) - return CDK_Inv_Value; - - - *r_algo = dek->algo; - return 0; -} - - -/** - * cdk_dek_set_key: - * @dek: the DEK object - * @key: the random session key - * @keylen: the length of the session key. - * - * Set the random session key for the given DEK object. - * If @key and @keylen is NULL (0) a random key will be generated. - * In any case, cdk_dek_set_cipher must be called first. - **/ -cdk_error_t -cdk_dek_set_key (cdk_dek_t dek, const byte *key, size_t keylen) -{ - gcry_cipher_hd_t hd; - size_t i; - - if (!dek) - return CDK_Inv_Value; - - /* The given key must be compatible with the symmetric - cipher algorithm set before. */ - if (keylen > 0 && keylen != dek->keylen) - return CDK_Inv_Mode; - - if (!key && !keylen) - { - gcry_error_t err; - - /* Used to generate a random session key. The extra code is used - to detect weak keys, if they are possible at all. */ - err = gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, - GCRY_CIPHER_ENABLE_SYNC); - if (err) - return map_gcry_error (err); - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM); - for (i = 0; i < 8; i++) - { - if (!gcry_cipher_setkey (hd, dek->key, dek->keylen)) - { - gcry_cipher_close (hd); - return 0; - } - gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM); - } - gcry_cipher_close (hd); - return CDK_Weak_Key; - } - - memcpy (dek->key, key, dek->keylen); - return 0; -} - - -/** - * cdk_dek_set_mdc_flag: - * @dek: the DEK object - * @val: value to enable or disable the use - * - * Enable or disable the MDC flag for the given DEK object. - **/ -void -cdk_dek_set_mdc_flag (cdk_dek_t dek, int val) -{ - if (dek) - dek->use_mdc = val; -} - - -int -cdk_dek_get_mdc_flag (cdk_dek_t dek) -{ - if (!dek) + if (is_DSA(pk_algo)) { /* DSS does not use a special encoding. */ + *r_md = cdk_malloc(dlen + 1); + if (!*r_md) + return CDK_Out_Of_Core; + *r_mdlen = dlen; + memcpy(*r_md, md, dlen); return 0; - return dek->use_mdc; -} - - -/** - * cdk_dek_free: - * @dek: the DEK object - * - * Release the DEK object. - **/ -void -cdk_dek_free (cdk_dek_t dek) -{ - if (!dek) - return; - - /* Make sure sentensive data is overwritten. */ - wipemem (dek->key, sizeof (dek->key)); - cdk_free (dek); -} + } else { + const byte *asn; + int asnlen; + cdk_error_t rc; + asnlen = _gnutls_get_digest_oid( digest_algo, &asn); + if (asnlen < 0) + return asnlen; -/* Hash the passphrase to produce the a DEK. - If create is set, a random salt will be generated. */ -static cdk_error_t -hash_passphrase (cdk_dek_t dek, const char *pw, cdk_s2k_t s2k, int create) -{ - gcry_md_hd_t md; - byte zero[1] = {0x00}; - int pass, i; - int used = 0, pwlen; - gcry_error_t err; - - if (!dek || !pw || !s2k) - return CDK_Inv_Value; - - if (!s2k->hash_algo) - s2k->hash_algo = GCRY_MD_SHA1; - pwlen = strlen (pw); - - dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); - err = gcry_md_open (&md, s2k->hash_algo, 0); - if (err) - return map_gcry_error (err); - - for (pass = 0; used < dek->keylen; pass++) - { - if (pass) - { - gcry_md_reset (md); - for (i = 0; i < pass; i++) /* preset the hash context */ - gcry_md_write (md, zero, 1); - } - if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED) - { - int len2 = pwlen + 8; - u32 count = len2; - if (create && !pass) - { - gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM); - if (s2k->mode == 3) - s2k->count = 96; /* 65536 iterations */ - } - if (s2k->mode == 3) - { - count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6); - if (count < len2) - count = len2; - } - /* a little bit complicated because we need a ulong for count */ - while (count > len2) - { /* maybe iterated+salted */ - gcry_md_write (md, s2k->salt, 8); - gcry_md_write (md, pw, pwlen); - count -= len2; - } - if (count < 8) - gcry_md_write (md, s2k->salt, count); - else - { - gcry_md_write (md, s2k->salt, 8); - count -= 8; - gcry_md_write (md, pw, count); - } - } - else - gcry_md_write (md, pw, pwlen); - gcry_md_final (md); - i = gcry_md_get_algo_dlen (s2k->hash_algo); - if (i > dek->keylen - used) - i = dek->keylen - used; - memcpy (dek->key + used, gcry_md_read (md, s2k->hash_algo), i); - used += i; - } - gcry_md_close (md); - return 0; -} - - -/** - * cdk_dek_from_passphrase: - * @ret_dek: the new DEK. - * @cipher_algo: symmetric key algorithm to use - * @s2k: the S2K to use - * @rndsalt: 1=create random salt - * @pw: the passphrase. - * - * Transform a passphrase into a DEK object. - */ -cdk_error_t -cdk_dek_from_passphrase (cdk_dek_t *ret_dek, int cipher_algo, cdk_s2k_t s2k, - int rndsalt, const char *pw) -{ - cdk_dek_t dek; - cdk_error_t rc; - - if (!ret_dek) - return CDK_Inv_Value; - - *ret_dek = NULL; - rc = cdk_dek_new (&dek); - if (rc) + rc = do_encode_md(r_md, r_mdlen, md, digest_algo, dlen, + nbits, asn, asnlen); return rc; - rc = cdk_dek_set_cipher (dek, cipher_algo); - if (!rc) - rc = hash_passphrase (dek, pw, s2k, rndsalt); - if (rc) - { - cdk_dek_free (dek); - return rc; - } - - *ret_dek = dek; + } return 0; } @@ -667,7 +200,8 @@ cdk_dek_from_passphrase (cdk_dek_t *ret_dek, int cipher_algo, cdk_s2k_t s2k, * The @salt parameter must be always 8 octets. **/ cdk_error_t -cdk_s2k_new (cdk_s2k_t *ret_s2k, int mode, int digest_algo, const byte *salt) +cdk_s2k_new(cdk_s2k_t * ret_s2k, int mode, int digest_algo, + const byte * salt) { cdk_s2k_t s2k; @@ -676,17 +210,17 @@ cdk_s2k_new (cdk_s2k_t *ret_s2k, int mode, int digest_algo, const byte *salt) if (mode != 0x00 && mode != 0x01 && mode != 0x03) return CDK_Inv_Mode; - - if (gcry_md_test_algo (digest_algo)) + + if (_gnutls_hash_get_algo_len(digest_algo) <= 0) return CDK_Inv_Algo; - - s2k = cdk_calloc (1, sizeof *s2k); + + s2k = cdk_calloc(1, sizeof *s2k); if (!s2k) return CDK_Out_Of_Core; s2k->mode = mode; s2k->hash_algo = digest_algo; if (salt) - memcpy (s2k->salt, salt, 8); + memcpy(s2k->salt, salt, 8); *ret_s2k = s2k; return 0; } @@ -698,25 +232,23 @@ cdk_s2k_new (cdk_s2k_t *ret_s2k, int mode, int digest_algo, const byte *salt) * * Release the given S2K object. **/ -void -cdk_s2k_free (cdk_s2k_t s2k) +void cdk_s2k_free(cdk_s2k_t s2k) { - cdk_free (s2k); + cdk_free(s2k); } /* Make a copy of the source s2k into R_DST. */ -cdk_error_t -_cdk_s2k_copy (cdk_s2k_t *r_dst, cdk_s2k_t src) +cdk_error_t _cdk_s2k_copy(cdk_s2k_t * r_dst, cdk_s2k_t src) { cdk_s2k_t dst; cdk_error_t err; - - err = cdk_s2k_new (&dst, src->mode, src->hash_algo, src->salt); + + err = cdk_s2k_new(&dst, src->mode, src->hash_algo, src->salt); if (err) return err; dst->count = src->count; *r_dst = dst; - + return 0; } diff --git a/lib/opencdk/sig-check.c b/lib/opencdk/sig-check.c index 24c9165f97..cbf6be2219 100644 --- a/lib/opencdk/sig-check.c +++ b/lib/opencdk/sig-check.c @@ -37,12 +37,12 @@ /* Hash all multi precision integers of the key PK with the given message digest context MD. */ static int -hash_mpibuf (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) +hash_mpibuf (cdk_pubkey_t pk, digest_hd_st* md, int usefpr) { byte buf[MAX_MPI_BYTES]; /* FIXME: do not use hardcoded length. */ size_t nbytes; size_t i, npkey; - gcry_error_t err; + int err; /* We have to differ between two modes for v3 keys. To form the fingerprint, we hash the MPI values without the length prefix. @@ -50,14 +50,14 @@ hash_mpibuf (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) npkey = cdk_pk_get_npkey (pk->pubkey_algo); for (i = 0; i < npkey; i++) { - err = gcry_mpi_print (GCRYMPI_FMT_PGP, buf, MAX_MPI_BYTES, - &nbytes, pk->mpi[i]); - if (err) - return map_gcry_error (err); + nbytes = MAX_MPI_BYTES; + err = _gnutls_mpi_print_pgp( pk->mpi[i], buf, &nbytes); + if (err < 0) + return map_gnutls_error (err); if (!usefpr || pk->version == 4) - gcry_md_write (md, buf, nbytes); + _gnutls_hash( md, buf, nbytes); else /* without the prefix. */ - gcry_md_write (md, buf + 2, nbytes - 2); + _gnutls_hash( md, buf+2, nbytes - 2); } return 0; } @@ -67,7 +67,7 @@ hash_mpibuf (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) MD. The @usefpr param is only valid for version 3 keys because of the different way to calculate the fingerprint. */ cdk_error_t -_cdk_hash_pubkey (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) +_cdk_hash_pubkey (cdk_pubkey_t pk, digest_hd_st* md, int usefpr) { byte buf[12]; size_t i, n, npkey; @@ -83,7 +83,7 @@ _cdk_hash_pubkey (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) n = pk->version < 4? 8 : 6; npkey = cdk_pk_get_npkey (pk->pubkey_algo); for (i = 0; i < npkey; i++) - n = n + (gcry_mpi_get_nbits (pk->mpi[i])+7)/8 + 2; + n = n + (_gnutls_mpi_get_nbits (pk->mpi[i])+7)/8 + 2; i = 0; buf[i++] = 0x99; @@ -106,7 +106,7 @@ _cdk_hash_pubkey (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) buf[i++] = a; } buf[i++] = pk->pubkey_algo; - gcry_md_write (md, buf, i); + _gnutls_hash( md, buf, i); return hash_mpibuf (pk, md, 0); } @@ -114,7 +114,7 @@ _cdk_hash_pubkey (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr) /* Hash the user ID @uid with the given message digest @md. Use openpgp mode if @is_v4 is 1. */ cdk_error_t -_cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, gcry_md_hd_t md) +_cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, digest_hd_st* md) { const byte *data; byte buf[5]; @@ -125,7 +125,7 @@ _cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, gcry_md_hd_t md) if (!is_v4) { - gcry_md_write (md, (byte*)uid->name, uid->len); + _gnutls_hash (md, (byte*)uid->name, uid->len); return 0; } @@ -136,8 +136,8 @@ _cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, gcry_md_hd_t md) buf[2] = dlen >> 16; buf[3] = dlen >> 8; buf[4] = dlen >> 0; - gcry_md_write (md, buf, 5); - gcry_md_write (md, data, dlen); + _gnutls_hash (md, buf, 5); + _gnutls_hash (md, data, dlen); return 0; } @@ -145,55 +145,61 @@ _cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, gcry_md_hd_t md) /* Hash all parts of the signature which are needed to derive the correct message digest to verify the sig. */ cdk_error_t -_cdk_hash_sig_data (cdk_pkt_signature_t sig, gcry_md_hd_t md) +_cdk_hash_sig_data (cdk_pkt_signature_t sig, digest_hd_st* md) { byte buf[4]; + byte tmp; if (!sig || !md) return CDK_Inv_Value; if (sig->version == 4) - gcry_md_putc (md, sig->version); - gcry_md_putc (md, sig->sig_class); + _gnutls_hash(md, &sig->version, 1); + + _gnutls_hash(md, &sig->sig_class, 1); if (sig->version < 4) { buf[0] = sig->timestamp >> 24; buf[1] = sig->timestamp >> 16; buf[2] = sig->timestamp >> 8; buf[3] = sig->timestamp >> 0; - gcry_md_write (md, buf, 4); + _gnutls_hash( md, buf, 4); } else { size_t n; - - gcry_md_putc (md, sig->pubkey_algo); - gcry_md_putc (md, sig->digest_algo); + + tmp = _cdk_pub_algo_to_pgp(sig->pubkey_algo); + _gnutls_hash( md, &tmp, 1); + tmp = _gnutls_hash_algo_to_pgp(sig->digest_algo); + _gnutls_hash( md, &tmp, 1); if (sig->hashed != NULL) { byte *p = _cdk_subpkt_get_array (sig->hashed, 0, &n); assert (p != NULL); buf[0] = n >> 8; buf[1] = n >> 0; - gcry_md_write (md, buf, 2); - gcry_md_write (md, p, n); + _gnutls_hash(md, buf, 2); + _gnutls_hash(md, p, n); cdk_free (p); sig->hashed_size = n; n = sig->hashed_size + 6; } else { - gcry_md_putc (md, 0x00); - gcry_md_putc (md, 0x00); + tmp = 0x00; + _gnutls_hash (md, &tmp, 1); + _gnutls_hash (md, &tmp, 1); n = 6; } - gcry_md_putc (md, sig->version); - gcry_md_putc (md, 0xFF); + _gnutls_hash(md, &sig->version, 1); + tmp = 0xff; + _gnutls_hash(md, &tmp, 1); buf[0] = n >> 24; buf[1] = n >> 16; buf[2] = n >> 8; buf[3] = n >> 0; - gcry_md_write (md, buf, 4); + _gnutls_hash(md, buf, 4); } return 0; } @@ -222,14 +228,17 @@ cache_sig_result (cdk_pkt_signature_t sig, int res) Use the digest handle @digest. */ cdk_error_t _cdk_sig_check (cdk_pubkey_t pk, cdk_pkt_signature_t sig, - gcry_md_hd_t digest, int *r_expired) + digest_hd_st* digest, int *r_expired) { cdk_error_t rc; byte md[MAX_DIGEST_LEN]; - time_t cur_time = (u32)time (NULL); + time_t cur_time = (u32)time (NULL); if (!pk || !sig || !digest) - return CDK_Inv_Value; + { + gnutls_assert(); + return CDK_Inv_Value; + } if (sig->flags.checked) return sig->flags.valid ?0 : CDK_Bad_Sig; @@ -243,13 +252,14 @@ _cdk_sig_check (cdk_pubkey_t pk, cdk_pkt_signature_t sig, *r_expired = 1; _cdk_hash_sig_data (sig, digest); - gcry_md_final (digest); - memcpy (md, gcry_md_read (digest, sig->digest_algo), - gcry_md_get_algo_dlen (sig->digest_algo)); + _gnutls_hash_output( digest, md); if (md[0] != sig->digest_start[0] || md[1] != sig->digest_start[1]) - return CDK_Chksum_Error; + { + gnutls_assert(); + return CDK_Chksum_Error; + } rc = cdk_pk_verify (pk, sig, md); cache_sig_result (sig, rc); @@ -263,8 +273,8 @@ cdk_error_t _cdk_pk_check_sig (cdk_keydb_hd_t keydb, cdk_kbnode_t knode, cdk_kbnode_t snode, int *is_selfsig, char** ret_uid) { - gcry_md_hd_t md; - gcry_error_t err; + digest_hd_st md; + int err; cdk_pubkey_t pk; cdk_pkt_signature_t sig; cdk_kbnode_t node; @@ -272,54 +282,65 @@ _cdk_pk_check_sig (cdk_keydb_hd_t keydb, int is_expired; if (!knode || !snode) - return CDK_Inv_Value; + { + gnutls_assert(); + return CDK_Inv_Value; + } if (is_selfsig) *is_selfsig = 0; if (knode->pkt->pkttype != CDK_PKT_PUBLIC_KEY || snode->pkt->pkttype != CDK_PKT_SIGNATURE) - return CDK_Inv_Value; + { + gnutls_assert(); + return CDK_Inv_Value; + } pk = knode->pkt->pkt.public_key; sig = snode->pkt->pkt.signature; - err = gcry_md_open (&md, sig->digest_algo, 0); - if (err) - return map_gcry_error (err); + err = _gnutls_hash_init(&md, sig->digest_algo); + if (err < 0) + { + gnutls_assert(); + return map_gnutls_error (err); + } is_expired = 0; if (sig->sig_class == 0x20) { /* key revocation */ - cdk_kbnode_hash (knode, md, 0, 0, 0); - rc = _cdk_sig_check (pk, sig, md, &is_expired); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); } else if (sig->sig_class == 0x28) { /* subkey revocation */ node = cdk_kbnode_find_prev (knode, snode, CDK_PKT_PUBLIC_SUBKEY); if (!node) { /* no subkey for subkey revocation packet */ + gnutls_assert(); rc = CDK_Error_No_Key; goto fail; } - cdk_kbnode_hash (knode, md, 0, 0, 0); - cdk_kbnode_hash (node, md, 0, 0, 0); - rc = _cdk_sig_check (pk, sig, md, &is_expired); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + cdk_kbnode_hash (node, &md, 0, 0, 0); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); } else if (sig->sig_class == 0x18 || sig->sig_class == 0x19) { /* primary/secondary key binding */ node = cdk_kbnode_find_prev (knode, snode, CDK_PKT_PUBLIC_SUBKEY); if (!node) { /* no subkey for subkey binding packet */ + gnutls_assert(); rc = CDK_Error_No_Key; goto fail; } - cdk_kbnode_hash (knode, md, 0, 0, 0); - cdk_kbnode_hash (node, md, 0, 0, 0); - rc = _cdk_sig_check (pk, sig, md, &is_expired); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + cdk_kbnode_hash (node, &md, 0, 0, 0); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); } else if (sig->sig_class == 0x1F) { /* direct key signature */ - cdk_kbnode_hash (knode, md, 0, 0, 0); - rc = _cdk_sig_check (pk, sig, md, &is_expired); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); } else { /* all other classes */ @@ -327,33 +348,35 @@ _cdk_pk_check_sig (cdk_keydb_hd_t keydb, node = cdk_kbnode_find_prev (knode, snode, CDK_PKT_USER_ID); if (!node) { /* no user ID for key signature packet */ + gnutls_assert(); rc = CDK_Error_No_Key; goto fail; } + uid = node->pkt->pkt.user_id; if (ret_uid) { *ret_uid = uid->name; } - cdk_kbnode_hash (knode, md, 0, 0, 0); - cdk_kbnode_hash (node, md, sig->version==4, 0, 0); + cdk_kbnode_hash (knode, &md, 0, 0, 0); + cdk_kbnode_hash (node, &md, sig->version==4, 0, 0); + if (pk->keyid[0] == sig->keyid[0] && pk->keyid[1] == sig->keyid[1]) { - rc = _cdk_sig_check (pk, sig, md, &is_expired); + rc = _cdk_sig_check (pk, sig, &md, &is_expired); if (is_selfsig) *is_selfsig = 1; } else if (keydb != NULL) { cdk_pubkey_t sig_pk; - rc = cdk_keydb_get_pk (keydb, sig->keyid, &sig_pk); if (!rc) - rc = _cdk_sig_check (sig_pk, sig, md, &is_expired); + rc = _cdk_sig_check (sig_pk, sig, &md, &is_expired); cdk_pk_release (sig_pk); } } fail: - gcry_md_close (md); + _gnutls_hash_deinit( &md, NULL); return rc; } @@ -422,7 +445,7 @@ struct verify_uid* p, *p1; */ static int uid_list_all_signed( struct verify_uid * list) { -struct verify_uid* p, *p1; +struct verify_uid* p; if (list == NULL) return 0; @@ -457,14 +480,20 @@ cdk_pk_check_sigs (cdk_kbnode_t key, cdk_keydb_hd_t keydb, int *r_status) int key_status, is_selfsig = 0; struct verify_uid* uid_list = NULL; char* uid_name; - - if (!key || !r_status) - return CDK_Inv_Value; + + if (!key || !r_status) + { + gnutls_assert(); + return CDK_Inv_Value; + } *r_status = 0; node = cdk_kbnode_find (key, CDK_PKT_PUBLIC_KEY); - if (!node) - return CDK_Error_No_Key; + if (!node) + { + gnutls_assert(); + return CDK_Error_No_Key; + } key_status = 0; /* Continue with the signature check but adjust the @@ -508,7 +537,10 @@ cdk_pk_check_sigs (cdk_kbnode_t key, cdk_keydb_hd_t keydb, int *r_status) */ rc = uid_list_add_sig( &uid_list, uid_name, (rc == CDK_Success && is_selfsig==0)?1:0); if (rc != CDK_Success) - goto exit; + { + gnutls_assert(); + goto exit; + } } } diff --git a/lib/opencdk/stream.c b/lib/opencdk/stream.c index 35290768fa..5bb3411033 100644 --- a/lib/opencdk/stream.c +++ b/lib/opencdk/stream.c @@ -49,7 +49,7 @@ static int stream_cache_flush (cdk_stream_t s, FILE *fp); struct stream_filter_s* filter_add (cdk_stream_t s, filter_fnct_t fnc, int type); /* Customized tmpfile() version from misc.c */ -FILE *my_tmpfile (void); +FILE *_cdk_tmpfile (void); /* FIXME: The read/write/putc/getc function cannot directly @@ -177,7 +177,7 @@ cdk_stream_new (const char *file, cdk_stream_t *ret_s) return CDK_Out_Of_Core; } } - s->fp = my_tmpfile (); + s->fp = _cdk_tmpfile (); if (!s->fp) { cdk_free (s->fname); @@ -708,7 +708,7 @@ stream_filter_write (cdk_stream_t s) if (!f->next && s->fname) f->tmp = fopen (s->fname, "w+b"); else - f->tmp = my_tmpfile (); + f->tmp = _cdk_tmpfile (); if (!f->tmp) { rc = CDK_File_Error; @@ -767,7 +767,7 @@ stream_filter_read (cdk_stream_t s) continue; } - f->tmp = my_tmpfile (); + f->tmp = _cdk_tmpfile (); if (!f->tmp) { rc = CDK_File_Error; @@ -821,7 +821,7 @@ _cdk_stream_get_opaque (cdk_stream_t s, int fid) for (f = s->filters; f; f = f->next) { - if (f->type == fid) + if ((int)f->type == fid) return f->opaque; } return NULL; @@ -1114,46 +1114,6 @@ cdk_stream_set_literal_flag (cdk_stream_t s, cdk_lit_format_t mode, /** - * cdk_stream_set_cipher_flag: - * @s: the stream object - * @dek: the data encryption key - * @use_mdc: 1 means to use the MDC mode - * - * In read mode it kicks off the cipher filter to decrypt the data - * from the stream with the key given in @dek. - * In write mode the stream data will be encrypted with the DEK object - * and optionally, the @use_mdc parameter can be used to enable the MDC mode. - **/ -cdk_error_t -cdk_stream_set_cipher_flag (cdk_stream_t s, cdk_dek_t dek, int use_mdc) -{ - struct stream_filter_s * f; - - _cdk_log_debug ("stream: enable cipher mode\n"); - if (!s) - return CDK_Inv_Value; - -#if 0 - f = filter_add (s, _cdk_filter_cipher, fCIPHER); - if (!f) - return CDK_Out_Of_Core; - dek->use_mdc = use_mdc; - f->ctl = stream_get_mode (s); - f->u.cfx.dek = dek; - f->u.cfx.mdc_method = use_mdc? GCRY_MD_SHA1 : 0; - if (s->blkmode > 0) - { - f->u.cfx.blkmode.on = 1; - f->u.cfx.blkmode.size = s->blkmode; - } - return 0; -#endif - - return CDK_Not_Implemented; -} - - -/** * cdk_stream_set_compress_flag: * @s: the stream object * @algo: the compression algo @@ -1167,11 +1127,12 @@ cdk_stream_set_cipher_flag (cdk_stream_t s, cdk_dek_t dek, int use_mdc) cdk_error_t cdk_stream_set_compress_flag (cdk_stream_t s, int algo, int level) { - struct stream_filter_s *f; return CDK_Not_Implemented; #if 0 + struct stream_filter_s *f; + if (!s) return CDK_Inv_Value; f = filter_add (s, _cdk_filter_compress, fCOMPRESS); @@ -1334,7 +1295,7 @@ cdk_stream_mmap_part (cdk_stream_t s, off_t off, size_t len, { cdk_error_t rc; off_t oldpos; - int n; + unsigned int n; if (!ret_buf || !ret_buflen) return CDK_Inv_Value; diff --git a/lib/opencdk/types.h b/lib/opencdk/types.h index bba742bcfc..8456a82292 100644 --- a/lib/opencdk/types.h +++ b/lib/opencdk/types.h @@ -24,8 +24,6 @@ #ifndef CDK_TYPES_H #define CDK_TYPES_H -#include <gcrypt.h> - #ifndef HAVE_BYTE_TYPEDEF # undef byte typedef unsigned char byte; diff --git a/lib/opencdk/verify.c b/lib/opencdk/verify.c index c141da8dc6..de5feb0064 100644 --- a/lib/opencdk/verify.c +++ b/lib/opencdk/verify.c @@ -40,12 +40,12 @@ struct { const char *name; int algo; } digest_table[] = { - {"MD5", GCRY_MD_MD5}, - {"SHA1", GCRY_MD_SHA1}, - {"RIPEMD160", GCRY_MD_RMD160}, - {"SHA256", GCRY_MD_SHA256}, - {"SHA384", GCRY_MD_SHA384}, - {"SHA512", GCRY_MD_SHA512}, + {"MD5", GNUTLS_DIG_MD5}, + {"SHA1", GNUTLS_DIG_SHA1}, + {"RIPEMD160", GNUTLS_DIG_RMD160}, + {"SHA256", GNUTLS_DIG_SHA256}, + {"SHA384", GNUTLS_DIG_SHA384}, + {"SHA512", GNUTLS_DIG_SHA512}, {NULL, 0} }; @@ -161,12 +161,12 @@ static cdk_error_t file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) { cdk_stream_t inp = NULL, out = NULL, tmp = NULL; - gcry_md_hd_t md = NULL; + digest_hd_st md; char buf[512], chk[512]; const char *s; int i, is_signed = 0, nbytes; int digest_algo = 0; - gcry_error_t err; + int err; cdk_error_t rc; if (output) @@ -223,19 +223,19 @@ file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) } } - if (digest_algo && gcry_md_test_algo (digest_algo)) + if (digest_algo && _gnutls_hash_get_algo_len(digest_algo) <= 0) { rc = CDK_Inv_Algo; goto leave; } if (!digest_algo) - digest_algo = GCRY_MD_MD5; + digest_algo = GNUTLS_DIG_MD5; - err = gcry_md_open (&md, digest_algo, 0); - if (err) + err = _gnutls_hash_init (&md, digest_algo); + if (err < 0) { - rc = map_gcry_error (err); + rc = map_gnutls_error (err); goto leave; } @@ -254,7 +254,7 @@ file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) if (strlen (buf) == 0 && i == 0) continue; /* skip last '\n' */ _cdk_trim_string (buf, i == 0? 0 : 1); - gcry_md_write (md, buf, strlen (buf)); + _gnutls_hash (&md, buf, strlen (buf)); } if (!strncmp (buf, "- ", 2)) /* FIXME: handle it recursive. */ memmove (buf, buf + 2, nbytes - 2); @@ -280,7 +280,7 @@ file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) nbytes = _cdk_stream_gets (inp, buf, DIM (buf)-1); if (!nbytes || nbytes == -1) break; - if (nbytes < (DIM (buf) -3)) + if (nbytes < (int)(DIM (buf) -3)) { buf[nbytes-1] = '\n'; buf[nbytes] = '\0'; @@ -295,10 +295,10 @@ file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output) cdk_stream_read (tmp, NULL, 0); /* the digest handle will be closed there. */ - rc = _cdk_proc_packets (hd, tmp, NULL, NULL, NULL, md); + rc = _cdk_proc_packets (hd, tmp, NULL, NULL, NULL, &md); leave: - gcry_md_close (md); + _gnutls_hash_deinit (&md, NULL); cdk_stream_close (out); cdk_stream_close (tmp); cdk_stream_close (inp); diff --git a/lib/opencdk/write-packet.c b/lib/opencdk/write-packet.c index 35b6b0f50c..c5ba1cc08d 100644 --- a/lib/opencdk/write-packet.c +++ b/lib/opencdk/write-packet.c @@ -94,38 +94,40 @@ write_16 (cdk_stream_t out, u16 u) static size_t -calc_mpisize (gcry_mpi_t mpi[MAX_CDK_PK_PARTS], size_t ncount) +calc_mpisize (bigint_t mpi[MAX_CDK_PK_PARTS], size_t ncount) { size_t size, i; size = 0; for (i = 0; i < ncount; i++) - size += (gcry_mpi_get_nbits (mpi[i]) + 7) / 8 + 2; + size += (_gnutls_mpi_get_nbits (mpi[i]) + 7) / 8 + 2; return size; } static int -write_mpi (cdk_stream_t out, gcry_mpi_t m) +write_mpi (cdk_stream_t out, bigint_t m) { byte buf[MAX_MPI_BYTES+2]; size_t nbits, nread; - gcry_error_t err; + int err; if (!out || !m) return CDK_Inv_Value; - nbits = gcry_mpi_get_nbits (m); + nbits = _gnutls_mpi_get_nbits (m); if (nbits > MAX_MPI_BITS || nbits < 1) return CDK_MPI_Error; - err = gcry_mpi_print (GCRYMPI_FMT_PGP, buf, MAX_MPI_BYTES+2, &nread, m); - if (err) - return map_gcry_error (err); + + nread = MAX_MPI_BYTES+2; + err = _gnutls_mpi_print_pgp( m, buf, &nread); + if (err < 0) + return map_gnutls_error (err); return stream_write (out, buf, nread); } static cdk_error_t -write_mpibuf (cdk_stream_t out, gcry_mpi_t mpi[MAX_CDK_PK_PARTS], size_t count) +write_mpibuf (cdk_stream_t out, bigint_t mpi[MAX_CDK_PK_PARTS], size_t count) { size_t i; cdk_error_t rc; @@ -250,93 +252,6 @@ pkt_write_head (cdk_stream_t out, int old_ctb, size_t size, int type) } -static cdk_error_t -write_encrypted (cdk_stream_t out, cdk_pkt_encrypted_t enc, int old_ctb) -{ - size_t nbytes; - cdk_error_t rc; - - assert (out); - assert (enc); - - if (DEBUG_PKT) - _cdk_log_debug ("write_encrypted: %lu bytes\n", enc->len); - - nbytes = enc->len ? (enc->len + enc->extralen) : 0; - rc = pkt_write_head (out, old_ctb, nbytes, CDK_PKT_ENCRYPTED); - /* The rest of the packet is ciphertext */ - return rc; -} - - -static int -write_encrypted_mdc (cdk_stream_t out, cdk_pkt_encrypted_t enc) -{ - size_t nbytes; - cdk_error_t rc; - - assert (out); - assert (enc); - - if (!enc->mdc_method) - return CDK_Inv_Packet; - - if (DEBUG_PKT) - _cdk_log_debug ("write_encrypted_mdc: %lu bytes\n", enc->len); - - nbytes = enc->len ? (enc->len + enc->extralen + 1) : 0; - rc = pkt_write_head (out, 0, nbytes, CDK_PKT_ENCRYPTED_MDC); - if (!rc) - rc = stream_putc (out, 1); /* version */ - /* The rest of the packet is ciphertext */ - return rc; -} - - -static cdk_error_t -write_symkey_enc (cdk_stream_t out, cdk_pkt_symkey_enc_t ske) -{ - cdk_s2k_t s2k; - size_t size = 0, s2k_size = 0; - cdk_error_t rc; - - assert (out); - assert (ske); - - if (ske->version != 4) - return CDK_Inv_Packet; - - if (DEBUG_PKT) - _cdk_log_debug ("write_symkey_enc:\n"); - - s2k = ske->s2k; - if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED) - s2k_size = 8; - if (s2k->mode == CDK_S2K_ITERSALTED) - s2k_size++; - size = 4 + s2k_size + ske->seskeylen; - rc = pkt_write_head (out, 0, size, CDK_PKT_SYMKEY_ENC); - if (!rc) - rc = stream_putc (out, ske->version); - if (!rc) - rc = stream_putc (out, ske->cipher_algo); - if (!rc) - rc = stream_putc (out, s2k->mode); - if (!rc) - rc = stream_putc (out, s2k->hash_algo); - if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED) - { - rc = stream_write (out, s2k->salt, 8); - if (!rc) - { - if (s2k->mode == CDK_S2K_ITERSALTED) - rc = stream_putc (out, s2k->count); - } - } - return rc; -} - - static int write_pubkey_enc (cdk_stream_t out, cdk_pkt_pubkey_enc_t pke, int old_ctb) { @@ -366,7 +281,7 @@ write_pubkey_enc (cdk_stream_t out, cdk_pkt_pubkey_enc_t pke, int old_ctb) if (!rc) rc = write_32 (out, pke->keyid[1]); if (!rc) - rc = stream_putc (out, pke->pubkey_algo); + rc = stream_putc (out, _cdk_pub_algo_to_pgp(pke->pubkey_algo)); if (!rc) rc = write_mpibuf (out, pke->mpi, nenc); return rc; @@ -429,9 +344,9 @@ write_v3_sig (cdk_stream_t out, cdk_pkt_signature_t sig, int nsig) if (!rc) rc = write_32 (out, sig->keyid[1]); if (!rc) - rc = stream_putc (out, sig->pubkey_algo); + rc = stream_putc (out, _cdk_pub_algo_to_pgp(sig->pubkey_algo)); if (!rc) - rc = stream_putc (out, sig->digest_algo); + rc = stream_putc (out, _gnutls_hash_algo_to_pgp(sig->digest_algo)); if (!rc) rc = stream_putc (out, sig->digest_start[0]); if (!rc) @@ -475,9 +390,9 @@ write_signature (cdk_stream_t out, cdk_pkt_signature_t sig, int old_ctb) if (!rc) rc = stream_putc (out, sig->sig_class); if (!rc) - rc = stream_putc (out, sig->pubkey_algo); + rc = stream_putc (out, _cdk_pub_algo_to_pgp(sig->pubkey_algo)); if (!rc) - rc = stream_putc (out, sig->digest_algo); + rc = stream_putc (out, _gnutls_hash_algo_to_pgp(sig->digest_algo)); if (!rc) rc = write_16 (out, sig->hashed_size); if (!rc) @@ -549,7 +464,7 @@ write_public_key (cdk_stream_t out, cdk_pkt_pubkey_t pk, rc = write_16 (out, ndays); } if (!rc) - rc = stream_putc (out, pk->pubkey_algo); + rc = stream_putc (out, _cdk_pub_algo_to_pgp(pk->pubkey_algo)); if (!rc) rc = write_mpibuf (out, pk->mpi, npkey); return rc; @@ -598,8 +513,10 @@ write_secret_key( cdk_stream_t out, cdk_pkt_seckey_t sk, npkey = cdk_pk_get_npkey (pk->pubkey_algo); nskey = cdk_pk_get_nskey (pk->pubkey_algo); - if (!npkey || !nskey) + if (!npkey || !nskey) { + gnutls_assert(); return CDK_Inv_Algo; + } if (pk->version < 4) size += 2; /* If the key is unprotected, the 1 extra byte: @@ -638,7 +555,7 @@ write_secret_key( cdk_stream_t out, cdk_pkt_seckey_t sk, rc = write_16 (out, ndays); } if (!rc) - rc = stream_putc (out, pk->pubkey_algo); + rc = stream_putc (out, _cdk_pub_algo_to_pgp(pk->pubkey_algo)); if( !rc ) rc = write_mpibuf (out, pk->mpi, npkey); if (sk->is_protected == 0) @@ -646,13 +563,13 @@ write_secret_key( cdk_stream_t out, cdk_pkt_seckey_t sk, else { if (is_RSA (pk->pubkey_algo) && pk->version < 4) - stream_putc (out, sk->protect.algo); + stream_putc (out, _gnutls_cipher_to_pgp(sk->protect.algo)); else if (sk->protect.s2k) { s2k_mode = sk->protect.s2k->mode; rc = stream_putc (out, sk->protect.sha1chk? 0xFE : 0xFF); if (!rc) - rc = stream_putc (out, sk->protect.algo); + rc = stream_putc (out, _gnutls_cipher_to_pgp(sk->protect.algo)); if (!rc) rc = stream_putc (out, sk->protect.s2k->mode); if (!rc) @@ -777,9 +694,9 @@ write_onepass_sig (cdk_stream_t out, cdk_pkt_onepass_sig_t sig) if (!rc) rc = stream_putc (out, sig->sig_class); if (!rc) - rc = stream_putc (out, sig->digest_algo); + rc = stream_putc (out, _gnutls_hash_algo_to_pgp(sig->digest_algo)); if (!rc) - rc = stream_putc (out, sig->pubkey_algo); + rc = stream_putc (out, _cdk_pub_algo_to_pgp(sig->pubkey_algo)); if (!rc) rc = write_32 (out, sig->keyid[0]); if (!rc) @@ -852,15 +769,6 @@ cdk_pkt_write (cdk_stream_t out, cdk_packet_t pkt) case CDK_PKT_MDC: rc = write_mdc (out, pkt->pkt.mdc); break; - case CDK_PKT_SYMKEY_ENC: - rc = write_symkey_enc (out, pkt->pkt.symkey_enc); - break; - case CDK_PKT_ENCRYPTED: - rc = write_encrypted (out, pkt->pkt.encrypted, pkt->old_ctb); - break; - case CDK_PKT_ENCRYPTED_MDC: - rc = write_encrypted_mdc (out, pkt->pkt.encrypted); - break; case CDK_PKT_PUBKEY_ENC: rc = write_pubkey_enc (out, pkt->pkt.pubkey_enc, pkt->old_ctb); break; diff --git a/lib/openpgp/extras.c b/lib/openpgp/extras.c index 1bbf6a1d92..322d6fab52 100644 --- a/lib/openpgp/extras.c +++ b/lib/openpgp/extras.c @@ -171,16 +171,7 @@ gnutls_openpgp_keyring_import (gnutls_openpgp_keyring_t keyring, goto error; } -#if 0 - i = 0; - do { - err = cdk_stream_getc( input); - if (err != EOF) raw_data[i++] = err; - } while( err != EOF); - - raw_len = i; -#else - ssize_t written=0; + size_t written=0; do { err = cdk_stream_read (input, raw_data+written, raw_len-written); @@ -190,7 +181,6 @@ gnutls_openpgp_keyring_import (gnutls_openpgp_keyring_t keyring, while( written < raw_len && err != EOF && err > 0); raw_len = written; -#endif } else @@ -281,7 +271,8 @@ gnutls_openpgp_keyring_get_crt (gnutls_openpgp_keyring_t ring, { cdk_kbnode_t knode; cdk_error_t err; - int ret = 0, count = 0; + int ret = 0; + unsigned int count = 0; cdk_keydb_search_t st; err = cdk_keydb_search_start (&st, ring->db, CDK_DBSEARCH_NEXT, NULL); diff --git a/lib/openpgp/openpgp_int.h b/lib/openpgp/openpgp_int.h index 42b176a3c6..cb95b8da2d 100644 --- a/lib/openpgp/openpgp_int.h +++ b/lib/openpgp/openpgp_int.h @@ -53,15 +53,15 @@ unsigned int _gnutls_get_pgp_key_usage(unsigned int pgp_usage); int _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, uint32_t keyid[2], - mpi_t * params, int *params_size); + bigint_t * params, int *params_size); int _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, uint32_t keyid[2], - mpi_t * params, int *params_size); + bigint_t * params, int *params_size); cdk_packet_t _gnutls_openpgp_find_key( cdk_kbnode_t knode, uint32_t keyid[2], unsigned int priv); -int _gnutls_read_pgp_mpi( cdk_packet_t pkt, unsigned int priv, size_t idx, mpi_t* m); +int _gnutls_read_pgp_mpi( cdk_packet_t pkt, unsigned int priv, size_t idx, bigint_t* m); int _gnutls_openpgp_find_subkey_idx( cdk_kbnode_t knode, uint32_t keyid[2], unsigned int priv); diff --git a/lib/openpgp/output.c b/lib/openpgp/output.c index a499a6fa51..e05c3ff94d 100644 --- a/lib/openpgp/output.c +++ b/lib/openpgp/output.c @@ -84,7 +84,7 @@ print_key_usage (gnutls_string * str, gnutls_openpgp_crt_t cert, unsigned int id addf (str, _("\t\tKey Usage:\n")); - if (idx == -1) + if (idx == (unsigned int)-1) err = gnutls_openpgp_crt_get_key_usage (cert, &key_usage); else err = gnutls_openpgp_crt_get_subkey_usage (cert, idx, &key_usage); diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c index 13d97d4530..f0d625cb42 100644 --- a/lib/openpgp/pgp.c +++ b/lib/openpgp/pgp.c @@ -167,7 +167,7 @@ int _gnutls_openpgp_export (cdk_kbnode_t node, if (format == GNUTLS_OPENPGP_FMT_BASE64) { - unsigned char *in = cdk_calloc (1, *output_data_size); + unsigned char *in = gnutls_calloc (1, *output_data_size); memcpy (in, output_data, *output_data_size); /* Calculate the size of the encoded data and check if the provided @@ -176,7 +176,7 @@ int _gnutls_openpgp_export (cdk_kbnode_t node, NULL, 0, &calc_size, private?CDK_ARMOR_SECKEY:CDK_ARMOR_PUBKEY); if (rc || calc_size > input_data_size) { - cdk_free (in); + gnutls_free (in); *output_data_size = calc_size; gnutls_assert (); return GNUTLS_E_SHORT_MEMORY_BUFFER; @@ -185,7 +185,7 @@ int _gnutls_openpgp_export (cdk_kbnode_t node, rc = cdk_armor_encode_buffer (in, *output_data_size, output_data, input_data_size, &calc_size, private?CDK_ARMOR_SECKEY:CDK_ARMOR_PUBKEY); - cdk_free (in); + gnutls_free (in); *output_data_size = calc_size; } @@ -1053,7 +1053,7 @@ gnutls_openpgp_crt_get_subkey_usage (gnutls_openpgp_crt_t key, return 0; } -int _gnutls_read_pgp_mpi( cdk_packet_t pkt, unsigned int priv, size_t idx, mpi_t* m) +int _gnutls_read_pgp_mpi( cdk_packet_t pkt, unsigned int priv, size_t idx, bigint_t* m) { size_t buf_size = 512; opaque * buf = gnutls_malloc( buf_size); @@ -1104,7 +1104,7 @@ unsigned int max_pub_params = 0; } } } - + if (err != CDK_Success) { gnutls_assert(); @@ -1112,7 +1112,7 @@ unsigned int max_pub_params = 0; return _gnutls_map_cdk_rc( err); } - err = _gnutls_mpi_scan_pgp (m, buf, &buf_size); + err = _gnutls_mpi_scan (m, buf, buf_size); gnutls_free( buf); if (err < 0) @@ -1129,7 +1129,7 @@ unsigned int max_pub_params = 0; */ int _gnutls_openpgp_crt_get_mpis (gnutls_openpgp_crt_t cert, uint32_t *keyid /* [2] */, - mpi_t * params, int *params_size) + bigint_t * params, int *params_size) { int result, i; int pk_algorithm, local_params; @@ -1200,7 +1200,7 @@ int _get_pk_rsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, int pk_algorithm, ret, i; cdk_packet_t pkt; uint32_t kid32[2]; - mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; int params_size = MAX_PUBLIC_PARAMS_SIZE; if (crt == NULL) @@ -1233,14 +1233,14 @@ int _get_pk_rsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, return ret; } - ret = _gnutls_mpi_dprint (m, params[0]); + ret = _gnutls_mpi_dprint (params[0], m); if (ret < 0) { gnutls_assert (); goto cleanup; } - ret = _gnutls_mpi_dprint (e, params[1]); + ret = _gnutls_mpi_dprint (params[1], e); if (ret < 0) { gnutls_assert (); @@ -1266,7 +1266,7 @@ int _get_pk_dsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, int pk_algorithm, ret, i; cdk_packet_t pkt; uint32_t kid32[2]; - mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; int params_size = MAX_PUBLIC_PARAMS_SIZE; if (crt == NULL) @@ -1300,7 +1300,7 @@ int _get_pk_dsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, } /* P */ - ret = _gnutls_mpi_dprint (p, params[0]); + ret = _gnutls_mpi_dprint (params[0], p); if (ret < 0) { gnutls_assert (); @@ -1308,7 +1308,7 @@ int _get_pk_dsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, } /* Q */ - ret = _gnutls_mpi_dprint (q, params[1]); + ret = _gnutls_mpi_dprint (params[1], q); if (ret < 0) { gnutls_assert (); @@ -1318,7 +1318,7 @@ int _get_pk_dsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, /* G */ - ret = _gnutls_mpi_dprint (g, params[2]); + ret = _gnutls_mpi_dprint (params[2], g); if (ret < 0) { gnutls_assert (); @@ -1329,7 +1329,7 @@ int _get_pk_dsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, /* Y */ - ret = _gnutls_mpi_dprint (y, params[3]); + ret = _gnutls_mpi_dprint (params[3], y); if (ret < 0) { gnutls_assert (); @@ -1556,6 +1556,10 @@ int ret; * for authentication. If flag is non zero and no authentication * subkey exists, then a valid subkey will be returned even if it is * not marked for authentication. + * Returns the 64-bit keyID of the first valid OpenPGP subkey marked + * for authentication. If flag is non zero and no authentication + * subkey exists, then a valid subkey will be returned even if it is + * not marked for authentication. * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ @@ -1604,16 +1608,15 @@ int gnutls_openpgp_crt_get_auth_subkey( gnutls_openpgp_crt_t crt, } if (usage & GNUTLS_KEY_KEY_AGREEMENT) - { - ret = gnutls_openpgp_crt_get_subkey_id( crt, i, keyid); - if (ret < 0) - { - gnutls_assert(); - return ret; - } - - return 0; - } + { + ret = gnutls_openpgp_crt_get_subkey_id( crt, i, keyid); + if (ret < 0) + { + gnutls_assert(); + return ret; + } + return 0; + } } if (flag && keyid_init) return 0; diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c index b843a9e373..13cd072ea0 100644 --- a/lib/openpgp/privkey.c +++ b/lib/openpgp/privkey.c @@ -78,7 +78,7 @@ gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key) * @key: The structure to store the parsed key. * @data: The RAW or BASE64 encoded key. * @format: One of gnutls_openpgp_crt_fmt_t elements. - * @pass: Unused for now + * @password: (unused for now) * @flags: should be zero * * This function will convert the given RAW or Base64 encoded key to @@ -91,7 +91,7 @@ int gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key, const gnutls_datum_t * data, gnutls_openpgp_crt_fmt_t format, - const char *pass, unsigned int flags) + const char *password, unsigned int flags) { cdk_stream_t inp; cdk_packet_t pkt; @@ -142,7 +142,7 @@ gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key, * gnutls_openpgp_privkey_export - export a RAW or BASE64 encoded key * @key: Holds the key. * @format: One of gnutls_openpgp_crt_fmt_t elements. - * @password: the password that will be used to encrypt the key. + * @password: the password that will be used to encrypt the key. (unused for now) * @flags: zero for future compatibility * @output_data: will contain the key base64 encoded or raw * @output_data_size: holds the size of output_data (and will be @@ -378,7 +378,7 @@ static cdk_packet_t _get_secret_subkey(gnutls_openpgp_privkey_t key, unsigned in { cdk_kbnode_t p, ctx; cdk_packet_t pkt; - int subkeys; + unsigned int subkeys; ctx = NULL; subkeys = 0; @@ -656,7 +656,7 @@ gnutls_openpgp_privkey_get_subkey_fingerprint (gnutls_openpgp_privkey_t key, */ int _gnutls_openpgp_privkey_get_mpis (gnutls_openpgp_privkey_t pkey, uint32_t *keyid /*[2]*/, - mpi_t * params, int *params_size) + bigint_t * params, int *params_size) { int result, i; int pk_algorithm, local_params; @@ -730,7 +730,7 @@ int _get_sk_rsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, int pk_algorithm, ret, i; cdk_packet_t pkt; uint32_t kid32[2]; - mpi_t params[MAX_PRIV_PARAMS_SIZE]; + bigint_t params[MAX_PRIV_PARAMS_SIZE]; int params_size = MAX_PRIV_PARAMS_SIZE; if (pkey == NULL) @@ -763,14 +763,14 @@ int _get_sk_rsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, return ret; } - ret = _gnutls_mpi_dprint (m, params[0]); + ret = _gnutls_mpi_dprint (params[0], m); if (ret < 0) { gnutls_assert (); goto cleanup; } - ret = _gnutls_mpi_dprint (e, params[1]); + ret = _gnutls_mpi_dprint (params[1], e); if (ret < 0) { gnutls_assert (); @@ -778,7 +778,7 @@ int _get_sk_rsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (d, params[2]); + ret = _gnutls_mpi_dprint (params[2], d); if (ret < 0) { gnutls_assert (); @@ -787,7 +787,7 @@ int _get_sk_rsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (p, params[3]); + ret = _gnutls_mpi_dprint (params[3], p); if (ret < 0) { gnutls_assert (); @@ -797,7 +797,7 @@ int _get_sk_rsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (q, params[4]); + ret = _gnutls_mpi_dprint (params[4], q); if (ret < 0) { gnutls_assert (); @@ -808,7 +808,7 @@ int _get_sk_rsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (u, params[5]); + ret = _gnutls_mpi_dprint (params[5], u); if (ret < 0) { gnutls_assert (); @@ -839,7 +839,7 @@ int _get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, int pk_algorithm, ret, i; cdk_packet_t pkt; uint32_t kid32[2]; - mpi_t params[MAX_PRIV_PARAMS_SIZE]; + bigint_t params[MAX_PRIV_PARAMS_SIZE]; int params_size = MAX_PRIV_PARAMS_SIZE; if (pkey == NULL) @@ -873,7 +873,7 @@ int _get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, } /* P */ - ret = _gnutls_mpi_dprint (p, params[0]); + ret = _gnutls_mpi_dprint (params[0], p); if (ret < 0) { gnutls_assert (); @@ -881,7 +881,7 @@ int _get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, } /* Q */ - ret = _gnutls_mpi_dprint (q, params[1]); + ret = _gnutls_mpi_dprint (params[1], q); if (ret < 0) { gnutls_assert (); @@ -891,7 +891,7 @@ int _get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, /* G */ - ret = _gnutls_mpi_dprint (g, params[2]); + ret = _gnutls_mpi_dprint (params[2], g); if (ret < 0) { gnutls_assert (); @@ -902,7 +902,7 @@ int _get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, /* Y */ - ret = _gnutls_mpi_dprint (y, params[3]); + ret = _gnutls_mpi_dprint (params[3], y); if (ret < 0) { gnutls_assert (); @@ -912,7 +912,7 @@ int _get_sk_dsa_raw(gnutls_openpgp_privkey_t pkey, gnutls_openpgp_keyid_t keyid, goto cleanup; } - ret = _gnutls_mpi_dprint (x, params[4]); + ret = _gnutls_mpi_dprint (params[4], x); if (ret < 0) { gnutls_assert (); diff --git a/lib/pk-libgcrypt.c b/lib/pk-libgcrypt.c new file mode 100644 index 0000000000..2c1c83c117 --- /dev/null +++ b/lib/pk-libgcrypt.c @@ -0,0 +1,767 @@ +/* + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 Free Software Foundation + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +/* This file contains the functions needed for RSA/DSA public key + * encryption and signatures. + */ + +#include <gnutls_int.h> +#include <gnutls_mpi.h> +#include <gnutls_pk.h> +#include <gnutls_errors.h> +#include <gnutls_datum.h> +#include <gnutls_global.h> +#include <gnutls_num.h> +#include "debug.h" +#include <x509/x509_int.h> +#include <x509/common.h> +#include <random.h> +#include <gnutls_pk.h> +#include <gcrypt.h> + +/* this is based on code from old versions of libgcrypt (centuries ago) + */ + +int (*generate) (gnutls_pk_algorithm_t, unsigned int level /*bits */ , + gnutls_pk_params_st *); + +int +_wrap_gcry_pk_encrypt(gnutls_pk_algorithm_t algo, + gnutls_datum_t * ciphertext, + const gnutls_datum_t * plaintext, + const gnutls_pk_params_st * pk_params) +{ + gcry_sexp_t s_ciph = NULL, s_data = NULL, s_pkey = NULL; + int rc = -1; + int ret; + bigint_t data = NULL; + + if (_gnutls_mpi_scan_nz(&data, plaintext->data, plaintext->size) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + /* make a sexp from pkey */ + switch (algo) { + case GNUTLS_PK_RSA: + if (pk_params->params_nr >= 2) + rc = gcry_sexp_build(&s_pkey, NULL, + "(public-key(rsa(n%m)(e%m)))", + pk_params->params[0], pk_params->params[1]); + break; + + default: + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + if (rc != 0) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + /* put the data into a simple list */ + if (gcry_sexp_build(&s_data, NULL, "%m", data)) { + gnutls_assert(); + ret = GNUTLS_E_MEMORY_ERROR; + goto cleanup; + } + + _gnutls_mpi_release(&data); + + /* pass it to libgcrypt */ + rc = gcry_pk_encrypt(&s_ciph, s_data, s_pkey); + gcry_sexp_release(s_data); + s_data = NULL; + gcry_sexp_release(s_pkey); + s_pkey = NULL; + + if (rc != 0) { + gnutls_assert(); + ret = GNUTLS_E_PK_ENCRYPTION_FAILED; + goto cleanup; + } else { + gcry_sexp_t list = gcry_sexp_find_token(s_ciph, "a", 0); + bigint_t res; + + if (list == NULL) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + res = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + if (res == NULL) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + ret = _gnutls_mpi_dprint_size(res, ciphertext, plaintext->size); + _gnutls_mpi_release(&res); + + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + } + + gcry_sexp_release(s_ciph); + return 0; + +cleanup: + _gnutls_mpi_release(&data); + if (s_ciph) + gcry_sexp_release(s_ciph); + if (s_data) + gcry_sexp_release(s_data); + if (s_pkey) + gcry_sexp_release(s_pkey); + + return ret; +} + +int +_wrap_gcry_pk_decrypt(gnutls_pk_algorithm_t algo, + gnutls_datum_t * plaintext, + const gnutls_datum_t * ciphertext, + const gnutls_pk_params_st * pk_params) +{ + gcry_sexp_t s_plain = NULL, s_data = NULL, s_pkey = NULL; + int rc = -1; + int ret; + bigint_t data; + + if (_gnutls_mpi_scan_nz(&data, ciphertext->data, ciphertext->size) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + /* make a sexp from pkey */ + switch (algo) { + case GNUTLS_PK_RSA: + if (pk_params->params_nr >= 6) + rc = gcry_sexp_build(&s_pkey, NULL, + "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))", + pk_params->params[0], pk_params->params[1], + pk_params->params[2], pk_params->params[3], + pk_params->params[4], pk_params->params[5]); + break; + + default: + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + if (rc != 0) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + /* put the data into a simple list */ + if (gcry_sexp_build(&s_data, NULL, "(enc-val(rsa(a%m)))", data)) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + _gnutls_mpi_release(&data); + + /* pass it to libgcrypt */ + rc = gcry_pk_decrypt(&s_plain, s_data, s_pkey); + gcry_sexp_release(s_data); + gcry_sexp_release(s_pkey); + + if (rc != 0) { + gnutls_assert(); + return GNUTLS_E_PK_DECRYPTION_FAILED; + } else { + bigint_t res; + res = gcry_sexp_nth_mpi(s_plain, 0, 0); + gcry_sexp_release(s_plain); + + if (res == NULL) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + ret = _gnutls_mpi_dprint_size(res, plaintext, ciphertext->size); + _gnutls_mpi_release(&res); + + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + } + + return 0; + +cleanup: + _gnutls_mpi_release(&data); + if (s_plain) + gcry_sexp_release(s_plain); + if (s_data) + gcry_sexp_release(s_data); + if (s_pkey) + gcry_sexp_release(s_pkey); + + return ret; + +} + + +/* in case of DSA puts into data, r,s + */ +int +_wrap_gcry_pk_sign(gnutls_pk_algorithm_t algo, gnutls_datum_t * signature, + const gnutls_datum_t * vdata, + const gnutls_pk_params_st * pk_params) +{ + gcry_sexp_t s_hash = NULL, s_key = NULL, s_sig = NULL; + gcry_sexp_t list = NULL; + int rc = -1, ret; + bigint_t hash; + bigint_t res[2] = { NULL, NULL }; + + if (_gnutls_mpi_scan_nz(&hash, vdata->data, vdata->size) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + /* make a sexp from pkey */ + switch (algo) { + case GNUTLS_PK_DSA: + if (pk_params->params_nr >= 5) + rc = gcry_sexp_build(&s_key, NULL, + "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", + pk_params->params[0], pk_params->params[1], + pk_params->params[2], pk_params->params[3], + pk_params->params[4]); + else { + gnutls_assert(); + } + + break; + case GNUTLS_PK_RSA: + if (pk_params->params_nr >= 6) + rc = gcry_sexp_build(&s_key, NULL, + "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))", + pk_params->params[0], pk_params->params[1], + pk_params->params[2], pk_params->params[3], + pk_params->params[4], pk_params->params[5]); + else { + gnutls_assert(); + } + break; + + default: + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + if (rc != 0) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + /* put the data into a simple list */ + if (gcry_sexp_build(&s_hash, NULL, "%m", hash)) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + _gnutls_mpi_release(&hash); + + /* pass it to libgcrypt */ + rc = gcry_pk_sign(&s_sig, s_hash, s_key); + gcry_sexp_release(s_hash); + gcry_sexp_release(s_key); + + if (rc != 0) { + gnutls_assert(); + ret = GNUTLS_E_PK_SIGN_FAILED; + goto cleanup; + } + + ret = GNUTLS_E_INTERNAL_ERROR; + + if (algo == GNUTLS_PK_DSA) { + list = gcry_sexp_find_token(s_sig, "r", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(s_sig); + return GNUTLS_E_INTERNAL_ERROR; + } + + res[0] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token(s_sig, "s", 0); + if (list == NULL) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + res[1] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + ret = _gnutls_encode_ber_rs(signature, res[0], res[1]); + + } else if (algo == GNUTLS_PK_RSA) { /* GCRY_PK_RSA */ + list = gcry_sexp_find_token(s_sig, "s", 0); + if (list == NULL) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + res[0] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + ret = _gnutls_mpi_dprint(res[0], signature); + } + + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + + gcry_sexp_release(s_sig); + + return 0; + +cleanup: + _gnutls_mpi_release(&hash); + _gnutls_mpi_release(&res[0]); + _gnutls_mpi_release(&res[1]); + if (s_sig) + gcry_sexp_release(s_sig); + if (list) + gcry_sexp_release(list); + if (s_hash) + gcry_sexp_release(s_hash); + if (s_key) + gcry_sexp_release(s_key); + + return ret; +} + +int _wrap_gcry_pk_verify( gnutls_pk_algorithm_t algo, + const gnutls_datum_t * vdata, const gnutls_datum_t * signature, + const gnutls_pk_params_st * pk_params) +{ + gcry_sexp_t s_sig, s_hash, s_pkey; + int rc = -1, ret; + bigint_t hash; + bigint_t tmp[2] = { NULL, NULL }; + + if (_gnutls_mpi_scan_nz(&hash, vdata->data, vdata->size) != 0) { + gnutls_assert(); + return GNUTLS_E_MPI_SCAN_FAILED; + } + + /* make a sexp from pkey */ + switch (algo) { + case GNUTLS_PK_DSA: + if (pk_params->params_nr >= 4) + rc = gcry_sexp_build(&s_pkey, NULL, + "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", + pk_params->params[0], pk_params->params[1], pk_params->params[2], pk_params->params[3]); + break; + case GNUTLS_PK_RSA: + if (pk_params->params_nr >= 2) + rc = gcry_sexp_build(&s_pkey, NULL, + "(public-key(rsa(n%m)(e%m)))", + pk_params->params[0], pk_params->params[1]); + break; + + default: + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + if (rc != 0) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + /* put the data into a simple list */ + if (gcry_sexp_build(&s_hash, NULL, "%m", hash)) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + switch (algo) { + case GNUTLS_PK_DSA: + ret = _gnutls_decode_ber_rs (signature, &tmp[0], &tmp[1]); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + rc = gcry_sexp_build(&s_sig, NULL, + "(sig-val(dsa(r%m)(s%m)))", tmp[0], tmp[1]); + + break; + case GNUTLS_PK_RSA: + ret = _gnutls_mpi_scan_nz( &tmp[0], signature->data, signature->size); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s%m)))", tmp[0]); + break; + + default: + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + if (rc != 0) { + gnutls_assert(); + ret = GNUTLS_E_INTERNAL_ERROR; + goto cleanup; + } + + _gnutls_mpi_release(&tmp[0]); + _gnutls_mpi_release(&tmp[1]); + + rc = gcry_pk_verify(s_sig, s_hash, s_pkey); + + gcry_sexp_release(s_sig); + gcry_sexp_release(s_hash); + gcry_sexp_release(s_pkey); + + if (rc != 0) { + gnutls_assert(); + ret = GNUTLS_E_PK_SIG_VERIFY_FAILED; + goto cleanup; + } + + return 0; + +cleanup: + _gnutls_mpi_release(&hash); + _gnutls_mpi_release(&tmp[0]); + _gnutls_mpi_release(&tmp[1]); + if (s_sig) + gcry_sexp_release(s_sig); + if (s_hash) + gcry_sexp_release(s_hash); + if (s_pkey) + gcry_sexp_release(s_pkey); + + return ret; +} + +static int _dsa_generate_params(bigint_t * resarr, int *resarr_len, int bits) +{ + + int ret; + gcry_sexp_t parms, key, list; + + /* FIXME: Remove me once we depend on 1.3.1 */ + if (bits > 1024 && gcry_check_version("1.3.1") == NULL) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + if (bits < 512) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + ret = gcry_sexp_build(&parms, NULL, "(genkey(dsa(nbits %d)))", bits); + if (ret != 0) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + /* generate the DSA key + */ + ret = gcry_pk_genkey(&key, parms); + gcry_sexp_release(parms); + + if (ret != 0) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + list = gcry_sexp_find_token(key, "p", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[0] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token(key, "q", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[1] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token(key, "g", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[2] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token(key, "y", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[3] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + + list = gcry_sexp_find_token(key, "x", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[4] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + + gcry_sexp_release(key); + + _gnutls_dump_mpi("p: ", resarr[0]); + _gnutls_dump_mpi("q: ", resarr[1]); + _gnutls_dump_mpi("g: ", resarr[2]); + _gnutls_dump_mpi("y: ", resarr[3]); + _gnutls_dump_mpi("x: ", resarr[4]); + + *resarr_len = 5; + + return 0; + +} + +static int _rsa_generate_params(bigint_t * resarr, int *resarr_len, int bits) +{ + + int ret; + gcry_sexp_t parms, key, list; + + ret = gcry_sexp_build(&parms, NULL, "(genkey(rsa(nbits %d)))", bits); + if (ret != 0) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + /* generate the RSA key */ + ret = gcry_pk_genkey(&key, parms); + gcry_sexp_release(parms); + + if (ret != 0) { + gnutls_assert(); + return GNUTLS_E_INTERNAL_ERROR; + } + + list = gcry_sexp_find_token(key, "n", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[0] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token(key, "e", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[1] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token(key, "d", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[2] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + list = gcry_sexp_find_token(key, "p", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[3] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + + list = gcry_sexp_find_token(key, "q", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[4] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + + list = gcry_sexp_find_token(key, "u", 0); + if (list == NULL) { + gnutls_assert(); + gcry_sexp_release(key); + return GNUTLS_E_INTERNAL_ERROR; + } + + resarr[5] = gcry_sexp_nth_mpi(list, 1, 0); + gcry_sexp_release(list); + + gcry_sexp_release(key); + + _gnutls_dump_mpi("n: ", resarr[0]); + _gnutls_dump_mpi("e: ", resarr[1]); + _gnutls_dump_mpi("d: ", resarr[2]); + _gnutls_dump_mpi("p: ", resarr[3]); + _gnutls_dump_mpi("q: ", resarr[4]); + _gnutls_dump_mpi("u: ", resarr[5]); + + *resarr_len = 6; + + return 0; + +} + + +static +int wrap_gcry_pk_generate_params(gnutls_pk_algorithm_t algo, + unsigned int level /*bits */ , + gnutls_pk_params_st * params) +{ + + switch (algo) { + + case GNUTLS_PK_DSA: + params->params_nr = RSA_PRIVATE_PARAMS; + params->params = gnutls_malloc(sizeof(bigint_t)*params->params_nr); + if (params->params == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + return _dsa_generate_params(params->params, ¶ms->params_nr, level); + + case GNUTLS_PK_RSA: + params->params_nr = DSA_PRIVATE_PARAMS; + params->params = gnutls_malloc(sizeof(bigint_t)*params->params_nr); + if (params->params == NULL) + { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + return _rsa_generate_params(params->params, ¶ms->params_nr, level); + + default: + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } +} + + +static int wrap_gcry_pk_fixup(gnutls_pk_algorithm_t algo, + gnutls_direction_t direction, + gnutls_pk_params_st * params) +{ + int ret; + + /* only for RSA we invert the coefficient --pgp type */ + + if (algo != GNUTLS_PK_RSA) + return 0; + + if (params->params[5]) + _gnutls_mpi_release(¶ms->params[5]); + params->params[5] = + _gnutls_mpi_new(_gnutls_mpi_get_nbits(params->params[0])); + + if (params->params[5] == NULL) { + gnutls_assert(); + return GNUTLS_E_MEMORY_ERROR; + } + + if (direction == GNUTLS_IMPORT) + ret = gcry_mpi_invm(params->params[5], params->params[3], params->params[4]); + else + ret = gcry_mpi_invm(params->params[5], params->params[4], params->params[3]); + if (ret == 0) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } + + return 0; +} + +int crypto_pk_prio = INT_MAX; + +gnutls_crypto_pk_st _gnutls_pk_ops = { + .encrypt = _wrap_gcry_pk_encrypt, + .decrypt = _wrap_gcry_pk_decrypt, + .sign = _wrap_gcry_pk_sign, + .verify = _wrap_gcry_pk_verify, + .generate = wrap_gcry_pk_generate_params, + .pk_fixup_private_params = wrap_gcry_pk_fixup, +}; diff --git a/lib/random.c b/lib/random.c index 82340c60b7..40b959b0bd 100644 --- a/lib/random.c +++ b/lib/random.c @@ -29,26 +29,15 @@ #include <gnutls_errors.h> #include <random.h> -static gnutls_crypto_rnd_st * cc = NULL; static void * rnd_ctx; -int -_gnutls_rnd_init () +int _gnutls_rnd_init () { - int result; - - /* check if a digest has been registered - */ - cc = _gnutls_get_crypto_rnd(); - - if (cc != NULL) { - if (cc->init(& rnd_ctx) < 0) { + if (_gnutls_rnd_ops.init != NULL) { + if (_gnutls_rnd_ops.init(& rnd_ctx) < 0) { gnutls_assert(); return GNUTLS_E_RANDOM_FAILED; } - } else { - char c; - gc_pseudo_random (&c, 1); } return 0; @@ -57,8 +46,8 @@ _gnutls_rnd_init () void _gnutls_rnd_deinit () { - if (cc != NULL) { - cc->deinit( rnd_ctx); + if (_gnutls_rnd_ops.deinit != NULL) { + _gnutls_rnd_ops.deinit( rnd_ctx); } return; @@ -67,21 +56,9 @@ _gnutls_rnd_deinit () int _gnutls_rnd (int level, void *data, int len) { -int ret = GC_OK; - if (len > 0) { - - if (cc != NULL) { - return cc->rnd( rnd_ctx, level, data, len); - } - - if (level == RND_NONCE) - ret = gc_nonce (data, len); - else - ret = gc_pseudo_random( data, len); + return _gnutls_rnd_ops.rnd( rnd_ctx, level, data, len); } - - if (ret == GC_OK) return 0; - else return GNUTLS_E_RANDOM_FAILED; + return 0; } diff --git a/lib/random.h b/lib/random.h index 5178b92712..02d06f63d2 100644 --- a/lib/random.h +++ b/lib/random.h @@ -3,6 +3,9 @@ #include <gnutls/crypto.h> +extern int crypto_rnd_prio; +extern gnutls_crypto_rnd_st _gnutls_rnd_ops; + #define RND_RANDOM GNUTLS_RND_RANDOM #define RND_NONCE GNUTLS_RND_NONCE #define RND_KEY GNUTLS_RND_KEY diff --git a/lib/rnd-libgcrypt.c b/lib/rnd-libgcrypt.c new file mode 100644 index 0000000000..3a4a50d590 --- /dev/null +++ b/lib/rnd-libgcrypt.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 Free Software Foundation + * + * Author: Nikos Mavrogiannopoulos + * + * This file is part of GNUTLS. + * + * The GNUTLS 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 library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + * + */ + +/* Here is the libgcrypt random generator layer. + */ + +#include <gnutls_int.h> +#include <libtasn1.h> +#include <gnutls_errors.h> +#include <gnutls_num.h> +#include <gnutls_mpi.h> +#include <gcrypt.h> + +static int wrap_gcry_rnd_init( void** ctx) +{ +char c; + + gcry_create_nonce ( &c, 1); + gcry_randomize(&c, 1, GCRY_STRONG_RANDOM); + + return 0; +} + +static int wrap_gcry_rnd( void* ctx, int level, void* data, int datasize) +{ + if (level == GNUTLS_RND_NONCE) + gcry_create_nonce ( data, datasize); + else + gcry_randomize( data, datasize, level); + + return 0; +} + +int crypto_rnd_prio = INT_MAX; + +gnutls_crypto_rnd_st _gnutls_rnd_ops = { + .init = wrap_gcry_rnd_init, + .deinit = NULL, + .rnd = wrap_gcry_rnd, +}; diff --git a/lib/x509/Makefile.am b/lib/x509/Makefile.am index 7f0640b58c..6098ac09fd 100644 --- a/lib/x509/Makefile.am +++ b/lib/x509/Makefile.am @@ -29,7 +29,7 @@ INCLUDES = \ noinst_LTLIBRARIES = libgnutls_x509.la libgnutls_x509_la_SOURCES = crl.c dn.c common.c x509.c extensions.c \ - dsa.c rfc2818_hostname.c verify.c mpi.c privkey.c pkcs7.c \ + rfc2818_hostname.c verify.c mpi.c privkey.c pkcs7.c \ crq.c sign.c privkey_pkcs8.c pkcs12.c pkcs12_bag.c \ pkcs12_encr.c x509_write.c crl_write.c common.h x509_int.h \ output.c diff --git a/lib/x509/common.c b/lib/x509/common.c index 82e6261902..925051eae9 100644 --- a/lib/x509/common.c +++ b/lib/x509/common.c @@ -1137,7 +1137,7 @@ int _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst, const char *dst_name, gnutls_pk_algorithm_t - pk_algorithm, mpi_t * params, + pk_algorithm, bigint_t * params, int params_size) { const char *pk; @@ -1259,7 +1259,7 @@ _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name, int algo; char oid[64]; int len; - mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; char name[128]; _gnutls_str_cpy (name, sizeof (name), src_name); diff --git a/lib/x509/common.h b/lib/x509/common.h index ffc35454f0..ed0d679647 100644 --- a/lib/x509/common.h +++ b/lib/x509/common.h @@ -117,7 +117,7 @@ int _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name, int _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst, const char *dst_name, gnutls_pk_algorithm_t - pk_algorithm, mpi_t * params, + pk_algorithm, bigint_t * params, int params_size); int _gnutls_asn1_copy_node (ASN1_TYPE * dst, const char *dst_name, ASN1_TYPE src, const char *src_name); diff --git a/lib/x509/crl.c b/lib/x509/crl.c index 10677cb137..b37f26cf78 100644 --- a/lib/x509/crl.c +++ b/lib/x509/crl.c @@ -327,7 +327,8 @@ gnutls_x509_crl_get_signature (gnutls_x509_crl_t crl, char *sig, size_t *sizeof_sig) { int result; - int bits, len; + int bits; + unsigned int len; if (crl == NULL) { diff --git a/lib/x509/mpi.c b/lib/x509/mpi.c index 247ea543c1..1ff3f65ccf 100644 --- a/lib/x509/mpi.c +++ b/lib/x509/mpi.c @@ -37,7 +37,7 @@ * Returns 2 parameters (m,e). */ int -_gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params) +_gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; @@ -88,7 +88,7 @@ _gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params) * params[0-2] */ int -_gnutls_x509_read_dsa_params (opaque * der, int dersize, mpi_t * params) +_gnutls_x509_read_dsa_params (opaque * der, int dersize, bigint_t * params) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; @@ -154,7 +154,7 @@ _gnutls_x509_read_dsa_params (opaque * der, int dersize, mpi_t * params) */ int -_gnutls_x509_read_der_int (opaque * der, int dersize, mpi_t * out) +_gnutls_x509_read_der_int (opaque * der, int dersize, bigint_t * out) { int result; ASN1_TYPE spk = ASN1_TYPE_EMPTY; @@ -197,7 +197,7 @@ _gnutls_x509_read_der_int (opaque * der, int dersize, mpi_t * out) * only sets params[3] */ int -_gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params) +_gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params) { return _gnutls_x509_read_der_int( der, dersize, ¶ms[3]); } @@ -207,7 +207,7 @@ _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params) */ int _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, - mpi_t * params, int *params_size) + bigint_t * params, int *params_size) { int result; int pk_algorithm; @@ -237,7 +237,7 @@ _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, if (*params_size < RSA_PUBLIC_PARAMS) { gnutls_assert (); - /* internal error. Increase the mpi_ts in params */ + /* internal error. Increase the bigint_ts in params */ result = GNUTLS_E_INTERNAL_ERROR; goto error; } @@ -260,7 +260,7 @@ _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, if (*params_size < DSA_PUBLIC_PARAMS) { gnutls_assert (); - /* internal error. Increase the mpi_ts in params */ + /* internal error. Increase the bigint_ts in params */ result = GNUTLS_E_INTERNAL_ERROR; goto error; } @@ -323,7 +323,7 @@ error: * Allocates the space used to store the DER data. */ int -_gnutls_x509_write_rsa_params (mpi_t * params, int params_size, +_gnutls_x509_write_rsa_params (bigint_t * params, int params_size, gnutls_datum_t * der) { int result; @@ -384,7 +384,7 @@ cleanup: int _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name, gnutls_pk_algorithm_t pk_algorithm, - gnutls_digest_algorithm_t dig, mpi_t * params, + gnutls_digest_algorithm_t dig, bigint_t * params, int params_size) { gnutls_datum_t der; @@ -457,7 +457,7 @@ _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name, * Allocates the space used to store the DER data. */ int -_gnutls_x509_write_dsa_params (mpi_t * params, int params_size, +_gnutls_x509_write_dsa_params (bigint_t * params, int params_size, gnutls_datum_t * der) { int result; @@ -523,7 +523,7 @@ cleanup: * Allocates the space used to store the DER data. */ int -_gnutls_x509_write_dsa_public_key (mpi_t * params, int params_size, +_gnutls_x509_write_dsa_public_key (bigint_t * params, int params_size, gnutls_datum_t * der) { int result; diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c index 060cc2e3b3..3fc73ea9b2 100644 --- a/lib/x509/pkcs12.c +++ b/lib/x509/pkcs12.c @@ -909,7 +909,7 @@ gnutls_pkcs12_generate_mac (gnutls_pkcs12_t pkcs12, const char *pass) /* Generate the key. */ - result = _pkcs12_string_to_key (3 /*MAC*/, salt, sizeof (salt), + result = _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt, sizeof (salt), iter, pass, sizeof (key), key); if (result < 0) { @@ -1033,7 +1033,7 @@ gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12, const char *pass) /* Generate the key. */ - result = _pkcs12_string_to_key (3 /*MAC*/, salt.data, salt.size, + result = _gnutls_pkcs12_string_to_key (3 /*MAC*/, salt.data, salt.size, iter, pass, sizeof (key), key); if (result < 0) { diff --git a/lib/x509/pkcs12_encr.c b/lib/x509/pkcs12_encr.c index edbec8b702..6ed78f64f5 100644 --- a/lib/x509/pkcs12_encr.c +++ b/lib/x509/pkcs12_encr.c @@ -25,8 +25,7 @@ #ifdef ENABLE_PKI -#include <gcrypt.h> -#include <gc.h> +#include <gnutls_mpi.h> #include <gnutls_errors.h> /* Returns 0 if the password is ok, or a negative error @@ -54,19 +53,27 @@ _pkcs12_check_pass (const char *pass, size_t plen) * 1 for encryption key */ int -_pkcs12_string_to_key (unsigned int id, const opaque * salt, +_gnutls_pkcs12_string_to_key (unsigned int id, const opaque * salt, unsigned int salt_size, unsigned int iter, const char *pw, unsigned int req_keylen, opaque * keybuf) { int rc; unsigned int i, j; - gc_hash_handle md; - mpi_t num_b1 = NULL; + digest_hd_st md; + bigint_t num_b1 = NULL, num_ij = NULL; + bigint_t mpi512 = NULL; unsigned int pwlen; opaque hash[20], buf_b[64], buf_i[128], *p; size_t cur_keylen; size_t n; + const opaque buf_512[] = /* 2^64 */ + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; cur_keylen = 0; @@ -87,6 +94,13 @@ _pkcs12_string_to_key (unsigned int id, const opaque * salt, return rc; } + rc = _gnutls_mpi_scan (&mpi512, buf_512, sizeof(buf_512)); + if (rc < 0) + { + gnutls_assert(); + return rc; + } + /* Store salt and password in BUF_I */ p = buf_i; for (i = 0; i < 64; i++) @@ -106,64 +120,75 @@ _pkcs12_string_to_key (unsigned int id, const opaque * salt, for (;;) { - rc = gc_hash_open (GC_SHA1, 0, &md); - if (rc) + rc = _gnutls_hash_init (&md, GNUTLS_MAC_SHA1); + if (rc < 0) { gnutls_assert (); - return GNUTLS_E_DECRYPTION_FAILED; + goto cleanup; } for (i = 0; i < 64; i++) { unsigned char lid = id & 0xFF; - gc_hash_write (md, 1, &lid); + _gnutls_hash (&md, &lid, 1); } - gc_hash_write (md, pw ? 128 : 64, buf_i); - memcpy (hash, gc_hash_read (md), 20); - gc_hash_close (md); + _gnutls_hash( &md, buf_i, pw ? 128 : 64); + _gnutls_hash_deinit( &md, hash); for (i = 1; i < iter; i++) - gc_hash_buffer (GC_SHA1, hash, 20, hash); + { + rc = _gnutls_hash_init (&md, GNUTLS_MAC_SHA1); + if (rc < 0) + { + gnutls_assert(); + goto cleanup; + } + _gnutls_hash( &md, hash, 20); + _gnutls_hash_deinit( &md, hash); + } for (i = 0; i < 20 && cur_keylen < req_keylen; i++) keybuf[cur_keylen++] = hash[i]; if (cur_keylen == req_keylen) { - gcry_mpi_release (num_b1); - return 0; /* ready */ + rc = 0; /* ready */ + goto cleanup; } /* need more bytes. */ for (i = 0; i < 64; i++) buf_b[i] = hash[i % 20]; n = 64; - rc = _gnutls_mpi_scan (&num_b1, buf_b, &n); + rc = _gnutls_mpi_scan (&num_b1, buf_b, n); if (rc < 0) { gnutls_assert (); - return rc; + goto cleanup; } - gcry_mpi_add_ui (num_b1, num_b1, 1); + _gnutls_mpi_add_ui (num_b1, num_b1, 1); for (i = 0; i < 128; i += 64) { - mpi_t num_ij; - n = 64; - rc = _gnutls_mpi_scan (&num_ij, buf_i + i, &n); + rc = _gnutls_mpi_scan (&num_ij, buf_i + i, n); if (rc < 0) { gnutls_assert (); - return rc; + goto cleanup; } - gcry_mpi_add (num_ij, num_ij, num_b1); - gcry_mpi_clear_highbit (num_ij, 64 * 8); + _gnutls_mpi_addm (num_ij, num_ij, num_b1, mpi512); n = 64; - rc = _gnutls_mpi_print (buf_i + i, &n, num_ij); + rc = _gnutls_mpi_print (num_ij, buf_i + i, &n); if (rc < 0) { gnutls_assert (); - return rc; + goto cleanup; } - gcry_mpi_release (num_ij); + _gnutls_mpi_release (&num_ij); } } +cleanup: + _gnutls_mpi_release (&num_ij); + _gnutls_mpi_release (&num_b1); + _gnutls_mpi_release (&mpi512); + + return rc; } #endif /* ENABLE_PKI */ diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c index 2ea3e1016d..61a95d212b 100644 --- a/lib/x509/privkey.c +++ b/lib/x509/privkey.c @@ -32,9 +32,10 @@ #include <gnutls_x509.h> #include <x509_b64.h> #include <x509_int.h> +#include <gnutls_pk.h> -static int _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params); -int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params); +static int _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params); +int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, bigint_t * params); /* remove this when libgcrypt can handle the PKCS #1 coefficients from * rsa keys @@ -156,6 +157,11 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, { int result; ASN1_TYPE pkey_asn; + bigint_t temp_params[RSA_PRIVATE_PARAMS]; + gnutls_pk_params_st pk_params; + + pk_params.params = temp_params; + pk_params.params_nr = RSA_PRIVATE_PARAMS; if ((result = asn1_create_element (_gnutls_get_gnutls_asn (), @@ -166,10 +172,10 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, return NULL; } - if ((sizeof (pkey->params) / sizeof (mpi_t)) < RSA_PRIVATE_PARAMS) + if ((sizeof (pkey->params) / sizeof (bigint_t)) < RSA_PRIVATE_PARAMS) { gnutls_assert (); - /* internal error. Increase the mpi_ts in params */ + /* internal error. Increase the bigint_ts in params */ return NULL; } @@ -181,7 +187,7 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, } if ((result = _gnutls_x509_read_int (pkey_asn, "modulus", - &pkey->params[0])) < 0) + &pk_params.params[0])) < 0) { gnutls_assert (); goto error; @@ -189,7 +195,7 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, if ((result = _gnutls_x509_read_int (pkey_asn, "publicExponent", - &pkey->params[1])) < 0) + &pk_params.params[1])) < 0) { gnutls_assert (); goto error; @@ -197,61 +203,59 @@ _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key, if ((result = _gnutls_x509_read_int (pkey_asn, "privateExponent", - &pkey->params[2])) < 0) + &pk_params.params[2])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "prime1", - &pkey->params[3])) < 0) + &pk_params.params[3])) < 0) { gnutls_assert (); goto error; } if ((result = _gnutls_x509_read_int (pkey_asn, "prime2", - &pkey->params[4])) < 0) + &pk_params.params[4])) < 0) { gnutls_assert (); goto error; } -#ifdef CALC_COEFF - /* Calculate the coefficient. This is because the gcrypt - * library is uses the p,q in the reverse order. - */ - pkey->params[5] = - _gnutls_mpi_snew (_gnutls_mpi_get_nbits (pkey->params[0])); - - if (pkey->params[5] == NULL) + if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient", + &pk_params.params[5])) < 0) { gnutls_assert (); goto error; } - _gnutls_mpi_invm (pkey->params[5], pkey->params[3], pkey->params[4]); - /* p, q */ -#else - if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient", - &pkey->params[5])) < 0) + + result = _gnutls_pk_fixup( GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params); + if (result < 0) { - gnutls_assert (); + gnutls_assert(); goto error; } -#endif - pkey->params_size = 6; + + pkey->params[0] = pk_params.params[0]; + pkey->params[1] = pk_params.params[1]; + pkey->params[2] = pk_params.params[2]; + pkey->params[3] = pk_params.params[3]; + pkey->params[4] = pk_params.params[4]; + pkey->params[5] = pk_params.params[5]; + pkey->params_size = pk_params.params_nr; return pkey_asn; error: asn1_delete_structure (&pkey_asn); - _gnutls_mpi_release (&pkey->params[0]); - _gnutls_mpi_release (&pkey->params[1]); - _gnutls_mpi_release (&pkey->params[2]); - _gnutls_mpi_release (&pkey->params[3]); - _gnutls_mpi_release (&pkey->params[4]); - _gnutls_mpi_release (&pkey->params[5]); + _gnutls_mpi_release (&pk_params.params[0]); + _gnutls_mpi_release (&pk_params.params[1]); + _gnutls_mpi_release (&pk_params.params[2]); + _gnutls_mpi_release (&pk_params.params[3]); + _gnutls_mpi_release (&pk_params.params[4]); + _gnutls_mpi_release (&pk_params.params[5]); return NULL; } @@ -271,10 +275,10 @@ decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey) return NULL; } - if ((sizeof (pkey->params) / sizeof (mpi_t)) < DSA_PRIVATE_PARAMS) + if ((sizeof (pkey->params) / sizeof (bigint_t)) < DSA_PRIVATE_PARAMS) { gnutls_assert (); - /* internal error. Increase the mpi_ts in params */ + /* internal error. Increase the bigint_ts in params */ return NULL; } @@ -452,7 +456,7 @@ cleanup: } #define FREE_RSA_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \ - _gnutls_mpi_release(&key->params[i]) + _gnutls_mpi_release(&pk_params.params[i]) #define FREE_DSA_PRIVATE_PARAMS for (i=0;i<DSA_PRIVATE_PARAMS;i++) \ _gnutls_mpi_release(&key->params[i]) @@ -484,6 +488,11 @@ gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key, { int i = 0, ret; size_t siz = 0; + bigint_t temp_params[RSA_PRIVATE_PARAMS]; + gnutls_pk_params_st pk_params; + + pk_params.params = temp_params; + pk_params.params_nr = RSA_PRIVATE_PARAMS; if (key == NULL) { @@ -492,7 +501,7 @@ gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key, } siz = m->size; - if (_gnutls_mpi_scan_nz (&key->params[0], m->data, &siz)) + if (_gnutls_mpi_scan_nz (&pk_params.params[0], m->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; @@ -500,7 +509,7 @@ gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key, } siz = e->size; - if (_gnutls_mpi_scan_nz (&key->params[1], e->data, &siz)) + if (_gnutls_mpi_scan_nz (&pk_params.params[1], e->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; @@ -508,7 +517,7 @@ gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key, } siz = d->size; - if (_gnutls_mpi_scan_nz (&key->params[2], d->data, &siz)) + if (_gnutls_mpi_scan_nz (&pk_params.params[2], d->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; @@ -516,7 +525,7 @@ gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key, } siz = p->size; - if (_gnutls_mpi_scan_nz (&key->params[3], p->data, &siz)) + if (_gnutls_mpi_scan_nz (&pk_params.params[3], p->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; @@ -524,33 +533,28 @@ gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key, } siz = q->size; - if (_gnutls_mpi_scan_nz (&key->params[4], q->data, &siz)) + if (_gnutls_mpi_scan_nz (&pk_params.params[4], q->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; return GNUTLS_E_MPI_SCAN_FAILED; } -#ifdef CALC_COEFF - key->params[5] = _gnutls_mpi_snew (_gnutls_mpi_get_nbits (key->params[0])); - - if (key->params[5] == NULL) + siz = u->size; + if (_gnutls_mpi_scan_nz (&pk_params.params[5], u->data, siz)) { gnutls_assert (); FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MEMORY_ERROR; + return GNUTLS_E_MPI_SCAN_FAILED; } - _gnutls_mpi_invm (key->params[5], key->params[3], key->params[4]); -#else - siz = u->size; - if (_gnutls_mpi_scan_nz (&key->params[5], u->data, &siz)) + ret = _gnutls_pk_fixup( GNUTLS_PK_RSA, GNUTLS_IMPORT, &pk_params); + if (ret < 0) { - gnutls_assert (); + gnutls_assert(); FREE_RSA_PRIVATE_PARAMS; - return GNUTLS_E_MPI_SCAN_FAILED; + return ret; } -#endif if (!key->crippled) { @@ -563,7 +567,13 @@ gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key, } } - key->params_size = RSA_PRIVATE_PARAMS; + key->params[0] = pk_params.params[0]; + key->params[1] = pk_params.params[1]; + key->params[2] = pk_params.params[2]; + key->params[3] = pk_params.params[3]; + key->params[4] = pk_params.params[4]; + key->params[5] = pk_params.params[5]; + key->params_size = pk_params.params_nr; key->pk_algorithm = GNUTLS_PK_RSA; return 0; @@ -604,7 +614,7 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key, } siz = p->size; - if (_gnutls_mpi_scan_nz (&key->params[0], p->data, &siz)) + if (_gnutls_mpi_scan_nz (&key->params[0], p->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; @@ -612,7 +622,7 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key, } siz = q->size; - if (_gnutls_mpi_scan_nz (&key->params[1], q->data, &siz)) + if (_gnutls_mpi_scan_nz (&key->params[1], q->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; @@ -620,7 +630,7 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key, } siz = g->size; - if (_gnutls_mpi_scan_nz (&key->params[2], g->data, &siz)) + if (_gnutls_mpi_scan_nz (&key->params[2], g->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; @@ -628,7 +638,7 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key, } siz = y->size; - if (_gnutls_mpi_scan_nz (&key->params[3], y->data, &siz)) + if (_gnutls_mpi_scan_nz (&key->params[3], y->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; @@ -636,7 +646,7 @@ gnutls_x509_privkey_import_dsa_raw (gnutls_x509_privkey_t key, } siz = x->size; - if (_gnutls_mpi_scan_nz (&key->params[4], x->data, &siz)) + if (_gnutls_mpi_scan_nz (&key->params[4], x->data, siz)) { gnutls_assert (); FREE_DSA_PRIVATE_PARAMS; @@ -783,7 +793,7 @@ gnutls_x509_privkey_export_rsa_raw (gnutls_x509_privkey_t key, gnutls_datum_t * q, gnutls_datum_t * u) { int ret; - mpi_t coeff = NULL; + gnutls_pk_params_st pk_params; if (key == NULL) { @@ -793,74 +803,69 @@ gnutls_x509_privkey_export_rsa_raw (gnutls_x509_privkey_t key, m->data = e->data = d->data = p->data = q->data = u->data = NULL; m->size = e->size = d->size = p->size = q->size = u->size = 0; - - ret = _gnutls_mpi_dprint (m, key->params[0]); + + ret = _gnutls_pk_params_copy( &pk_params, key->params, RSA_PRIVATE_PARAMS); if (ret < 0) { gnutls_assert (); - goto error; + return ret; } - - /* E */ - ret = _gnutls_mpi_dprint (e, key->params[1]); + + ret = _gnutls_pk_fixup( GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params); if (ret < 0) { - gnutls_assert (); + gnutls_assert(); goto error; } - /* D */ - ret = _gnutls_mpi_dprint (d, key->params[2]); + ret = _gnutls_mpi_dprint (pk_params.params[0], m); if (ret < 0) { gnutls_assert (); goto error; } - /* P */ - ret = _gnutls_mpi_dprint (p, key->params[3]); + /* E */ + ret = _gnutls_mpi_dprint (pk_params.params[1], e); if (ret < 0) { gnutls_assert (); goto error; } - /* Q */ - ret = _gnutls_mpi_dprint (q, key->params[4]); + /* D */ + ret = _gnutls_mpi_dprint (pk_params.params[2], d); if (ret < 0) { gnutls_assert (); goto error; } -#ifdef CALC_COEFF - coeff = _gnutls_mpi_snew (_gnutls_mpi_get_nbits (key->params[0])); - - if (coeff == NULL) + /* P */ + ret = _gnutls_mpi_dprint (pk_params.params[3], p); + if (ret < 0) { gnutls_assert (); - ret = GNUTLS_E_MEMORY_ERROR; goto error; } - _gnutls_mpi_invm (coeff, key->params[4], key->params[3]); - ret = _gnutls_mpi_dprint (u, coeff); + /* Q */ + ret = _gnutls_mpi_dprint (pk_params.params[4], q); if (ret < 0) { gnutls_assert (); goto error; } - _gnutls_mpi_release (&coeff); -#else /* U */ - ret = _gnutls_mpi_dprint (u, key->params[5]); + ret = _gnutls_mpi_dprint (key->params[5], u); if (ret < 0) { gnutls_assert (); goto error; } -#endif + + gnutls_pk_params_release( &pk_params); return 0; @@ -870,7 +875,7 @@ error: _gnutls_free_datum (e); _gnutls_free_datum (p); _gnutls_free_datum (q); - _gnutls_mpi_release (&coeff); + gnutls_pk_params_release( &pk_params); return ret; } @@ -906,7 +911,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, } /* P */ - ret = _gnutls_mpi_dprint (p, key->params[0]); + ret = _gnutls_mpi_dprint (key->params[0], p); if (ret < 0) { gnutls_assert (); @@ -914,7 +919,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, } /* Q */ - ret = _gnutls_mpi_dprint (q, key->params[1]); + ret = _gnutls_mpi_dprint (key->params[1], q); if (ret < 0) { gnutls_assert (); @@ -924,7 +929,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, /* G */ - ret = _gnutls_mpi_dprint (g, key->params[2]); + ret = _gnutls_mpi_dprint (key->params[2], g); if (ret < 0) { gnutls_assert (); @@ -935,7 +940,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, /* Y */ - ret = _gnutls_mpi_dprint (y, key->params[3]); + ret = _gnutls_mpi_dprint (key->params[3], y); if (ret < 0) { gnutls_assert (); @@ -946,7 +951,7 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, } /* X */ - ret = _gnutls_mpi_dprint (x, key->params[4]); + ret = _gnutls_mpi_dprint (key->params[4], x); if (ret < 0) { gnutls_assert (); @@ -964,83 +969,83 @@ gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key, /* Encodes the RSA parameters into an ASN.1 RSA private key structure. */ static int -_gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params) +_gnutls_asn1_encode_rsa (ASN1_TYPE * c2, bigint_t * params) { int result, i; size_t size[8], total; opaque *m_data, *pube_data, *prie_data; opaque *p1_data, *p2_data, *u_data, *exp1_data, *exp2_data; opaque *all_data = NULL, *p; - mpi_t exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL, u = NULL; + bigint_t exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL; opaque null = '\0'; + gnutls_pk_params_st pk_params; /* Read all the sizes */ total = 0; for (i = 0; i < 5; i++) { - _gnutls_mpi_print_lz (NULL, &size[i], params[i]); + _gnutls_mpi_print_lz (params[i], NULL, &size[i]); total += size[i]; } - /* Now generate exp1 and exp2 - */ - exp1 = _gnutls_mpi_salloc_like (params[0]); /* like modulus */ - if (exp1 == NULL) + result = _gnutls_pk_params_copy( &pk_params, params, RSA_PRIVATE_PARAMS); + if (result < 0) { gnutls_assert (); - result = GNUTLS_E_MEMORY_ERROR; + return result; + } + + result = _gnutls_pk_fixup( GNUTLS_PK_RSA, GNUTLS_EXPORT, &pk_params); + if (result < 0) + { + gnutls_assert(); goto cleanup; } - exp2 = _gnutls_mpi_salloc_like (params[0]); - if (exp2 == NULL) + q1 = _gnutls_mpi_alloc_like (pk_params.params[4]); + if (q1 == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } - q1 = _gnutls_mpi_salloc_like (params[4]); - if (q1 == NULL) + p1 = _gnutls_mpi_alloc_like (pk_params.params[3]); + if (p1 == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } - p1 = _gnutls_mpi_salloc_like (params[3]); - if (p1 == NULL) + /* inverse of q mod p */ + _gnutls_mpi_print_lz (pk_params.params[5], NULL, &size[5]); + total += size[5]; + + _gnutls_mpi_sub_ui (p1, pk_params.params[3], 1); + _gnutls_mpi_sub_ui (q1, pk_params.params[4], 1); + + exp1 = _gnutls_mpi_mod (pk_params.params[2], p1); + if (exp1 == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } - u = _gnutls_mpi_salloc_like (params[3]); - if (u == NULL) + exp2 = _gnutls_mpi_mod (pk_params.params[2], q1); + if (exp2 == NULL) { gnutls_assert (); result = GNUTLS_E_MEMORY_ERROR; goto cleanup; } - _gnutls_mpi_invm (u, params[4], params[3]); - /* inverse of q mod p */ - _gnutls_mpi_print_lz (NULL, &size[5], u); - total += size[5]; - - _gnutls_mpi_sub_ui (p1, params[3], 1); - _gnutls_mpi_sub_ui (q1, params[4], 1); - - _gnutls_mpi_mod (exp1, params[2], p1); - _gnutls_mpi_mod (exp2, params[2], q1); - - /* calculate exp's size */ - _gnutls_mpi_print_lz (NULL, &size[6], exp1); + _gnutls_mpi_print_lz (exp1, NULL, &size[6]); total += size[6]; - _gnutls_mpi_print_lz (NULL, &size[7], exp2); + _gnutls_mpi_print_lz (exp2, NULL, &size[7]); total += size[7]; /* Encoding phase. @@ -1071,14 +1076,14 @@ _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params) p += size[6]; exp2_data = p; - _gnutls_mpi_print_lz (m_data, &size[0], params[0]); - _gnutls_mpi_print_lz (pube_data, &size[1], params[1]); - _gnutls_mpi_print_lz (prie_data, &size[2], params[2]); - _gnutls_mpi_print_lz (p1_data, &size[3], params[3]); - _gnutls_mpi_print_lz (p2_data, &size[4], params[4]); - _gnutls_mpi_print_lz (u_data, &size[5], u); - _gnutls_mpi_print_lz (exp1_data, &size[6], exp1); - _gnutls_mpi_print_lz (exp2_data, &size[7], exp2); + _gnutls_mpi_print_lz (pk_params.params[0], m_data, &size[0]); + _gnutls_mpi_print_lz (pk_params.params[1], pube_data, &size[1]); + _gnutls_mpi_print_lz (pk_params.params[2], prie_data, &size[2]); + _gnutls_mpi_print_lz (pk_params.params[3], p1_data, &size[3]); + _gnutls_mpi_print_lz (pk_params.params[4], p2_data, &size[4]); + _gnutls_mpi_print_lz (pk_params.params[5], u_data, &size[5]); + _gnutls_mpi_print_lz (exp1, exp1_data, &size[6]); + _gnutls_mpi_print_lz (exp2, exp2_data, &size[7]); /* Ok. Now we have the data. Create the asn1 structures */ @@ -1162,7 +1167,7 @@ _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params) _gnutls_mpi_release (&exp2); _gnutls_mpi_release (&q1); _gnutls_mpi_release (&p1); - _gnutls_mpi_release (&u); + gnutls_pk_params_release( &pk_params); gnutls_free (all_data); if ((result = asn1_write_value (*c2, "otherPrimeInfos", @@ -1183,11 +1188,11 @@ _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params) return 0; cleanup: - _gnutls_mpi_release (&u); _gnutls_mpi_release (&exp1); _gnutls_mpi_release (&exp2); _gnutls_mpi_release (&q1); _gnutls_mpi_release (&p1); + gnutls_pk_params_release( &pk_params); asn1_delete_structure (c2); gnutls_free (all_data); @@ -1197,7 +1202,7 @@ cleanup: /* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure. */ int -_gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params) +_gnutls_asn1_encode_dsa (ASN1_TYPE * c2, bigint_t * params) { int result, i; size_t size[DSA_PRIVATE_PARAMS], total; @@ -1209,7 +1214,7 @@ _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params) total = 0; for (i = 0; i < DSA_PRIVATE_PARAMS; i++) { - _gnutls_mpi_print_lz (NULL, &size[i], params[i]); + _gnutls_mpi_print_lz (params[i], NULL, &size[i]); total += size[i]; } @@ -1235,11 +1240,11 @@ _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params) p += size[3]; x_data = p; - _gnutls_mpi_print_lz (p_data, &size[0], params[0]); - _gnutls_mpi_print_lz (q_data, &size[1], params[1]); - _gnutls_mpi_print_lz (g_data, &size[2], params[2]); - _gnutls_mpi_print_lz (y_data, &size[3], params[3]); - _gnutls_mpi_print_lz (x_data, &size[4], params[4]); + _gnutls_mpi_print_lz (params[0], p_data, &size[0]); + _gnutls_mpi_print_lz (params[1], q_data, &size[1]); + _gnutls_mpi_print_lz (params[2], g_data, &size[2]); + _gnutls_mpi_print_lz (params[3], y_data, &size[3]); + _gnutls_mpi_print_lz (params[4], x_data, &size[4]); /* Ok. Now we have the data. Create the asn1 structures */ @@ -1328,8 +1333,9 @@ gnutls_x509_privkey_generate (gnutls_x509_privkey_t key, gnutls_pk_algorithm_t algo, unsigned int bits, unsigned int flags) { - int ret, params_len; - int i; + int ret; + unsigned int params_len; + unsigned int i; if (key == NULL) { diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c index 84fce06d78..0026d1d728 100644 --- a/lib/x509/privkey_pkcs8.c +++ b/lib/x509/privkey_pkcs8.c @@ -692,7 +692,7 @@ read_pkcs_schema_params (schema_id schema, const char *password, if (enc_params->iv_size) { result = - _pkcs12_string_to_key (2 /*IV*/, kdf_params->salt, + _gnutls_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt, kdf_params->salt_size, kdf_params->iter_count, password, enc_params->iv_size, enc_params->iv); @@ -1504,7 +1504,7 @@ decrypt_data (schema_id schema, ASN1_TYPE pkcs8_asn, else { result = - _pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt, + _gnutls_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt, kdf_params->salt_size, kdf_params->iter_count, password, key_size, key); @@ -1818,7 +1818,7 @@ generate_key (schema_id schema, else { /* PKCS12 schemas */ ret = - _pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt, + _gnutls_pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt, kdf_params->salt_size, kdf_params->iter_count, password, kdf_params->key_size, key->data); @@ -1833,7 +1833,7 @@ generate_key (schema_id schema, if (enc_params->iv_size) { ret = - _pkcs12_string_to_key (2 /*IV*/, kdf_params->salt, + _gnutls_pkcs12_string_to_key (2 /*IV*/, kdf_params->salt, kdf_params->salt_size, kdf_params->iter_count, password, enc_params->iv_size, enc_params->iv); diff --git a/lib/x509/sign.c b/lib/x509/sign.c index cd94be8aee..79ebda0425 100644 --- a/lib/x509/sign.c +++ b/lib/x509/sign.c @@ -129,7 +129,7 @@ encode_ber_digest_info (gnutls_digest_algorithm_t hash, */ static int pkcs1_rsa_sign (gnutls_digest_algorithm_t hash, const gnutls_datum_t * text, - mpi_t * params, int params_len, gnutls_datum_t * signature) + bigint_t * params, int params_len, gnutls_datum_t * signature) { int ret; opaque _digest[MAX_HASH_SIZE]; @@ -173,7 +173,7 @@ pkcs1_rsa_sign (gnutls_digest_algorithm_t hash, const gnutls_datum_t * text, static int dsa_sign (const gnutls_datum_t * text, - mpi_t * params, int params_len, gnutls_datum_t * signature) + bigint_t * params, int params_len, gnutls_datum_t * signature) { int ret; opaque _digest[MAX_HASH_SIZE]; diff --git a/lib/x509/verify.c b/lib/x509/verify.c index ecca86a2d2..34ba499137 100644 --- a/lib/x509/verify.c +++ b/lib/x509/verify.c @@ -535,7 +535,7 @@ decode_ber_digest_info (const gnutls_datum_t * info, */ static int _pkcs1_rsa_verify_sig (const gnutls_datum_t * text, - const gnutls_datum_t * signature, mpi_t * params, + const gnutls_datum_t * signature, bigint_t * params, int params_len) { gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN; @@ -596,7 +596,7 @@ _pkcs1_rsa_verify_sig (const gnutls_datum_t * text, */ static int dsa_verify_sig (const gnutls_datum_t * text, - const gnutls_datum_t * signature, mpi_t * params, + const gnutls_datum_t * signature, bigint_t * params, int params_len) { int ret; @@ -628,7 +628,7 @@ dsa_verify_sig (const gnutls_datum_t * text, static int verify_sig (const gnutls_datum_t * tbs, const gnutls_datum_t * signature, - gnutls_pk_algorithm_t pk, mpi_t * issuer_params, + gnutls_pk_algorithm_t pk, bigint_t * issuer_params, int issuer_params_size) { @@ -674,7 +674,7 @@ _gnutls_x509_verify_signature (const gnutls_datum_t * tbs, const gnutls_datum_t * signature, gnutls_x509_crt_t issuer) { - mpi_t issuer_params[MAX_PUBLIC_PARAMS_SIZE]; + bigint_t issuer_params[MAX_PUBLIC_PARAMS_SIZE]; int ret, issuer_params_size, i; /* Read the MPI parameters from the issuer's certificate. diff --git a/lib/x509/x509.c b/lib/x509/x509.c index d6d9569e18..e621cdef65 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -533,7 +533,7 @@ gnutls_x509_crt_get_signature (gnutls_x509_crt_t cert, len = bits / 8; - if (*sizeof_sig < len) + if (*sizeof_sig < (unsigned int)len) { *sizeof_sig = bits / 8; return GNUTLS_E_SHORT_MEMORY_BUFFER; @@ -909,7 +909,7 @@ parse_general_name (ASN1_TYPE src, const char *src_name, int seq, void *name, size_t * name_size, unsigned int* ret_type, int othername_oid) { - int len; + unsigned int len; char nptr[MAX_NAME_SIZE]; int result; opaque choice_type[128]; @@ -2042,7 +2042,7 @@ rsadsa_get_key_id (gnutls_x509_crt_t crt, int pk, unsigned char *output_data, size_t * output_data_size) { - mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; int params_size = MAX_PUBLIC_PARAMS_SIZE; int i, result = 0; gnutls_datum_t der = { NULL, 0 }; @@ -2589,7 +2589,7 @@ gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt, gnutls_datum_t * m, gnutls_datum_t * e) { int ret; - mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; int params_size = MAX_PUBLIC_PARAMS_SIZE; int i; @@ -2613,14 +2613,14 @@ gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt, return ret; } - ret = _gnutls_mpi_dprint (m, params[0]); + ret = _gnutls_mpi_dprint (params[0], m); if (ret < 0) { gnutls_assert (); goto cleanup; } - ret = _gnutls_mpi_dprint (e, params[1]); + ret = _gnutls_mpi_dprint (params[1], e); if (ret < 0) { gnutls_assert (); @@ -2658,7 +2658,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, gnutls_datum_t * g, gnutls_datum_t * y) { int ret; - mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; + bigint_t params[MAX_PUBLIC_PARAMS_SIZE]; int params_size = MAX_PUBLIC_PARAMS_SIZE; int i; @@ -2684,7 +2684,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, /* P */ - ret = _gnutls_mpi_dprint (p, params[0]); + ret = _gnutls_mpi_dprint (params[0], p); if (ret < 0) { gnutls_assert (); @@ -2692,7 +2692,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, } /* Q */ - ret = _gnutls_mpi_dprint (q, params[1]); + ret = _gnutls_mpi_dprint (params[1], q); if (ret < 0) { gnutls_assert (); @@ -2702,7 +2702,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, /* G */ - ret = _gnutls_mpi_dprint (g, params[2]); + ret = _gnutls_mpi_dprint (params[2], g); if (ret < 0) { gnutls_assert (); @@ -2713,7 +2713,7 @@ gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt, /* Y */ - ret = _gnutls_mpi_dprint (y, params[3]); + ret = _gnutls_mpi_dprint (params[3], y); if (ret < 0) { gnutls_assert (); diff --git a/lib/x509/x509_int.h b/lib/x509/x509_int.h index a70db6237e..169b223a6c 100644 --- a/lib/x509/x509_int.h +++ b/lib/x509/x509_int.h @@ -77,7 +77,7 @@ typedef struct gnutls_x509_privkey_int /* the size of params depends on the public * key algorithm */ - mpi_t params[MAX_PRIV_PARAMS_SIZE]; + bigint_t params[MAX_PRIV_PARAMS_SIZE]; /* * RSA: [0] is modulus @@ -161,7 +161,6 @@ int _gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct, int indx, void *_oid, size_t * sizeof_oid); /* dsa.c */ -int _gnutls_dsa_generate_params (mpi_t * resarr, int *resarr_len, int bits); /* verify.c */ @@ -177,7 +176,7 @@ int _gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs, /* privkey.h */ ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t *raw_key, gnutls_x509_privkey_t pkey); -int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params); +int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, bigint_t * params); /* extensions.c */ int _gnutls_x509_crt_get_extension (gnutls_x509_crt_t cert, @@ -226,33 +225,33 @@ int _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint, /* mpi.c */ int _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert, - mpi_t * params, int *params_size); -int _gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params); -int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params); -int _gnutls_x509_read_dsa_params (opaque * der, int dersize, mpi_t * params); + bigint_t * params, int *params_size); +int _gnutls_x509_read_rsa_params (opaque * der, int dersize, bigint_t * params); +int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, bigint_t * params); +int _gnutls_x509_read_dsa_params (opaque * der, int dersize, bigint_t * params); -int _gnutls_x509_write_rsa_params (mpi_t * params, int params_size, +int _gnutls_x509_write_rsa_params (bigint_t * params, int params_size, gnutls_datum_t * der); -int _gnutls_x509_write_dsa_params (mpi_t * params, int params_size, +int _gnutls_x509_write_dsa_params (bigint_t * params, int params_size, gnutls_datum_t * der); -int _gnutls_x509_write_dsa_public_key (mpi_t * params, int params_size, +int _gnutls_x509_write_dsa_public_key (bigint_t * params, int params_size, gnutls_datum_t * der); int _gnutls_x509_read_uint (ASN1_TYPE node, const char *value, unsigned int *ret); -int _gnutls_x509_read_der_int (opaque * der, int dersize, mpi_t* out); +int _gnutls_x509_read_der_int (opaque * der, int dersize, bigint_t* out); int _gnutls_x509_read_int (ASN1_TYPE node, const char *value, - mpi_t * ret_mpi); -int _gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi, + bigint_t * ret_mpi); +int _gnutls_x509_write_int (ASN1_TYPE node, const char *value, bigint_t mpi, int lz); int _gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value, uint32_t num); int _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name, gnutls_pk_algorithm_t pk_algorithm, - gnutls_digest_algorithm_t, mpi_t * params, + gnutls_digest_algorithm_t, bigint_t * params, int params_size); /* pkcs12.h */ #include <gnutls/pkcs12.h> @@ -294,7 +293,7 @@ typedef struct gnutls_pkcs12_bag_int #define KEY_ID_OID "1.2.840.113549.1.9.21" int -_pkcs12_string_to_key (unsigned int id, const opaque * salt, +_gnutls_pkcs12_string_to_key (unsigned int id, const opaque * salt, unsigned int salt_size, unsigned int iter, const char *pw, unsigned int req_keylen, opaque * keybuf); diff --git a/src/psk-gaa.c b/src/psk-gaa.c index f3e58592f7..f10b2efd2b 100644 --- a/src/psk-gaa.c +++ b/src/psk-gaa.c @@ -738,7 +738,7 @@ static int gaa_internal_get_next_str(FILE *file, gaa_str_node *tmp_str, int argc len++; a = fgetc( file); - if(a==EOF) return 0; /* a = ' '; */ + if(a==EOF) return 0; //a = ' '; } len += 1; diff --git a/tests/Makefile.am b/tests/Makefile.am index 4684ec5066..47febc976b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -31,6 +31,7 @@ EXTRA_DIST = libgcrypt.supp AM_CPPFLAGS = -I$(top_srcdir)/lgl -I$(top_builddir)/lgl \ -I$(top_srcdir)/gl -I$(top_builddir)/gl \ -I$(top_srcdir)/includes -I$(top_builddir)/includes \ + -I$(top_srcdir)/lib \ -I$(top_srcdir)/doc/examples AM_LDFLAGS = -no-install LDADD = ../lib/libgnutls.la ../gl/libgnu.la ../lgl/liblgnu.la libutils.la @@ -38,7 +39,7 @@ LDADD = ../lib/libgnutls.la ../gl/libgnu.la ../lgl/liblgnu.la libutils.la noinst_LTLIBRARIES = libutils.la libutils_la_SOURCES = utils.h utils.c -ctests = simple openssl gc set_pkcs12_cred certder \ +ctests = simple openssl gc set_pkcs12_cred certder mpi \ certificate_set_x509_crl dn parse_ca moredn crypto_rng mini openssl_LDADD = $(LDADD) ../libextra/libgnutls-openssl.la diff --git a/tests/ca.pem b/tests/ca.pem index 4b7362ab6b..e69de29bb2 100644 --- a/tests/ca.pem +++ b/tests/ca.pem @@ -1,56 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 99999 (0x1869f) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=U.S. Government, OU=DoD, OU=Testing, CN=Trust Anchor - Validity - Not Before: Jan 1 12:01:00 1999 GMT - Not After : Jan 1 12:01:00 2048 GMT - Subject: C=US, O=U.S. Government, OU=DoD, OU=Testing, CN=Trust Anchor - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public Key: (1024 bit) - Modulus (1024 bit): - 00:d3:f3:b9:c1:33:b7:3f:a7:27:f6:41:1d:5c:9c: - 79:9d:aa:d2:95:10:b7:84:ce:da:a3:e5:58:0c:3e: - 4e:8b:56:bf:3e:aa:21:2d:50:13:fe:f3:19:2e:7a: - cb:11:cf:f3:d3:b8:5f:57:9f:9d:97:80:af:1d:95: - 57:12:df:34:d4:bd:f3:ae:4d:e7:7c:a6:20:d4:04: - 4e:da:63:61:3e:3d:2a:8d:37:cf:c5:3c:c9:f9:fa: - f0:39:48:04:78:bd:b0:dd:f5:24:46:33:a1:46:9f: - 17:9f:04:bb:cf:37:94:0c:13:43:aa:90:ac:91:78: - 1d:ba:f3:18:84:2a:82:2b:47 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Subject Key Identifier: - AB:9A:EB:F9:C2:E7:54:8F - X509v3 Basic Constraints: - CA:TRUE - X509v3 Authority Key Identifier: - keyid:AB:9A:EB:F9:C2:E7:54:8F - - Signature Algorithm: sha1WithRSAEncryption - 16:56:0f:61:ac:87:8b:4f:eb:64:12:1b:c3:85:59:4a:68:e1: - 3b:a5:21:c1:59:2e:91:ac:68:fe:13:ff:63:6d:ee:55:d4:a0: - 82:4c:37:bc:16:8e:a9:26:61:fe:7f:46:fa:38:1f:13:5c:8a: - 6a:b7:12:47:98:72:b9:b5:56:80:ee:78:95:18:1a:f4:63:70: - 26:39:9b:19:20:84:8d:bb:62:5f:df:2c:a1:3d:fc:1b:d0:3a: - bb:d8:cc:1b:36:12:a2:ab:ad:3e:e6:e1:52:b4:75:13:11:ec: - 27:95:a6:63:cf:d3:cc:f4:4e:d8:ba:b8:ad:ad:cc:1a:65:a7: - 5a:45 ------BEGIN CERTIFICATE----- -MIICbDCCAdWgAwIBAgIDAYafMA0GCSqGSIb3DQEBBQUAMF4xCzAJBgNVBAYTAlVT -MRgwFgYDVQQKEw9VLlMuIEdvdmVybm1lbnQxDDAKBgNVBAsTA0RvRDEQMA4GA1UE -CxMHVGVzdGluZzEVMBMGA1UEAxMMVHJ1c3QgQW5jaG9yMB4XDTk5MDEwMTEyMDEw -MFoXDTQ4MDEwMTEyMDEwMFowXjELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD1UuUy4g -R292ZXJubWVudDEMMAoGA1UECxMDRG9EMRAwDgYDVQQLEwdUZXN0aW5nMRUwEwYD -VQQDEwxUcnVzdCBBbmNob3IwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANPz -ucEztz+nJ/ZBHVyceZ2q0pUQt4TO2qPlWAw+TotWvz6qIS1QE/7zGS56yxHP89O4 -X1efnZeArx2VVxLfNNS9865N53ymINQETtpjYT49Ko03z8U8yfn68DlIBHi9sN31 -JEYzoUafF58Eu883lAwTQ6qQrJF4HbrzGIQqgitHAgMBAAGjODA2MBEGA1UdDgQK -BAirmuv5wudUjzAMBgNVHRMEBTADAQH/MBMGA1UdIwQMMAqACKua6/nC51SPMA0G -CSqGSIb3DQEBBQUAA4GBABZWD2Gsh4tP62QSG8OFWUpo4TulIcFZLpGsaP4T/2Nt -7lXUoIJMN7wWjqkmYf5/Rvo4HxNcimq3EkeYcrm1VoDueJUYGvRjcCY5mxkghI27 -Yl/fLKE9/BvQOrvYzBs2EqKrrT7m4VK0dRMR7CeVpmPP08z0Tti6uK2tzBplp1pF ------END CERTIFICATE----- diff --git a/tests/crypto_rng.c b/tests/crypto_rng.c index 2667178a06..663bf9813c 100644 --- a/tests/crypto_rng.c +++ b/tests/crypto_rng.c @@ -49,7 +49,7 @@ doit (void) memset(buf2, 1, sizeof(buf2)); - _gnutls_rnd(GNUTLS_RND_KEY, buf1, sizeof(buf1)); + _gnutls_rnd(GNUTLS_RND_RANDOM, buf1, sizeof(buf1)); if (memcmp( buf1, buf2, sizeof(buf1))!=0) failed = 1; diff --git a/tests/mpi.c b/tests/mpi.c new file mode 100644 index 0000000000..c33b446e0a --- /dev/null +++ b/tests/mpi.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2007 Free Software Foundation + * + * Author: Simon Josefsson + * + * This file is part of GNUTLS. + * + * GNUTLS 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 3 of the License, or + * (at your option) any later version. + * + * GNUTLS 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 GNUTLS; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> + +#include "utils.h" +#include "../lib/gnutls_int.h" +#include "../lib/gnutls_mpi.h" +#include "../lib/debug.h" + +static void +tls_log_func (int level, const char *str) +{ + fprintf (stderr, "|<%d>| %s", level, str); +} + +#define RND_BITS 510 /* not multiple of 8 */ +void +doit (void) +{ + int rc; + bigint_t n1, n2, n3, n4; + + gnutls_global_init(); + + gnutls_global_set_log_function (tls_log_func); + gnutls_global_set_log_level (99); + + n1 = _gnutls_mpi_new(1000); + if (n1 == NULL) + fail ("mpi_new failed\n"); + + n2 = _gnutls_mpi_set_ui( NULL, 2); + if (n2 == NULL) + fail ("mpi_set_ui failed\n"); + + n3 = _gnutls_mpi_set_ui( NULL, 5); + if (n3 == NULL) + fail ("mpi_set_ui failed\n"); + + _gnutls_mpi_randomize(n1, RND_BITS, GNUTLS_RND_NONCE); + + _gnutls_dump_mpi ( "rand:", n1); + + rc = _gnutls_mpi_get_nbits(n1); + if (rc > RND_BITS) + fail ("mpi_get_nbits failed... returned %d\n", rc); + + n4 = _gnutls_mpi_addm( NULL, n1, n3, n2); + if (n4 == NULL) + fail ("mpi_set_ui failed\n"); + + if (_gnutls_mpi_cmp_ui(n4, 0)!=0 && _gnutls_mpi_cmp_ui(n4, 1)!=0) + fail ("mpi_cmp_ui failed\n"); + + success ("mpi ops ok\n"); +} diff --git a/tests/netconf-psk.c b/tests/netconf-psk.c index 4674283af4..4b57b28b64 100644 --- a/tests/netconf-psk.c +++ b/tests/netconf-psk.c @@ -34,6 +34,12 @@ #include "utils.h" +static void +tls_log_func (int level, const char *str) +{ + fprintf (stderr, "<%d>| %s", level, str); +} + void doit (void) { @@ -44,6 +50,9 @@ doit (void) gnutls_global_init (); + gnutls_global_set_log_function (tls_log_func); + gnutls_global_set_log_level (2); + if (gnutls_psk_netconf_derive_key ("password", "psk_identity", "psk_identity_hint", &key) == 0) success ("success: gnutls_psk_netconf_derive_key\n"); diff --git a/tests/openpgp/keyring.c b/tests/openpgp/keyring.c index d56a3cd930..1edef2337b 100644 --- a/tests/openpgp/keyring.c +++ b/tests/openpgp/keyring.c @@ -177,6 +177,12 @@ static const gnutls_openpgp_keyid_t id_not_in_keyring = 0x00, 0x00, 0x00, 0x00 }; +static void +tls_log_func (int level, const char *str) +{ + fprintf (stderr, "%d| %s", level, str); +} + void doit (void) { @@ -188,6 +194,9 @@ doit (void) if (ret < 0) fail ("init %d\n", ret); + gnutls_global_set_log_function (tls_log_func); + gnutls_global_set_log_level (2); + ret = gnutls_global_init_extra (); if (ret < 0) fail ("extra-init %d\n", ret); diff --git a/tests/pkcs12-decode/Makefile.am b/tests/pkcs12-decode/Makefile.am index 2b712b77a0..f79b813d97 100644 --- a/tests/pkcs12-decode/Makefile.am +++ b/tests/pkcs12-decode/Makefile.am @@ -23,4 +23,15 @@ EXTRA_DIST = client.p12 noclient.p12 unclient.p12 dist_check_SCRIPTS = pkcs12 -TESTS = pkcs12 +TESTS = pkcs12 pkcs12_s2k + +check_PROGRAMS = pkcs12_s2k + +AM_CPPFLAGS = -I$(top_srcdir)/lgl -I$(top_builddir)/lgl -I.. \ + -I$(top_srcdir)/gl -I$(top_builddir)/gl \ + -I$(top_srcdir)/includes -I$(top_builddir)/includes \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/doc/examples +AM_LDFLAGS = -no-install +LDADD = ../../lib/libgnutls.la ../../gl/libgnu.la ../../lgl/liblgnu.la ../libutils.la + diff --git a/tests/pkcs12-decode/pkcs12_s2k b/tests/pkcs12-decode/pkcs12_s2k Binary files differnew file mode 100755 index 0000000000..2bd87810da --- /dev/null +++ b/tests/pkcs12-decode/pkcs12_s2k diff --git a/tests/pkcs12-decode/pkcs12_s2k.c b/tests/pkcs12-decode/pkcs12_s2k.c new file mode 100644 index 0000000000..6ff1887da2 --- /dev/null +++ b/tests/pkcs12-decode/pkcs12_s2k.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2007 Free Software Foundation + * + * Author: Simon Josefsson + * + * This file is part of GNUTLS. + * + * GNUTLS 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 3 of the License, or + * (at your option) any later version. + * + * GNUTLS 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 GNUTLS; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> + +#include <utils.h> +#include "../../lib/gnutls_int.h" +#include "../../lib/x509/x509_int.h" +#include "../../lib/debug.h" + +static void +tls_log_func (int level, const char *str) +{ + fprintf (stderr, "|<%d>| %s", level, str); +} + +char *salt[3] = { "salt1", "ltsa22", "balt33" }; +char *pw[3] = { "secret1", "verysecret2", "veryverysecret3" }; + +char *values[] = { +/* 1.0 */ "85a3c676a66f0960f4807144a28c8d61a0001b81846f301a1ac164289879972f", +/* 1.2 */ "e659da7d5989733a3d268e0bf7752c35c116e5c75919449a98f6812f82a15b16", +/* 1.2 */"878b8a88bf6166ce803b7498822205b1ac82870d3aec20807148779375a61f1e", +/* 2.0 */"1c845be764371d633c7fd1056967a9940385e110e85b58f826d39ae8561a0019", +/* 2.1 */"de8dd3ffd59b65d3d5f59a1f71d7add582741f7752a786c045953e727e4465c0", +/* 2.2 */"9dd7f19e5e6aee5c5008b5deefd35889ab7519356f13478ecdee593c5ed689b1", +/* 3.0 */"1c165e5a291a1539f3dbcf82a3e6ed566eb9d50ad4b0b3b57b599b08f0531236", +/* 3.1 */"5c9abee3cde31656eedfc131b7c2f8061032a3c705961ee2306a826c8b4b1a76", +/* 3.2 */"a9c94e0acdaeaea54d1b1b681c3b64916396a352dea7ffe635fb2c11d8502e98" +}; + +void +doit (void) +{ + int rc, i, j, x; + char key[32]; + char tmp[1024]; + + gnutls_global_init(); + + gnutls_global_set_log_function (tls_log_func); + gnutls_global_set_log_level (99); + + x = 0; + for (i=1;i<4;i++) { + for (j=0;j<3;j++) { + rc = _gnutls_pkcs12_string_to_key(i, salt[j], strlen(salt[j]), j+i+15, pw[j], sizeof(key), key); + if (rc < 0) + fail ("_gnutls_pkcs12_string_to_key failed[0]\n"); + + if (strcmp( _gnutls_bin2hex( key, sizeof(key), tmp, sizeof(tmp)), values[x]) != 0) + fail ("_gnutls_pkcs12_string_to_key failed[1]\n"); + + printf("ij: %d.%d: %s\n", i, j, _gnutls_bin2hex( key, sizeof(key), tmp, sizeof(tmp))); + x++; + } + } + printf("\n"); + + success ("_gnutls_pkcs12_string_to_key ok\n"); +} |