diff options
author | Martin Willi <martin@strongswan.org> | 2009-08-24 14:06:41 +0200 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2009-08-26 11:23:52 +0200 |
commit | 741680d1799f617ec806a865a9fa69ccffb774c2 (patch) | |
tree | c623162b7d527f1ebc3a19ee47b7c116b8e35bb1 | |
parent | 1384a42e1b212ed8dd56112a151e0efde45c06e4 (diff) | |
download | strongswan-741680d1799f617ec806a865a9fa69ccffb774c2.tar.bz2 strongswan-741680d1799f617ec806a865a9fa69ccffb774c2.tar.xz |
updated gmp plugin to new private/public key API, use encoder framework
-rw-r--r-- | src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c | 234 | ||||
-rw-r--r-- | src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c | 176 |
2 files changed, 130 insertions, 280 deletions
diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c index 97322289b..5cea55cd3 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) 2005-2008 Martin Willi + * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -44,11 +44,6 @@ struct private_gmp_rsa_private_key_t { gmp_rsa_private_key_t public; /** - * Version of key, as encoded in PKCS#1 - */ - u_int version; - - /** * Public modulus. */ mpz_t n; @@ -92,34 +87,33 @@ struct private_gmp_rsa_private_key_t { * Keysize in bytes. */ size_t k; - - /** - * Keyid formed as a SHA-1 hash of a publicKey object - */ - identification_t* keyid; - - /** - * Keyid formed as a SHA-1 hash of a publicKeyInfo object - */ - identification_t* keyid_info; /** * reference count */ - refcount_t ref; + refcount_t ref; }; /** - * Shared functions defined in gmp_rsa_public_key.c + * Convert a MP integer into a chunk_t */ -extern bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, - identification_t **keyid, - identification_t **keyid_info); +chunk_t gmp_mpz_to_chunk(const mpz_t value) +{ + chunk_t n; + + n.len = 1 + mpz_sizeinbase(value, 2) / BITS_PER_BYTE; + n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value); + if (n.ptr == NULL) + { /* if we have zero in "value", gmp returns NULL */ + n.len = 0; + } + return n; +} /** * Auxiliary function overwriting private key material with zero bytes */ -static void mpz_clear_randomized(mpz_t z) +static void mpz_clear_sensitive(mpz_t z) { size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE; u_int8_t *random = alloca(len); @@ -194,8 +188,8 @@ static chunk_t rsadp(private_gmp_rsa_private_key_t *this, chunk_t data) decrypted.len = 0; } - mpz_clear_randomized(t1); - mpz_clear_randomized(t2); + mpz_clear_sensitive(t1); + mpz_clear_sensitive(t2); return decrypted; } @@ -364,47 +358,6 @@ static size_t get_keysize(private_gmp_rsa_private_key_t *this) } /** - * Implementation of gmp_rsa_private_key.get_id. - */ -static identification_t* get_id(private_gmp_rsa_private_key_t *this, - id_type_t type) -{ - switch (type) - { - case ID_PUBKEY_INFO_SHA1: - return this->keyid_info; - case ID_PUBKEY_SHA1: - return this->keyid; - default: - return NULL; - } -} - -/** - * Convert a MP integer into a chunk_t - */ -chunk_t gmp_mpz_to_chunk(const mpz_t value) -{ - chunk_t n; - - n.len = 1 + mpz_sizeinbase(value, 2) / BITS_PER_BYTE; - n.ptr = mpz_export(NULL, NULL, 1, n.len, 1, 0, value); - if (n.ptr == NULL) - { /* if we have zero in "value", gmp returns NULL */ - n.len = 0; - } - return n; -} - -/** - * Convert a MP integer into a DER coded ASN.1 object - */ -chunk_t gmp_mpz_to_asn1(const mpz_t value) -{ - return asn1_wrap(ASN1_INTEGER, "m", gmp_mpz_to_chunk(value)); -} - -/** * Implementation of gmp_rsa_private_key.get_public_key. */ static public_key_t* get_public_key(private_gmp_rsa_private_key_t *this) @@ -428,27 +381,7 @@ static public_key_t* get_public_key(private_gmp_rsa_private_key_t *this) */ static bool equals(private_gmp_rsa_private_key_t *this, private_key_t *other) { - identification_t *keyid; - - if (&this->public.interface == other) - { - return TRUE; - } - if (other->get_type(other) != KEY_RSA) - { - return FALSE; - } - keyid = other->get_id(other, ID_PUBKEY_SHA1); - if (keyid && keyid->equals(keyid, this->keyid)) - { - return TRUE; - } - keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1); - if (keyid && keyid->equals(keyid, this->keyid_info)) - { - return TRUE; - } - return FALSE; + return private_key_equals(&this->public.interface, other); } /** @@ -456,40 +389,67 @@ static bool equals(private_gmp_rsa_private_key_t *this, private_key_t *other) */ static bool belongs_to(private_gmp_rsa_private_key_t *this, public_key_t *public) { - identification_t *keyid; + return private_key_belongs_to(&this->public.interface, public); +} - if (public->get_type(public) != KEY_RSA) - { - return FALSE; - } - keyid = public->get_id(public, ID_PUBKEY_SHA1); - if (keyid && keyid->equals(keyid, this->keyid)) - { - return TRUE; - } - keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1); - if (keyid && keyid->equals(keyid, this->keyid_info)) - { - return TRUE; - } - return FALSE; +/** + * Implementation of private_key_t.get_encoding + */ +static bool get_encoding(private_gmp_rsa_private_key_t *this, + key_encoding_type_t type, chunk_t *encoding) +{ + chunk_t n, e, d, p, q, exp1, exp2, coeff; + bool success; + + n = gmp_mpz_to_chunk(this->n); + e = gmp_mpz_to_chunk(this->e); + d = gmp_mpz_to_chunk(this->d); + p = gmp_mpz_to_chunk(this->p); + q = gmp_mpz_to_chunk(this->q); + exp1 = gmp_mpz_to_chunk(this->exp1); + exp2 = gmp_mpz_to_chunk(this->exp2); + coeff = gmp_mpz_to_chunk(this->coeff); + + success = lib->encoding->encode(lib->encoding, + type, NULL, encoding, KEY_PART_RSA_MODULUS, n, + KEY_PART_RSA_PUB_EXP, e, KEY_PART_RSA_PRIV_EXP, d, + KEY_PART_RSA_PRIME1, p, KEY_PART_RSA_PRIME2, q, + KEY_PART_RSA_EXP1, exp1, KEY_PART_RSA_EXP2, exp2, + KEY_PART_RSA_COEFF, coeff, KEY_PART_END); + chunk_free(&n); + chunk_free(&e); + chunk_clear(&d); + chunk_clear(&p); + chunk_clear(&q); + chunk_clear(&exp1); + chunk_clear(&exp2); + chunk_clear(&coeff); + + return success; } /** - * Implementation of private_key_t.get_encoding. + * Implementation of private_key_t.get_fingerprint */ -static chunk_t get_encoding(private_gmp_rsa_private_key_t *this) +static bool get_fingerprint(private_gmp_rsa_private_key_t *this, + key_encoding_type_t type, chunk_t *fp) { - return asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm", - ASN1_INTEGER_0, - gmp_mpz_to_asn1(this->n), - gmp_mpz_to_asn1(this->e), - gmp_mpz_to_asn1(this->d), - gmp_mpz_to_asn1(this->p), - gmp_mpz_to_asn1(this->q), - gmp_mpz_to_asn1(this->exp1), - gmp_mpz_to_asn1(this->exp2), - gmp_mpz_to_asn1(this->coeff)); + chunk_t n, e; + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + n = gmp_mpz_to_chunk(this->n); + e = gmp_mpz_to_chunk(this->e); + + success = lib->encoding->encode(lib->encoding, type, this, fp, + KEY_PART_RSA_MODULUS, n, KEY_PART_RSA_PUB_EXP, e, KEY_PART_END); + chunk_free(&n); + chunk_free(&e); + + return success; } /** @@ -499,7 +459,6 @@ static private_gmp_rsa_private_key_t* get_ref(private_gmp_rsa_private_key_t *thi { ref_get(&this->ref); return this; - } /** @@ -509,16 +468,15 @@ static void destroy(private_gmp_rsa_private_key_t *this) { if (ref_put(&this->ref)) { - mpz_clear_randomized(this->n); - mpz_clear_randomized(this->e); - mpz_clear_randomized(this->p); - mpz_clear_randomized(this->q); - mpz_clear_randomized(this->d); - mpz_clear_randomized(this->exp1); - mpz_clear_randomized(this->exp2); - mpz_clear_randomized(this->coeff); - DESTROY_IF(this->keyid); - DESTROY_IF(this->keyid_info); + mpz_clear_sensitive(this->n); + mpz_clear_sensitive(this->e); + mpz_clear_sensitive(this->p); + mpz_clear_sensitive(this->q); + mpz_clear_sensitive(this->d); + mpz_clear_sensitive(this->exp1); + mpz_clear_sensitive(this->exp2); + mpz_clear_sensitive(this->coeff); + lib->encoding->clear_cache(lib->encoding, this); free(this); } } @@ -612,9 +570,9 @@ static status_t check(private_gmp_rsa_private_key_t *this) status = FAILED; } - mpz_clear_randomized(t); - mpz_clear_randomized(u); - mpz_clear_randomized(q1); + mpz_clear_sensitive(t); + mpz_clear_sensitive(u); + mpz_clear_sensitive(q1); if (status != SUCCESS) { DBG1("key integrity tests failed"); @@ -633,16 +591,14 @@ static private_gmp_rsa_private_key_t *gmp_rsa_private_key_create_empty(void) this->public.interface.sign = (bool (*) (private_key_t*, signature_scheme_t, chunk_t, chunk_t*))sign; this->public.interface.decrypt = (bool (*) (private_key_t*, chunk_t, chunk_t*))decrypt; this->public.interface.get_keysize = (size_t (*) (private_key_t*))get_keysize; - this->public.interface.get_id = (identification_t* (*) (private_key_t*, id_type_t))get_id; this->public.interface.get_public_key = (public_key_t* (*) (private_key_t*))get_public_key; this->public.interface.equals = (bool (*) (private_key_t*, private_key_t*))equals; this->public.interface.belongs_to = (bool (*) (private_key_t*, public_key_t*))belongs_to; - this->public.interface.get_encoding = (chunk_t (*) (private_key_t*))get_encoding; + this->public.interface.get_fingerprint = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint; + this->public.interface.get_encoding = (bool(*)(private_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding; this->public.interface.get_ref = (private_key_t* (*) (private_key_t*))get_ref; this->public.interface.destroy = (void (*) (private_key_t*))destroy; - this->keyid = NULL; - this->keyid_info = NULL; this->ref = 1; return this; @@ -712,9 +668,9 @@ static gmp_rsa_private_key_t *generate(size_t key_size) mpz_add(coeff, coeff, p); } - mpz_clear_randomized(q1); - mpz_clear_randomized(m); - mpz_clear_randomized(t); + mpz_clear_sensitive(q1); + mpz_clear_sensitive(m); + mpz_clear_sensitive(t); /* apply values */ *(this->p) = *p; @@ -774,12 +730,6 @@ static gmp_rsa_private_key_t *load(chunk_t n, chunk_t e, chunk_t d, mpz_import(this->exp2, exp2.len, 1, 1, 1, 0, exp2.ptr); } this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - if (!gmp_rsa_public_key_build_id(this->n, this->e, - &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } if (check(this) != SUCCESS) { destroy(this); @@ -853,7 +803,7 @@ static void add(private_builder_t *this, builder_part_t part, ...) this->exp1 = va_arg(args, chunk_t); break; case BUILD_RSA_EXP2: - this->exp1 = va_arg(args, chunk_t); + this->exp2 = va_arg(args, chunk_t); break; case BUILD_RSA_COEFF: this->coeff = va_arg(args, chunk_t); diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c index 96e168777..ec47ea1e0 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c @@ -55,16 +55,6 @@ struct private_gmp_rsa_public_key_t { size_t k; /** - * Keyid formed as a SHA-1 hash of a publicKeyInfo object - */ - identification_t *keyid_info; - - /** - * Keyid formed as a SHA-1 hash of a publicKey object - */ - identification_t *keyid; - - /** * reference counter */ refcount_t ref; @@ -74,7 +64,6 @@ 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); -extern chunk_t gmp_mpz_to_asn1(const mpz_t value); /** * RSAEP algorithm specified in PKCS#1. @@ -314,7 +303,7 @@ static bool verify(private_gmp_rsa_public_key_t *this, signature_scheme_t scheme } } -#define MIN_PS_PADDING 8 +#define MIN_PS_PADDING 8 /** * Implementation of public_key_t.encrypt. @@ -384,27 +373,7 @@ static bool encrypt_(private_gmp_rsa_public_key_t *this, chunk_t plain, */ static bool equals(private_gmp_rsa_public_key_t *this, public_key_t *other) { - identification_t *keyid; - - if (&this->public.interface == other) - { - return TRUE; - } - if (other->get_type(other) != KEY_RSA) - { - return FALSE; - } - keyid = other->get_id(other, ID_PUBKEY_SHA1); - if (keyid && keyid->equals(keyid, this->keyid)) - { - return TRUE; - } - keyid = other->get_id(other, ID_PUBKEY_INFO_SHA1); - if (keyid && keyid->equals(keyid, this->keyid_info)) - { - return TRUE; - } - return FALSE; + return public_key_equals(&this->public.interface, other); } /** @@ -416,72 +385,47 @@ static size_t get_keysize(private_gmp_rsa_public_key_t *this) } /** - * Build the PGP version 3 RSA key identifier from n and e using - * MD5 hashed modulus and exponent. + * Implementation of public_key_t.get_encoding */ -static identification_t* gmp_rsa_build_pgp_v3_keyid(mpz_t n, mpz_t e) +static bool get_encoding(private_gmp_rsa_public_key_t *this, + key_encoding_type_t type, chunk_t *encoding) { - identification_t *keyid; - chunk_t modulus, mod, exponent, exp, hash; - hasher_t *hasher; + chunk_t n, e; + bool success; - hasher= lib->crypto->create_hasher(lib->crypto, HASH_MD5); - if (hasher == NULL) - { - DBG1("computation of PGP V3 keyid failed, no MD5 hasher is available"); - return NULL; - } - mod = modulus = gmp_mpz_to_chunk(n); - exp = exponent = gmp_mpz_to_chunk(e); - - /* remove leading zero bytes before hashing modulus and exponent */ - while (mod.len > 0 && *mod.ptr == 0x00) - { - mod.ptr++; - mod.len--; - } - while (exp.len > 0 && *exp.ptr == 0x00) - { - exp.ptr++; - exp.len--; - } - hasher->allocate_hash(hasher, mod, NULL); - hasher->allocate_hash(hasher, exp, &hash); - hasher->destroy(hasher); - keyid = identification_create_from_encoding(ID_KEY_ID, hash); - free(hash.ptr); - free(modulus.ptr); - free(exponent.ptr); - return keyid; + n = gmp_mpz_to_chunk(this->n); + e = gmp_mpz_to_chunk(this->e); + + success = lib->encoding->encode(lib->encoding, type, NULL, encoding, + KEY_PART_RSA_MODULUS, n, KEY_PART_RSA_PUB_EXP, e, KEY_PART_END); + chunk_free(&n); + chunk_free(&e); + + return success; } /** - * Implementation of public_key_t.get_id. + * Implementation of public_key_t.get_fingerprint */ -static identification_t *get_id(private_gmp_rsa_public_key_t *this, - id_type_t type) +static bool get_fingerprint(private_gmp_rsa_public_key_t *this, + key_encoding_type_t type, chunk_t *fp) { - switch (type) + chunk_t n, e; + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) { - case ID_PUBKEY_INFO_SHA1: - return this->keyid_info; - case ID_PUBKEY_SHA1: - return this->keyid; - case ID_KEY_ID: - return gmp_rsa_build_pgp_v3_keyid(this->n, this->e); - default: - return NULL; + return TRUE; } -} - -/* - * Implementation of public_key_t.get_encoding. - */ -static chunk_t get_encoding(private_gmp_rsa_public_key_t *this) -{ - return asn1_wrap(ASN1_SEQUENCE, "mm", - gmp_mpz_to_asn1(this->n), - gmp_mpz_to_asn1(this->e)); + n = gmp_mpz_to_chunk(this->n); + e = gmp_mpz_to_chunk(this->e); + + success = lib->encoding->encode(lib->encoding, type, this, fp, + KEY_PART_RSA_MODULUS, n, KEY_PART_RSA_PUB_EXP, e, KEY_PART_END); + chunk_free(&n); + chunk_free(&e); + + return success; } /** @@ -502,8 +446,7 @@ static void destroy(private_gmp_rsa_public_key_t *this) { mpz_clear(this->n); mpz_clear(this->e); - DESTROY_IF(this->keyid); - DESTROY_IF(this->keyid_info); + lib->encoding->clear_cache(lib->encoding, this); free(this); } } @@ -520,55 +463,17 @@ static private_gmp_rsa_public_key_t *gmp_rsa_public_key_create_empty() this->public.interface.encrypt = (bool (*) (public_key_t*, chunk_t, chunk_t*))encrypt_; this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals; this->public.interface.get_keysize = (size_t (*) (public_key_t*))get_keysize; - this->public.interface.get_id = (identification_t* (*) (public_key_t*, id_type_t))get_id; - this->public.interface.get_encoding = (chunk_t(*) (public_key_t*))get_encoding; + this->public.interface.get_fingerprint = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *fp))get_fingerprint; + this->public.interface.get_encoding = (bool(*)(public_key_t*, key_encoding_type_t type, chunk_t *encoding))get_encoding; this->public.interface.get_ref = (public_key_t* (*) (public_key_t *this))get_ref; this->public.interface.destroy = (void (*) (public_key_t *this))destroy; - this->keyid = NULL; - this->keyid_info = NULL; this->ref = 1; return this; } /** - * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info). - * Also used in rsa_private_key.c. - */ -bool gmp_rsa_public_key_build_id(mpz_t n, mpz_t e, identification_t **keyid, - identification_t **keyid_info) -{ - chunk_t publicKeyInfo, publicKey, hash; - hasher_t *hasher; - - hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); - if (hasher == NULL) - { - DBG1("SHA1 hash algorithm not supported, unable to use RSA"); - return FALSE; - } - publicKey = asn1_wrap(ASN1_SEQUENCE, "mm", - gmp_mpz_to_asn1(n), - gmp_mpz_to_asn1(e)); - hasher->allocate_hash(hasher, publicKey, &hash); - *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash); - chunk_free(&hash); - - publicKeyInfo = asn1_wrap(ASN1_SEQUENCE, "cm", - asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), - asn1_bitstring("m", publicKey)); - hasher->allocate_hash(hasher, publicKeyInfo, &hash); - *keyid_info = identification_create_from_encoding(ID_PUBKEY_INFO_SHA1, hash); - chunk_free(&hash); - - hasher->destroy(hasher); - chunk_free(&publicKeyInfo); - - return TRUE; -} - -/** * Load a public key from n and e */ static gmp_rsa_public_key_t *load(chunk_t n, chunk_t e) @@ -581,13 +486,8 @@ static gmp_rsa_public_key_t *load(chunk_t n, chunk_t e) mpz_import(this->n, n.len, 1, 1, 1, 0, n.ptr); mpz_import(this->e, e.len, 1, 1, 1, 0, e.ptr); - this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; - if (!gmp_rsa_public_key_build_id(this->n, this->e, - &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } + this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; + return &this->public; } |