summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/gmp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/gmp')
-rw-r--r--src/libstrongswan/plugins/gmp/Makefile.in11
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c68
-rw-r--r--src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c158
3 files changed, 60 insertions, 177 deletions
diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in
index 11aef42f0..a74d76201 100644
--- a/src/libstrongswan/plugins/gmp/Makefile.in
+++ b/src/libstrongswan/plugins/gmp/Makefile.in
@@ -311,7 +311,6 @@ PYTHON_VERSION = @PYTHON_VERSION@
PY_TEST = @PY_TEST@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
-RUBY = @RUBY@
RUBYGEMDIR = @RUBYGEMDIR@
SED = @SED@
SET_MAKE = @SET_MAKE@
@@ -337,6 +336,8 @@ am__tar = @am__tar@
am__untar = @am__untar@
attest_plugins = @attest_plugins@
bindir = @bindir@
+botan_CFLAGS = @botan_CFLAGS@
+botan_LIBS = @botan_LIBS@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
@@ -357,8 +358,6 @@ dvidir = @dvidir@
exec_prefix = @exec_prefix@
fips_mode = @fips_mode@
fuzz_plugins = @fuzz_plugins@
-gtk_CFLAGS = @gtk_CFLAGS@
-gtk_LIBS = @gtk_LIBS@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
@@ -413,8 +412,6 @@ random_device = @random_device@
resolv_conf = @resolv_conf@
routing_table = @routing_table@
routing_table_prio = @routing_table_prio@
-ruby_CFLAGS = @ruby_CFLAGS@
-ruby_LIBS = @ruby_LIBS@
runstatedir = @runstatedir@
s_plugins = @s_plugins@
sbindir = @sbindir@
@@ -443,8 +440,12 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
tss2_CFLAGS = @tss2_CFLAGS@
tss2_LIBS = @tss2_LIBS@
+tss2_esys_CFLAGS = @tss2_esys_CFLAGS@
+tss2_esys_LIBS = @tss2_esys_LIBS@
tss2_socket_CFLAGS = @tss2_socket_CFLAGS@
tss2_socket_LIBS = @tss2_socket_LIBS@
+tss2_sys_CFLAGS = @tss2_sys_CFLAGS@
+tss2_sys_LIBS = @tss2_sys_LIBS@
tss2_tabrmd_CFLAGS = @tss2_tabrmd_CFLAGS@
tss2_tabrmd_LIBS = @tss2_tabrmd_LIBS@
urandom_device = @urandom_device@
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
index 241ef7d3b..e9a83fdf4 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Tobias Brunner
+ * Copyright (C) 2017-2018 Tobias Brunner
* Copyright (C) 2005 Jan Hutter
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2012 Andreas Steffen
@@ -264,14 +264,15 @@ static chunk_t rsasp1(private_gmp_rsa_private_key_t *this, chunk_t data)
}
/**
- * Build a signature using the PKCS#1 EMSA scheme
+ * Hashes the data and builds the plaintext signature value with EMSA
+ * PKCS#1 v1.5 padding.
+ *
+ * Allocates the signature data.
*/
-static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
- hash_algorithm_t hash_algorithm,
- chunk_t data, chunk_t *signature)
+bool gmp_emsa_pkcs1_signature_data(hash_algorithm_t hash_algorithm,
+ chunk_t data, size_t keylen, chunk_t *em)
{
chunk_t digestInfo = chunk_empty;
- chunk_t em;
if (hash_algorithm != HASH_UNKNOWN)
{
@@ -295,43 +296,56 @@ static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
/* build DER-encoded digestInfo */
digestInfo = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_algorithmIdentifier(hash_oid),
- asn1_simple_object(ASN1_OCTET_STRING, hash)
- );
- chunk_free(&hash);
+ asn1_wrap(ASN1_OCTET_STRING, "m", hash));
+
data = digestInfo;
}
- if (data.len > this->k - 3)
+ if (data.len > keylen - 11)
{
- free(digestInfo.ptr);
- DBG1(DBG_LIB, "unable to sign %d bytes using a %dbit key", data.len,
- mpz_sizeinbase(this->n, 2));
+ chunk_free(&digestInfo);
+ DBG1(DBG_LIB, "signature value of %zu bytes is too long for key of "
+ "%zu bytes", data.len, keylen);
return FALSE;
}
- /* build chunk to rsa-decrypt:
- * EM = 0x00 || 0x01 || PS || 0x00 || T.
- * PS = 0xFF padding, with length to fill em
+ /* EM = 0x00 || 0x01 || PS || 0x00 || T.
+ * PS = 0xFF padding, with length to fill em (at least 8 bytes)
* T = encoded_hash
*/
- em.len = this->k;
- em.ptr = malloc(em.len);
+ *em = chunk_alloc(keylen);
/* fill em with padding */
- memset(em.ptr, 0xFF, em.len);
+ memset(em->ptr, 0xFF, em->len);
/* set magic bytes */
- *(em.ptr) = 0x00;
- *(em.ptr+1) = 0x01;
- *(em.ptr + em.len - data.len - 1) = 0x00;
- /* set DER-encoded hash */
- memcpy(em.ptr + em.len - data.len, data.ptr, data.len);
+ *(em->ptr) = 0x00;
+ *(em->ptr+1) = 0x01;
+ *(em->ptr + em->len - data.len - 1) = 0x00;
+ /* set encoded hash */
+ memcpy(em->ptr + em->len - data.len, data.ptr, data.len);
+
+ chunk_clear(&digestInfo);
+ return TRUE;
+}
+
+/**
+ * Build a signature using the PKCS#1 EMSA scheme
+ */
+static bool build_emsa_pkcs1_signature(private_gmp_rsa_private_key_t *this,
+ hash_algorithm_t hash_algorithm,
+ chunk_t data, chunk_t *signature)
+{
+ chunk_t em;
+
+ if (!gmp_emsa_pkcs1_signature_data(hash_algorithm, data, this->k, &em))
+ {
+ return FALSE;
+ }
/* build signature */
*signature = rsasp1(this, em);
- free(digestInfo.ptr);
- free(em.ptr);
-
+ chunk_free(&em);
return TRUE;
}
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
index 52bc9fb38..9b5ee67fa 100644
--- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
+++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Tobias Brunner
+ * Copyright (C) 2017-2018 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
* HSR Hochschule fuer Technik Rapperswil
@@ -70,7 +70,9 @@ struct private_gmp_rsa_public_key_t {
/**
* Shared functions defined in gmp_rsa_private_key.c
*/
-extern chunk_t gmp_mpz_to_chunk(const mpz_t value);
+chunk_t gmp_mpz_to_chunk(const mpz_t value);
+bool gmp_emsa_pkcs1_signature_data(hash_algorithm_t hash_algorithm,
+ chunk_t data, size_t keylen, chunk_t *em);
/**
* RSAEP algorithm specified in PKCS#1.
@@ -115,26 +117,13 @@ static chunk_t rsavp1(private_gmp_rsa_public_key_t *this, chunk_t data)
}
/**
- * ASN.1 definition of digestInfo
- */
-static const asn1Object_t digestInfoObjects[] = {
- { 0, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 1, "digest", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
- { 0, "exit", ASN1_EOC, ASN1_EXIT }
-};
-#define DIGEST_INFO 0
-#define DIGEST_INFO_ALGORITHM 1
-#define DIGEST_INFO_DIGEST 2
-
-/**
* Verification of an EMSA PKCS1 signature described in PKCS#1
*/
static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
hash_algorithm_t algorithm,
chunk_t data, chunk_t signature)
{
- chunk_t em_ori, em;
+ chunk_t em_expected, em;
bool success = FALSE;
/* remove any preceding 0-bytes from signature */
@@ -148,140 +137,19 @@ static bool verify_emsa_pkcs1_signature(private_gmp_rsa_public_key_t *this,
return FALSE;
}
- /* unpack signature */
- em_ori = em = rsavp1(this, signature);
-
- /* result should look like this:
- * EM = 0x00 || 0x01 || PS || 0x00 || T.
- * PS = 0xFF padding, with length to fill em
- * T = oid || hash
- */
-
- /* check magic bytes */
- if (em.len < 2 || *(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
+ /* generate expected signature value */
+ if (!gmp_emsa_pkcs1_signature_data(algorithm, data, this->k, &em_expected))
{
- goto end;
- }
- em = chunk_skip(em, 2);
-
- /* find magic 0x00 */
- while (em.len > 0)
- {
- if (*em.ptr == 0x00)
- {
- /* found magic byte, stop */
- em = chunk_skip(em, 1);
- break;
- }
- else if (*em.ptr != 0xFF)
- {
- /* bad padding, decryption failed ?!*/
- goto end;
- }
- em = chunk_skip(em, 1);
- }
-
- if (em.len == 0)
- {
- /* no digestInfo found */
- goto end;
- }
-
- if (algorithm == HASH_UNKNOWN)
- { /* IKEv1 signatures without digestInfo */
- if (em.len != data.len)
- {
- DBG1(DBG_LIB, "hash size in signature is %u bytes instead of"
- " %u bytes", em.len, data.len);
- goto end;
- }
- success = memeq_const(em.ptr, data.ptr, data.len);
+ return FALSE;
}
- else
- { /* IKEv2 and X.509 certificate signatures */
- asn1_parser_t *parser;
- chunk_t object;
- int objectID;
- hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
-
- DBG2(DBG_LIB, "signature verification:");
- parser = asn1_parser_create(digestInfoObjects, em);
- while (parser->iterate(parser, &objectID, &object))
- {
- switch (objectID)
- {
- case DIGEST_INFO:
- {
- if (em.len > object.len)
- {
- DBG1(DBG_LIB, "digestInfo field in signature is"
- " followed by %u surplus bytes",
- em.len - object.len);
- goto end_parser;
- }
- break;
- }
- case DIGEST_INFO_ALGORITHM:
- {
- int hash_oid = asn1_parse_algorithmIdentifier(object,
- parser->get_level(parser)+1, NULL);
-
- hash_algorithm = hasher_algorithm_from_oid(hash_oid);
- if (hash_algorithm == HASH_UNKNOWN || hash_algorithm != algorithm)
- {
- DBG1(DBG_LIB, "expected hash algorithm %N, but found"
- " %N (OID: %#B)", hash_algorithm_names, algorithm,
- hash_algorithm_names, hash_algorithm, &object);
- goto end_parser;
- }
- break;
- }
- case DIGEST_INFO_DIGEST:
- {
- chunk_t hash;
- hasher_t *hasher;
-
- hasher = lib->crypto->create_hasher(lib->crypto, hash_algorithm);
- if (hasher == NULL)
- {
- DBG1(DBG_LIB, "hash algorithm %N not supported",
- hash_algorithm_names, hash_algorithm);
- goto end_parser;
- }
-
- if (object.len != hasher->get_hash_size(hasher))
- {
- DBG1(DBG_LIB, "hash size in signature is %u bytes"
- " instead of %u bytes", object.len,
- hasher->get_hash_size(hasher));
- hasher->destroy(hasher);
- goto end_parser;
- }
-
- /* build our own hash and compare */
- if (!hasher->allocate_hash(hasher, data, &hash))
- {
- hasher->destroy(hasher);
- goto end_parser;
- }
- hasher->destroy(hasher);
- success = memeq_const(object.ptr, hash.ptr, hash.len);
- free(hash.ptr);
- break;
- }
- default:
- break;
- }
- }
+ /* unpack signature */
+ em = rsavp1(this, signature);
-end_parser:
- success &= parser->success(parser);
- parser->destroy(parser);
- }
+ success = chunk_equals_const(em_expected, em);
-end:
- free(em_ori.ptr);
+ chunk_free(&em_expected);
+ chunk_free(&em);
return success;
}