summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-05-25 10:48:30 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-05-29 08:23:49 +0200
commit7822f10e9229af74998b3daeafcf9e7f22bc0f8d (patch)
tree06c367513a231fda042762f2a84c554a906f04fe
parent9e5452193c3510102801fd86b6e65d37b5dc1012 (diff)
downloadgnutls-7822f10e9229af74998b3daeafcf9e7f22bc0f8d.tar.gz
Introduced gnutls_sign_supports_pk_algorithm()
This function allows to test whether a combination of public key algorithm and signature algorithm are supported. This is introduced for RSA-PSS signatures which can be generated by a GNUTLS_PK_RSA key or by a GNUTLS_PK_RSA_PSS key. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/algorithms/sign.c55
-rw-r--r--lib/includes/gnutls/gnutls.h.in3
-rw-r--r--lib/libgnutls.map1
3 files changed, 49 insertions, 10 deletions
diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c
index 614b17155e..1c19cc86fb 100644
--- a/lib/algorithms/sign.c
+++ b/lib/algorithms/sign.c
@@ -24,6 +24,7 @@
#include <algorithms.h>
#include "errors.h"
#include <x509/common.h>
+#include <assert.h>
/* signature algorithms;
*/
@@ -42,6 +43,9 @@ typedef struct gnutls_sign_entry gnutls_sign_entry;
#define TLS_SIGN_AID_UNKNOWN {255, 255}
static const sign_algorithm_st unknown_tls_aid = TLS_SIGN_AID_UNKNOWN;
+/* Signature algorithms may be listed twice with a different PK algorithm,
+ * e.g., RSA-PSS-SHA256 can be generated by GNUTLS_PK_RSA or GNUTLS_PK_RSA_PSS.
+ */
static const gnutls_sign_entry sign_algorithms[] = {
{"RSA-SHA1", SIG_RSA_SHA1_OID, GNUTLS_SIGN_RSA_SHA1, GNUTLS_PK_RSA,
GNUTLS_DIG_SHA1, {2, 1}},
@@ -125,14 +129,17 @@ static const gnutls_sign_entry sign_algorithms[] = {
GNUTLS_PK_DSA, GNUTLS_DIG_SHA3_512, TLS_SIGN_AID_UNKNOWN},
{"RSA-PSS-SHA256", PK_PKIX1_RSA_PSS_OID, GNUTLS_SIGN_RSA_PSS_SHA256,
- GNUTLS_PK_RSA_PSS,
- GNUTLS_DIG_SHA256, {8, 4}},
+ GNUTLS_PK_RSA_PSS, GNUTLS_DIG_SHA256, {8, 4}},
+ {"RSA-PSS-SHA256", PK_PKIX1_RSA_PSS_OID, GNUTLS_SIGN_RSA_PSS_SHA256,
+ GNUTLS_PK_RSA, GNUTLS_DIG_SHA256, {8, 4}},
+ {"RSA-PSS-SHA384", PK_PKIX1_RSA_PSS_OID, GNUTLS_SIGN_RSA_PSS_SHA384,
+ GNUTLS_PK_RSA_PSS, GNUTLS_DIG_SHA384, {8, 5}},
{"RSA-PSS-SHA384", PK_PKIX1_RSA_PSS_OID, GNUTLS_SIGN_RSA_PSS_SHA384,
- GNUTLS_PK_RSA_PSS,
- GNUTLS_DIG_SHA384, {8, 5}},
+ GNUTLS_PK_RSA, GNUTLS_DIG_SHA384, {8, 5}},
{"RSA-PSS-SHA512", PK_PKIX1_RSA_PSS_OID, GNUTLS_SIGN_RSA_PSS_SHA512,
- GNUTLS_PK_RSA_PSS,
- GNUTLS_DIG_SHA512, {8, 6}},
+ GNUTLS_PK_RSA_PSS, GNUTLS_DIG_SHA512, {8, 6}},
+ {"RSA-PSS-SHA512", PK_PKIX1_RSA_PSS_OID, GNUTLS_SIGN_RSA_PSS_SHA512,
+ GNUTLS_PK_RSA, GNUTLS_DIG_SHA512, {8, 6}},
{0, 0, 0, 0, 0, TLS_SIGN_AID_UNKNOWN}
};
@@ -197,13 +204,19 @@ int gnutls_sign_is_secure(gnutls_sign_algorithm_t algorithm)
**/
const gnutls_sign_algorithm_t *gnutls_sign_list(void)
{
- static gnutls_sign_algorithm_t supported_sign[MAX_ALGOS] = { 0 };
+ static gnutls_sign_algorithm_t supported_sign[MAX_ALGOS+1] = { 0 };
if (supported_sign[0] == 0) {
int i = 0;
- GNUTLS_SIGN_LOOP(supported_sign[i++] = p->id);
- supported_sign[i++] = 0;
+ GNUTLS_SIGN_LOOP(
+ /* list all algorithms, but not duplicates */
+ if (supported_sign[i] != p->id) {
+ assert(i+1 < MAX_ALGOS);
+ supported_sign[i++] = p->id;
+ supported_sign[i+1] = 0;
+ }
+ );
}
return supported_sign;
@@ -333,7 +346,9 @@ gnutls_sign_get_hash_algorithm(gnutls_sign_algorithm_t sign)
* @sign: is a signature algorithm
*
* This function returns the public key algorithm corresponding to
- * the given signature algorithms.
+ * the given signature algorithms. Note that there may be multiple
+ * public key algorithms supporting a particular signature type;
+ * when dealing with such algorithms use instead gnutls_sign_supports_pk_algorithm().
*
* Since: 3.1.1
*
@@ -349,6 +364,26 @@ gnutls_sign_get_pk_algorithm(gnutls_sign_algorithm_t sign)
return ret;
}
+/**
+ * gnutls_sign_supports_pk_algorithm:
+ * @sign: is a signature algorithm
+ * @pk: is a public key algorithm
+ *
+ * This function returns non-zero if the public key algorithm corresponds to
+ * the given signature algorithm.
+ *
+ * Since: 3.6.0
+ *
+ * Returns: return non-zero when the provided algorithms are compatible.
+ **/
+unsigned
+gnutls_sign_supports_pk_algorithm(gnutls_sign_algorithm_t sign, gnutls_pk_algorithm_t pk)
+{
+ GNUTLS_SIGN_LOOP( if(p->id && p->id == sign && pk == p->pk) { return 1; } );
+
+ return 0;
+}
+
gnutls_sign_algorithm_t
_gnutls_tls_aid_to_sign(const sign_algorithm_st * aid)
{
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index 19dc4f252b..fcd744ede2 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1018,6 +1018,9 @@ gnutls_sign_algorithm_t
gnutls_pk_to_sign(gnutls_pk_algorithm_t pk,
gnutls_digest_algorithm_t hash) __GNUTLS_CONST__;
+unsigned
+gnutls_sign_supports_pk_algorithm(gnutls_sign_algorithm_t sign, gnutls_pk_algorithm_t pk) __GNUTLS_CONST__;
+
#define gnutls_sign_algorithm_get_name gnutls_sign_get_name
gnutls_mac_algorithm_t gnutls_mac_get_id(const char *name) __GNUTLS_CONST__;
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index fb6fb36620..672c55bdc1 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -1155,6 +1155,7 @@ GNUTLS_3_4
gnutls_x509_crq_get_pk_algorithm2;
gnutls_x509_crq_set_pk_algorithm;
gnutls_x509_privkey_get_pk_algorithm3;
+ gnutls_sign_supports_pk_algorithm;
local:
*;
};