aboutsummaryrefslogtreecommitdiffstats
path: root/Source/lib/crypto
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2006-04-12 08:38:10 +0000
committerMartin Willi <martin@strongswan.org>2006-04-12 08:38:10 +0000
commit2cb7d3cab2b23f50bb406c99b8193a62ce4b8c00 (patch)
treea9876e5ff769be6e6fe06b11585b7e2e478b7c13 /Source/lib/crypto
parent8f1c27babbac024a92fca48cf84581bb32e108b0 (diff)
downloadstrongswan-2cb7d3cab2b23f50bb406c99b8193a62ce4b8c00.tar.bz2
strongswan-2cb7d3cab2b23f50bb406c99b8193a62ce4b8c00.tar.xz
- some improvements to new asn1 stuff
- to be continued
Diffstat (limited to 'Source/lib/crypto')
-rw-r--r--Source/lib/crypto/rsa/rsa_private_key.c211
-rw-r--r--Source/lib/crypto/rsa/rsa_public_key.c1
2 files changed, 118 insertions, 94 deletions
diff --git a/Source/lib/crypto/rsa/rsa_private_key.c b/Source/lib/crypto/rsa/rsa_private_key.c
index af09a2af5..c53dac37b 100644
--- a/Source/lib/crypto/rsa/rsa_private_key.c
+++ b/Source/lib/crypto/rsa/rsa_private_key.c
@@ -28,7 +28,12 @@
#include "rsa_private_key.h"
#include <daemon.h>
-#include <asn1-pluto/asn1-pluto.h>
+#ifdef NEW_ASN1
+# include <asn1/asn1.h>
+# include <asn1/der_decoder.h>
+#else
+# include <asn1-pluto/asn1-pluto.h>
+#endif
/*
@@ -138,8 +143,7 @@ struct private_rsa_private_key_t {
};
-#if 0
-Not used yet, since we use plutos ASN1 stuff
+#ifdef NEW_ASN1
/**
* Rules for de-/encoding of a private key from/in ASN1
*/
@@ -156,8 +160,7 @@ static asn1_rule_t rsa_private_key_rules[] = {
{ ASN1_INTEGER, ASN1_MPZ, offsetof(private_rsa_private_key_t, coeff), 0},
{ASN1_END, 0, 0, 0},
};
-#endif
-
+#else
struct {
const char *name;
size_t offset;
@@ -199,7 +202,7 @@ static const asn1Object_t privkeyObjects[] = {
#define PKCS1_PRIV_KEY_PUB_EXP 3
#define PKCS1_PRIV_KEY_COEFF 9
#define PKCS1_PRIV_KEY_ROOF 16
-
+#endif
static private_rsa_private_key_t *rsa_private_key_create_empty();
@@ -447,6 +450,100 @@ static bool belongs_to(private_rsa_private_key_t *this, rsa_public_key_t *public
}
/**
+ * Check the loaded key if it is valid and usable
+ * TODO: Log errors
+ */
+static status_t check(private_rsa_private_key_t *this)
+{
+ mpz_t t, u, q1;
+ status_t status = SUCCESS;
+
+ /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
+ * We actually require more (for security).
+ */
+ if (this->k < 512/8)
+ {
+ return FAILED;
+ }
+
+ /* we picked a max modulus size to simplify buffer allocation */
+ if (this->k > 8192/8)
+ {
+ return FAILED;
+ }
+
+ mpz_init(t);
+ mpz_init(u);
+ mpz_init(q1);
+
+ /* check that n == p * q */
+ mpz_mul(u, this->p, this->q);
+ if (mpz_cmp(u, this->n) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that e divides neither p-1 nor q-1 */
+ mpz_sub_ui(t, this->p, 1);
+ mpz_mod(t, t, this->e);
+ if (mpz_cmp_ui(t, 0) == 0)
+ {
+ status = FAILED;
+ }
+
+ mpz_sub_ui(t, this->q, 1);
+ mpz_mod(t, t, this->e);
+ if (mpz_cmp_ui(t, 0) == 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that d is e^-1 (mod lcm(p-1, q-1)) */
+ /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
+ mpz_sub_ui(q1, this->q, 1);
+ mpz_sub_ui(u, this->p, 1);
+ mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
+ mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
+ mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
+
+ mpz_mul(t, this->d, this->e);
+ mpz_mod(t, t, u);
+ if (mpz_cmp_ui(t, 1) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that exp1 is d mod (p-1) */
+ mpz_sub_ui(u, this->p, 1);
+ mpz_mod(t, this->d, u);
+ if (mpz_cmp(t, this->exp1) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that exp2 is d mod (q-1) */
+ mpz_sub_ui(u, this->q, 1);
+ mpz_mod(t, this->d, u);
+ if (mpz_cmp(t, this->exp2) != 0)
+ {
+ status = FAILED;
+ }
+
+ /* check that coeff is (q^-1) mod p */
+ mpz_mul(t, this->coeff, this->q);
+ mpz_mod(t, t, this->p);
+ if (mpz_cmp_ui(t, 1) != 0)
+ {
+ status = FAILED;
+ }
+
+ mpz_clear(t);
+ mpz_clear(u);
+ mpz_clear(q1);
+ return status;
+}
+
+/**
* Implementation of rsa_private_key.clone.
*/
static rsa_private_key_t* _clone(private_rsa_private_key_t *this)
@@ -595,9 +692,7 @@ rsa_private_key_t *rsa_private_key_create(size_t key_size)
return &this->public;
}
-
-#if 0
-NOT used yet, since we use plutos ASN1 parser for now
+#ifdef NEW_ASN1
/*
* see header
*/
@@ -627,98 +722,20 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t chunk)
return NULL;
}
this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
- return &this->public;
-}
-#endif
-
-static status_t check(private_rsa_private_key_t *this)
-{
- mpz_t t, u, q1;
- status_t status = SUCCESS;
-
- /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
- * We actually require more (for security).
- */
- if (this->k < 512/8)
- return FAILED;
-
- /* we picked a max modulus size to simplify buffer allocation */
- if (this->k > 8192/8)
- return FAILED;
-
- mpz_init(t);
- mpz_init(u);
- mpz_init(q1);
-
- /* check that n == p * q */
- mpz_mul(u, this->p, this->q);
- if (mpz_cmp(u, this->n) != 0)
- {
- status = FAILED;
- }
-
- /* check that e divides neither p-1 nor q-1 */
- mpz_sub_ui(t, this->p, 1);
- mpz_mod(t, t, this->e);
- if (mpz_cmp_ui(t, 0) == 0)
- {
- status = FAILED;
- }
-
- mpz_sub_ui(t, this->q, 1);
- mpz_mod(t, t, this->e);
- if (mpz_cmp_ui(t, 0) == 0)
- {
- status = FAILED;
- }
-
- /* check that d is e^-1 (mod lcm(p-1, q-1)) */
- /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
- mpz_sub_ui(q1, this->q, 1);
- mpz_sub_ui(u, this->p, 1);
- mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
- mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
- mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
-
- mpz_mul(t, this->d, this->e);
- mpz_mod(t, t, u);
- if (mpz_cmp_ui(t, 1) != 0)
- {
- status = FAILED;
- }
- /* check that exp1 is d mod (p-1) */
- mpz_sub_ui(u, this->p, 1);
- mpz_mod(t, this->d, u);
- if (mpz_cmp(t, this->exp1) != 0)
- {
- status = FAILED;
- }
-
- /* check that exp2 is d mod (q-1) */
- mpz_sub_ui(u, this->q, 1);
- mpz_mod(t, this->d, u);
- if (mpz_cmp(t, this->exp2) != 0)
+ if (check(this) != SUCCESS)
{
- status = FAILED;
+ destroy(this);
+ return NULL;
}
-
- /* check that coeff is (q^-1) mod p */
- mpz_mul(t, this->coeff, this->q);
- mpz_mod(t, t, this->p);
- if (mpz_cmp_ui(t, 1) != 0)
+ else
{
- status = FAILED;
+ return &this->public;
}
-
- mpz_clear(t);
- mpz_clear(u);
- mpz_clear(q1);
- return status;
}
-
+#else
/*
- * Parses a PKCS#1 private key
+ * see header
*/
rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
{
@@ -745,6 +762,7 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
{
if (!extract_object(privkeyObjects, &objectID, &object, &level, &ctx))
{
+ destroy(this);
return FALSE;
}
if (objectID == PKCS1_PRIV_KEY_VERSION)
@@ -765,6 +783,9 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
}
objectID++;
}
+
+ this->k = (mpz_sizeinbase(this->n, 2) + 7) / 8;
+
if (check(this) != SUCCESS)
{
destroy(this);
@@ -775,9 +796,11 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
return &this->public;
}
}
+#endif
/*
* see header
+ * TODO: PEM files
*/
rsa_private_key_t *rsa_private_key_create_from_file(char *filename, char *passphrase)
{
diff --git a/Source/lib/crypto/rsa/rsa_public_key.c b/Source/lib/crypto/rsa/rsa_public_key.c
index 5b85f5256..61739dd38 100644
--- a/Source/lib/crypto/rsa/rsa_public_key.c
+++ b/Source/lib/crypto/rsa/rsa_public_key.c
@@ -37,6 +37,7 @@
* hash algorithm OIDs. These also contain
* the length of the following hash.
* These values are also used in rsa_private_key.c.
+ * TODO: We may move them in asn1 sometime...
*/
u_int8_t md2_oid[] = {