summaryrefslogtreecommitdiff
path: root/src/libstrongswan/crypto/rsa/rsa_private_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/crypto/rsa/rsa_private_key.c')
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_private_key.c123
1 files changed, 36 insertions, 87 deletions
diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.c b/src/libstrongswan/crypto/rsa/rsa_private_key.c
index ec2f2fc74..1b1499887 100644
--- a/src/libstrongswan/crypto/rsa/rsa_private_key.c
+++ b/src/libstrongswan/crypto/rsa/rsa_private_key.c
@@ -6,8 +6,10 @@
*/
/*
- * Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2007-2008 Andreas Steffen
+ *
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,7 +22,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: rsa_private_key.c 3306 2007-10-17 02:55:53Z andreas $
+ * RCSID $Id: rsa_private_key.c 3429 2008-01-27 20:59:22Z andreas $
*/
#include <gmp.h>
@@ -40,6 +42,7 @@
* defined in rsa_public_key.c
*/
extern chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e);
+extern chunk_t rsa_public_key_id_create(const mpz_t n, const mpz_t e);
/**
* Public exponent to use for key generation.
@@ -111,7 +114,6 @@ struct private_rsa_private_key_t {
* Keyid formed as a SHA-1 hash of a publicKeyInfo object
*/
chunk_t keyid;
-
/**
* @brief Implements the RSADP algorithm specified in PKCS#1.
@@ -129,16 +131,6 @@ struct private_rsa_private_key_t {
* @return processed data
*/
chunk_t (*rsasp1) (private_rsa_private_key_t *this, chunk_t data);
-
- /**
- * @brief Generate a prime value.
- *
- * @param this calling object
- * @param prime_size size of the prime, in bytes
- * @param[out] prime uninitialized mpz
- */
- status_t (*compute_prime) (private_rsa_private_key_t *this, size_t prime_size, mpz_t *prime);
-
};
/* ASN.1 definition of a PKCS#1 RSA private key */
@@ -173,8 +165,6 @@ static const asn1Object_t privkey_objects[] = {
#define PRIV_KEY_COEFF 9
#define PRIV_KEY_ROOF 16
-static private_rsa_private_key_t *rsa_private_key_create_empty(void);
-
/**
* Auxiliary function overwriting private key material with
* pseudo-random bytes before releasing it
@@ -196,9 +186,9 @@ static void mpz_clear_randomized(mpz_t z)
}
/**
- * Implementation of private_rsa_private_key_t.compute_prime.
+ * Generate a random prime number with prime_len bytes
*/
-static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_size, mpz_t *prime)
+static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_len, mpz_t *prime)
{
randomizer_t *randomizer;
chunk_t random_bytes;
@@ -209,7 +199,8 @@ static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_size
do
{
- status = randomizer->allocate_random_bytes(randomizer, prime_size, &random_bytes);
+ DBG1(" generating %d bit prime from %s ...", BITS_PER_BYTE * prime_len, DEV_RANDOM);
+ status = randomizer->allocate_random_bytes(randomizer, prime_len, &random_bytes);
if (status != SUCCESS)
{
randomizer->destroy(randomizer);
@@ -230,7 +221,7 @@ static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_size
chunk_free_randomized(&random_bytes);
}
/* check if it isnt too large */
- while (((mpz_sizeinbase(*prime, 2) + 7) / 8) > prime_size);
+ while (((mpz_sizeinbase(*prime, 2) + 7) / BITS_PER_BYTE) > prime_len);
randomizer->destroy(randomizer);
return SUCCESS;
@@ -269,7 +260,7 @@ static chunk_t rsadp(private_rsa_private_key_t *this, chunk_t data)
}
/**
- * Implementation of rsa_private_key_t.eme_pkcs1_decrypt.
+ * Implementation of rsa_private_key_t.pkcs1_decrypt.
*/
static status_t pkcs1_decrypt(private_rsa_private_key_t *this,
chunk_t in, chunk_t *out)
@@ -319,47 +310,14 @@ static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this,
chunk_t data, chunk_t *signature)
{
hasher_t *hasher;
- chunk_t em, digestInfo, hash_id, hash;
-
- /* get oid string prepended to hash */
- switch (hash_algorithm)
- {
- case HASH_MD2:
- {
- hash_id =ASN1_md2_id;
- break;
- }
- case HASH_MD5:
- {
- hash_id = ASN1_md5_id;
- break;
- }
- case HASH_SHA1:
- {
- hash_id = ASN1_sha1_id;
- break;
- }
- case HASH_SHA256:
- {
- hash_id = ASN1_sha256_id;
- break;
- }
- case HASH_SHA384:
- {
- hash_id = ASN1_sha384_id;
- break;
- }
- case HASH_SHA512:
- {
- hash_id = ASN1_sha512_id;
- break;
- }
- default:
- {
- return NOT_SUPPORTED;
- }
+ chunk_t em, digestInfo, hash;
+ int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
+
+ if (hash_oid == OID_UNKNOWN)
+ {
+ return NOT_SUPPORTED;
}
-
+
/* get hasher */
hasher = hasher_create(hash_algorithm);
if (hasher == NULL)
@@ -373,7 +331,7 @@ static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this,
/* build DER-encoded digestInfo */
digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
- hash_id,
+ asn1_algorithmIdentifier(hash_oid),
asn1_simple_object(ASN1_OCTET_STRING, hash)
);
chunk_free(&hash);
@@ -432,7 +390,7 @@ static bool pkcs1_write(private_rsa_private_key_t *this, const char *filename, b
*/
rsa_public_key_t *get_public_key(private_rsa_private_key_t *this)
{
- return NULL;
+ return rsa_public_key_create(this->n, this->e);
}
/**
@@ -455,13 +413,13 @@ static status_t check(private_rsa_private_key_t *this)
/* 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)
+ if (this->k < 512 / BITS_PER_BYTE)
{
return FAILED;
}
/* we picked a max modulus size to simplify buffer allocation */
- if (this->k > 8192/8)
+ if (this->k > 8192 / BITS_PER_BYTE)
{
return FAILED;
}
@@ -572,7 +530,6 @@ static private_rsa_private_key_t *rsa_private_key_create_empty(void)
/* private functions */
this->rsadp = rsadp;
this->rsasp1 = rsadp; /* same algorithm */
- this->compute_prime = compute_prime;
this->keyid = chunk_empty;
@@ -587,20 +544,17 @@ rsa_private_key_t *rsa_private_key_create(size_t key_size)
mpz_t p, q, n, e, d, exp1, exp2, coeff;
mpz_t m, q1, t;
private_rsa_private_key_t *this;
-
- this = rsa_private_key_create_empty();
- key_size = key_size / 8;
+ size_t key_len = key_size / BITS_PER_BYTE;
+ size_t prime_len = key_len / 2;
/* Get values of primes p and q */
- if (this->compute_prime(this, key_size/2, &p) != SUCCESS)
+ if (compute_prime(this, prime_len, &p) != SUCCESS)
{
- free(this);
return NULL;
}
- if (this->compute_prime(this, key_size/2, &q) != SUCCESS)
+ if (compute_prime(this, prime_len, &q) != SUCCESS)
{
mpz_clear(p);
- free(this);
return NULL;
}
@@ -648,7 +602,13 @@ rsa_private_key_t *rsa_private_key_create(size_t key_size)
mpz_clear_randomized(m);
mpz_clear_randomized(t);
- /* apply values */
+ /* determine exact the modulus size in bits */
+ key_size = mpz_sizeinbase(n, 2);
+
+ /* create and fill in rsa_private_key_t object */
+ this = rsa_private_key_create_empty();
+ this->k = (key_size + 7) / BITS_PER_BYTE;
+ this->keyid = rsa_public_key_id_create(n, e);
*(this->p) = *p;
*(this->q) = *q;
*(this->n) = *n;
@@ -657,10 +617,8 @@ rsa_private_key_t *rsa_private_key_create(size_t key_size)
*(this->exp1) = *exp1;
*(this->exp2) = *exp2;
*(this->coeff) = *coeff;
-
- /* set key size in bytes */
- this->k = key_size;
-
+ DBG1("generated %d bit RSA key with keyid: %#B", key_size, &this->keyid);
+
return &this->public;
}
@@ -733,17 +691,8 @@ rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
}
this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
+ this->keyid = rsa_public_key_id_create(this->n, this->e);
- /* form the keyid as a SHA-1 hash of a publicKeyInfo object */
- {
- chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(this->n, this->e);
- hasher_t *hasher = hasher_create(HASH_SHA1);
-
- hasher->allocate_hash(hasher, publicKeyInfo, &this->keyid);
- hasher->destroy(hasher);
- free(publicKeyInfo.ptr);
- }
-
if (check(this) != SUCCESS)
{
destroy(this);