From: Nikos Mavrogiannopoulos Date: Thu, 28 Mar 2013 08:03:59 +0000 (+0100) Subject: Added sign and verification flags to operate in RSA raw mode (as used in TLS). X-Git-Tag: gnutls_3_2_0~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=222db2ede00e717886fe933362f06d2b01449418;p=thirdparty%2Fgnutls.git Added sign and verification flags to operate in RSA raw mode (as used in TLS). --- diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index 22b966ed45..1a42d50f38 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -694,7 +694,7 @@ cleanup: * gnutls_privkey_sign_data: * @signer: Holds the key * @hash: should be a digest algorithm - * @flags: should be 0 for now + * @flags: Zero or on of %gnutls_privkey_flags_t * @data: holds the data to be signed * @signature: will contain the signature allocate with gnutls_malloc() * @@ -721,6 +721,9 @@ gnutls_privkey_sign_data (gnutls_privkey_t signer, int ret; gnutls_datum_t digest; + if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + ret = pk_hash_data (signer->pk_algorithm, hash, NULL, data, &digest); if (ret < 0) { @@ -755,7 +758,7 @@ cleanup: * gnutls_privkey_sign_hash: * @signer: Holds the signer's key * @hash_algo: The hash algorithm used - * @flags: zero for now + * @flags: Zero or on of %gnutls_privkey_flags_t * @hash_data: holds the data to be signed * @signature: will contain newly allocated signature * @@ -782,6 +785,9 @@ gnutls_privkey_sign_hash (gnutls_privkey_t signer, int ret; gnutls_datum_t digest; + if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA) + return gnutls_privkey_sign_raw_data (signer, flags, hash_data, signature); + digest.data = gnutls_malloc (hash_data->size); if (digest.data == NULL) { @@ -825,6 +831,9 @@ cleanup: * For example on an RSA key the input @data should be of the DigestInfo * PKCS #1 1.5 format. Use it only if you know what are you doing. * + * Note this function is equivalent to using the %GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA + * flag with gnutls_privkey_sign_hash(). + * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index f11cc5e5e4..019704f7c8 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -1534,7 +1534,7 @@ gnutls_pubkey_import_dsa_raw (gnutls_pubkey_t key, /** * gnutls_pubkey_verify_data: * @pubkey: Holds the public key - * @flags: should be 0 for now + * @flags: Zero or on of %gnutls_pubkey_flags_t * @data: holds the signed data * @signature: contains the signature * @@ -1563,6 +1563,9 @@ gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags, return GNUTLS_E_INVALID_REQUEST; } + if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + ret = gnutls_pubkey_get_verify_algorithm (pubkey, signature, &hash); if (ret < 0) return gnutls_assert_val(ret); @@ -1581,7 +1584,7 @@ gnutls_pubkey_verify_data (gnutls_pubkey_t pubkey, unsigned int flags, * gnutls_pubkey_verify_data2: * @pubkey: Holds the public key * @algo: The signature algorithm used - * @flags: should be 0 for now + * @flags: Zero or on of %gnutls_pubkey_flags_t * @data: holds the signed data * @signature: contains the signature * @@ -1608,6 +1611,9 @@ gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey, return GNUTLS_E_INVALID_REQUEST; } + if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + ret = pubkey_verify_data( pubkey->pk_algorithm, gnutls_sign_get_hash_algorithm(algo), data, signature, &pubkey->params); if (ret < 0) @@ -1622,7 +1628,7 @@ gnutls_pubkey_verify_data2 (gnutls_pubkey_t pubkey, /** * gnutls_pubkey_verify_hash: * @key: Holds the public key - * @flags: should be 0 for now + * @flags: Zero or on of %gnutls_pubkey_flags_t * @hash: holds the hash digest to be verified * @signature: contains the signature * @@ -1657,7 +1663,7 @@ int ret; * gnutls_pubkey_verify_hash2: * @key: Holds the public key * @algo: The signature algorithm used - * @flags: should be 0 for now + * @flags: Zero or on of %gnutls_pubkey_flags_t * @hash: holds the hash digest to be verified * @signature: contains the signature * @@ -1682,8 +1688,10 @@ gnutls_pubkey_verify_hash2 (gnutls_pubkey_t key, return GNUTLS_E_INVALID_REQUEST; } - if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA) - return _gnutls_pk_verify (GNUTLS_PK_RSA, hash, signature, &key->params); + if (flags & GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA) + { + return _gnutls_pk_verify (GNUTLS_PK_RSA, hash, signature, &key->params); + } else { return pubkey_verify_hashed_data (key->pk_algorithm, gnutls_sign_get_hash_algorithm(algo), @@ -1870,15 +1878,13 @@ _pkcs1_rsa_verify_sig (gnutls_digest_algorithm_t hash, /* decrypted is a BER encoded data of type DigestInfo */ - ret = encode_ber_digest_info (hash, &d, &di); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_pk_verify (GNUTLS_PK_RSA, &di, signature, params); + _gnutls_free_datum (&di); - _gnutls_free_datum (&di); - return ret; } diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h index 6c121b3acc..541b7ecbd5 100644 --- a/lib/includes/gnutls/abstract.h +++ b/lib/includes/gnutls/abstract.h @@ -36,12 +36,23 @@ extern "C" /* Public key operations */ -#define GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA 1 -/* The following flag disables call to PIN callbacks etc. - * Only works for TPM keys. +#define GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA +/** + * gnutls_pubkey_flags: + * @GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA: This indicates that a (raw) RSA signature is provided + * as in the TLS 1.0 protocol. + * @GNUTLS_PUBKEY_DISABLE_CALLBACKS: The following flag disables call to PIN callbacks. Only + * relevant to TPM keys. + * @GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT: request an OPENPGP fingerprint instead of the default. + * + * Enumeration of different certificate import flags. */ -#define GNUTLS_PUBKEY_DISABLE_CALLBACKS (1<<2) -#define GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT (1<<3) + typedef enum gnutls_pubkey_flags + { + GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA = 1, + GNUTLS_PUBKEY_DISABLE_CALLBACKS = 1<<2, + GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT = 1<<3, + } gnutls_pubkey_flags_t; struct gnutls_pubkey_st; typedef struct gnutls_pubkey_st *gnutls_pubkey_t; @@ -214,13 +225,25 @@ int gnutls_privkey_get_pk_algorithm (gnutls_privkey_t key, gnutls_privkey_type_t gnutls_privkey_get_type (gnutls_privkey_t key); int gnutls_privkey_status (gnutls_privkey_t key); - -#define GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE (1<<0) -#define GNUTLS_PRIVKEY_IMPORT_COPY (1<<1) -/* The following flag disables call to PIN callbacks etc. - * Only works for TPM keys. +/** + * gnutls_privkey_flags: + * @GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA: Make an RSA signature on the hashed data as in the TLS protocol. + * @GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE: When importing a private key, automatically + * release it when the structure it was imported is released. + * @GNUTLS_PRIVKEY_IMPORT_COPY: Copy required values during import. + * @GNUTLS_PRIVKEY_DISABLE_CALLBACKS: The following flag disables call to PIN callbacks etc. + * Only relevant to TPM keys. + * + * Enumeration of different certificate import flags. */ -#define GNUTLS_PRIVKEY_DISABLE_CALLBACKS (1<<2) + typedef enum gnutls_privkey_flags + { + GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE = 1, + GNUTLS_PRIVKEY_IMPORT_COPY = 1<<1, + GNUTLS_PRIVKEY_DISABLE_CALLBACKS = 1<<2, + GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA = 1<<4, + } gnutls_privkey_flags_t; + int gnutls_privkey_import_pkcs11 (gnutls_privkey_t pkey, gnutls_pkcs11_privkey_t key, unsigned int flags); diff --git a/tests/x509sign-verify.c b/tests/x509sign-verify.c index 7e0727cf1f..69e0903462 100644 --- a/tests/x509sign-verify.c +++ b/tests/x509sign-verify.c @@ -249,7 +249,24 @@ doit (void) if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED) fail ("gnutls_x509_pubkey_verify_hash2-2 (hashed data)\n"); - + /* test the raw interface */ + gnutls_free(signature.data); + signature.data = NULL; + + if (gnutls_pubkey_get_pk_algorithm(pubkey, NULL) == GNUTLS_PK_RSA) + { + ret = gnutls_privkey_sign_hash (privkey, GNUTLS_DIG_SHA1, GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA, + &hash_data, &signature); + if (ret < 0) + fail ("gnutls_privkey_sign_hash: %s\n", gnutls_strerror(ret)); + + sign_algo = gnutls_pk_to_sign(gnutls_pubkey_get_pk_algorithm(pubkey, NULL), + GNUTLS_DIG_SHA1); + + ret = gnutls_pubkey_verify_hash2 (pubkey, sign_algo, GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA, &hash_data, &signature); + if (ret < 0) + fail ("gnutls_pubkey_verify_hash-3 (raw hashed data)\n"); + } gnutls_free(signature.data); gnutls_free(signature2.data); gnutls_x509_privkey_deinit (key);