summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/abstract_int.h8
-rw-r--r--lib/algorithms.h1
-rw-r--r--lib/algorithms/sign.c25
-rw-r--r--lib/privkey.c77
-rw-r--r--lib/x509/crq.c3
-rw-r--r--lib/x509/pkcs7.c3
-rw-r--r--lib/x509/sign.c9
7 files changed, 76 insertions, 50 deletions
diff --git a/lib/abstract_int.h b/lib/abstract_int.h
index f82e4f922a..2fefa2cf37 100644
--- a/lib/abstract_int.h
+++ b/lib/abstract_int.h
@@ -81,14 +81,16 @@ int _gnutls_privkey_update_sign_params(gnutls_privkey_t key,
void _gnutls_privkey_cleanup(gnutls_privkey_t key);
int privkey_sign_and_hash_data(gnutls_privkey_t signer,
+ const gnutls_sign_entry_st *se,
const gnutls_datum_t * data,
gnutls_datum_t * signature,
gnutls_x509_spki_st *params);
int
privkey_sign_raw_data(gnutls_privkey_t key,
- const gnutls_datum_t * data,
- gnutls_datum_t * signature,
- gnutls_x509_spki_st * params);
+ const gnutls_sign_entry_st *se,
+ const gnutls_datum_t * data,
+ gnutls_datum_t * signature,
+ gnutls_x509_spki_st * params);
unsigned pubkey_to_bits(gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params);
int _gnutls_pubkey_compatible_with_sig(gnutls_session_t,
diff --git a/lib/algorithms.h b/lib/algorithms.h
index 97404ec8c1..631675462e 100644
--- a/lib/algorithms.h
+++ b/lib/algorithms.h
@@ -321,6 +321,7 @@ struct gnutls_sign_entry_st {
typedef struct gnutls_sign_entry_st gnutls_sign_entry_st;
const gnutls_sign_entry_st *_gnutls_sign_to_entry(gnutls_sign_algorithm_t sign);
+const gnutls_sign_entry_st *_gnutls_pk_to_sign_entry(gnutls_pk_algorithm_t, gnutls_digest_algorithm_t);
gnutls_pk_algorithm_t _gnutls_x509_sign_to_pk(gnutls_sign_algorithm_t
sign);
diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c
index 062d926fcf..eca76fa487 100644
--- a/lib/algorithms/sign.c
+++ b/lib/algorithms/sign.c
@@ -281,6 +281,17 @@ gnutls_sign_algorithm_t gnutls_oid_to_sign(const char *oid)
return ret;
}
+const gnutls_sign_entry_st *_gnutls_pk_to_sign_entry(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
+{
+ GNUTLS_SIGN_LOOP(
+ if (pk == p->pk && hash == p->hash) {
+ return p;
+ }
+ );
+
+ return NULL;
+}
+
/**
* gnutls_pk_to_sign:
* @pk: is a public key algorithm
@@ -294,18 +305,12 @@ gnutls_sign_algorithm_t gnutls_oid_to_sign(const char *oid)
gnutls_sign_algorithm_t
gnutls_pk_to_sign(gnutls_pk_algorithm_t pk, gnutls_digest_algorithm_t hash)
{
- gnutls_sign_algorithm_t ret = 0;
+ const gnutls_sign_entry_st *e;
- GNUTLS_SIGN_LOOP(
- if (pk == p->pk && hash == p->hash) {
- ret = p->id;
- break;
- }
- );
-
- if (ret == 0)
+ e = _gnutls_pk_to_sign_entry(pk, hash);
+ if (e == NULL)
return GNUTLS_SIGN_UNKNOWN;
- return ret;
+ return e->id;
}
/**
diff --git a/lib/privkey.c b/lib/privkey.c
index e026ca4895..911829de16 100644
--- a/lib/privkey.c
+++ b/lib/privkey.c
@@ -39,9 +39,10 @@
static int
privkey_sign_prehashed(gnutls_privkey_t signer,
- const gnutls_datum_t * hash_data,
- gnutls_datum_t * signature,
- gnutls_x509_spki_st * params, unsigned flags);
+ const gnutls_sign_entry_st *se,
+ const gnutls_datum_t * hash_data,
+ gnutls_datum_t * signature,
+ gnutls_x509_spki_st * params, unsigned flags);
/**
* gnutls_privkey_get_type:
@@ -1007,7 +1008,7 @@ gnutls_privkey_sign_data(gnutls_privkey_t signer,
return ret;
}
- return privkey_sign_and_hash_data(signer, data, signature, &params);
+ return privkey_sign_and_hash_data(signer, _gnutls_pk_to_sign_entry(params.pk, hash), data, signature, &params);
}
/**
@@ -1059,7 +1060,7 @@ gnutls_privkey_sign_data2(gnutls_privkey_t signer,
return ret;
}
- return privkey_sign_and_hash_data(signer, data, signature, &params);
+ return privkey_sign_and_hash_data(signer, _gnutls_sign_to_entry(algo), data, signature, &params);
}
/**
@@ -1099,10 +1100,10 @@ gnutls_privkey_sign_hash2(gnutls_privkey_t signer,
{
int ret;
gnutls_x509_spki_st params;
- const gnutls_sign_entry_st *e;
+ const gnutls_sign_entry_st *se;
- e = _gnutls_sign_to_entry(algo);
- if (e == NULL)
+ se = _gnutls_sign_to_entry(algo);
+ if (se == NULL)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
ret = _gnutls_privkey_get_sign_params(signer, &params);
@@ -1111,18 +1112,19 @@ gnutls_privkey_sign_hash2(gnutls_privkey_t signer,
return ret;
}
- ret = _gnutls_privkey_update_sign_params(signer, e->pk, e->hash,
+ ret = _gnutls_privkey_update_sign_params(signer, se->pk, se->hash,
flags, &params);
if (ret < 0) {
gnutls_assert();
return ret;
}
- return privkey_sign_prehashed(signer, hash_data, signature, &params, flags);
+ return privkey_sign_prehashed(signer, se, hash_data, signature, &params, flags);
}
int
privkey_sign_and_hash_data(gnutls_privkey_t signer,
+ const gnutls_sign_entry_st *se,
const gnutls_datum_t * data,
gnutls_datum_t * signature,
gnutls_x509_spki_st * params)
@@ -1131,34 +1133,30 @@ privkey_sign_and_hash_data(gnutls_privkey_t signer,
gnutls_datum_t digest;
const mac_entry_st *me;
- if (_gnutls_pk_is_not_prehashed(signer->pk_algorithm)) {
- if (params->dig != GNUTLS_DIG_UNKNOWN &&
- gnutls_pk_to_sign(params->pk, params->dig) == GNUTLS_SIGN_UNKNOWN)
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ if (se == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- return privkey_sign_raw_data(signer, data, signature, params);
+ if (_gnutls_pk_is_not_prehashed(se->pk)) {
+ return privkey_sign_raw_data(signer, se, data, signature, params);
}
- if (gnutls_pk_to_sign(params->pk, params->dig) == GNUTLS_SIGN_UNKNOWN)
- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-
- me = hash_to_entry(params->dig);
+ me = hash_to_entry(se->hash);
if (me == NULL)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- ret = pk_hash_data(params->pk, me, NULL, data, &digest);
+ ret = pk_hash_data(se->pk, me, NULL, data, &digest);
if (ret < 0) {
gnutls_assert();
return ret;
}
- ret = pk_prepare_hash(params->pk, me, &digest);
+ ret = pk_prepare_hash(se->pk, me, &digest);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
- ret = privkey_sign_raw_data(signer, &digest, signature, params);
+ ret = privkey_sign_raw_data(signer, se, &digest, signature, params);
_gnutls_free_datum(&digest);
if (ret < 0) {
@@ -1225,21 +1223,24 @@ gnutls_privkey_sign_hash(gnutls_privkey_t signer,
return ret;
}
- return privkey_sign_prehashed(signer, hash_data, signature, &params, flags);
+ return privkey_sign_prehashed(signer, _gnutls_pk_to_sign_entry(params.pk, hash_algo),
+ hash_data, signature, &params, flags);
}
static int
privkey_sign_prehashed(gnutls_privkey_t signer,
- const gnutls_datum_t * hash_data,
- gnutls_datum_t * signature,
- gnutls_x509_spki_st * params,
- unsigned flags)
+ const gnutls_sign_entry_st *se,
+ const gnutls_datum_t * hash_data,
+ gnutls_datum_t * signature,
+ gnutls_x509_spki_st * params,
+ unsigned flags)
{
int ret;
gnutls_datum_t digest;
if (flags & GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA)
return privkey_sign_raw_data(signer,
+ se,
hash_data, signature,
params);
@@ -1247,6 +1248,9 @@ privkey_sign_prehashed(gnutls_privkey_t signer,
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
+ if (se == NULL)
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+
digest.data = gnutls_malloc(hash_data->size);
if (digest.data == NULL) {
gnutls_assert();
@@ -1255,13 +1259,14 @@ privkey_sign_prehashed(gnutls_privkey_t signer,
digest.size = hash_data->size;
memcpy(digest.data, hash_data->data, digest.size);
- ret = pk_prepare_hash(params->pk, hash_to_entry(params->dig), &digest);
+ ret = pk_prepare_hash(se->pk, hash_to_entry(se->hash), &digest);
if (ret < 0) {
gnutls_assert();
goto cleanup;
}
ret = privkey_sign_raw_data(signer,
+ se,
&digest, signature,
params);
if (ret < 0) {
@@ -1299,10 +1304,18 @@ privkey_sign_prehashed(gnutls_privkey_t signer,
-*/
int
privkey_sign_raw_data(gnutls_privkey_t key,
- const gnutls_datum_t * data,
- gnutls_datum_t * signature,
- gnutls_x509_spki_st * params)
+ const gnutls_sign_entry_st *se,
+ const gnutls_datum_t * data,
+ gnutls_datum_t * signature,
+ gnutls_x509_spki_st * params)
{
+ gnutls_pk_algorithm_t pk;
+
+ if (se == NULL) /* it can be null when signing raw-rsa */
+ pk = params->pk;
+ else
+ pk = se->pk;
+
switch (key->type) {
#ifdef ENABLE_PKCS11
case GNUTLS_PRIVKEY_PKCS11:
@@ -1310,7 +1323,7 @@ privkey_sign_raw_data(gnutls_privkey_t key,
data, signature);
#endif
case GNUTLS_PRIVKEY_X509:
- return _gnutls_pk_sign(params->pk, signature, data,
+ return _gnutls_pk_sign(pk, signature, data,
&key->key.x509->params, params);
case GNUTLS_PRIVKEY_EXT:
if (key->key.ext.sign_func == NULL)
diff --git a/lib/x509/crq.c b/lib/x509/crq.c
index 0f91278b4e..fc90e3296d 100644
--- a/lib/x509/crq.c
+++ b/lib/x509/crq.c
@@ -2862,7 +2862,8 @@ gnutls_x509_crq_privkey_sign(gnutls_x509_crq_t crq, gnutls_privkey_t key,
return result;
}
- result = privkey_sign_and_hash_data(key, &tbs, &signature, &params);
+ result = privkey_sign_and_hash_data(key, _gnutls_pk_to_sign_entry(params.pk, dig),
+ &tbs, &signature, &params);
gnutls_free(tbs.data);
if (result < 0) {
diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c
index c0b0810b0c..4bb8d863a8 100644
--- a/lib/x509/pkcs7.c
+++ b/lib/x509/pkcs7.c
@@ -2536,7 +2536,8 @@ int gnutls_pkcs7_sign(gnutls_pkcs7_t pkcs7,
goto cleanup;
}
- ret = privkey_sign_and_hash_data(signer_key, &sigdata, &signature, &params);
+ ret = privkey_sign_and_hash_data(signer_key, _gnutls_pk_to_sign_entry(params.pk, dig),
+ &sigdata, &signature, &params);
if (ret < 0) {
gnutls_assert();
goto cleanup;
diff --git a/lib/x509/sign.c b/lib/x509/sign.c
index dd688ea9ab..8a00d77411 100644
--- a/lib/x509/sign.c
+++ b/lib/x509/sign.c
@@ -111,6 +111,7 @@ _gnutls_x509_pkix_sign(ASN1_TYPE src, const char *src_name,
char name[128];
gnutls_pk_algorithm_t pk;
gnutls_x509_spki_st key_params, params;
+ const gnutls_sign_entry_st *se;
pk = gnutls_x509_crt_get_pk_algorithm(issuer, NULL);
if (pk == GNUTLS_PK_UNKNOWN)
@@ -168,10 +169,12 @@ _gnutls_x509_pkix_sign(ASN1_TYPE src, const char *src_name,
return result;
}
- if (_gnutls_pk_is_not_prehashed(issuer_key->pk_algorithm)) {
- result = privkey_sign_raw_data(issuer_key, &tbs, &signature, &params);
+ se = _gnutls_pk_to_sign_entry(params.pk, dig);
+ if (_gnutls_pk_is_not_prehashed(params.pk)) {
+ result = privkey_sign_raw_data(issuer_key, se, &tbs, &signature, &params);
} else {
- result = privkey_sign_and_hash_data(issuer_key, &tbs, &signature, &params);
+ result = privkey_sign_and_hash_data(issuer_key, se,
+ &tbs, &signature, &params);
}
gnutls_free(tbs.data);