diff options
Diffstat (limited to 'src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c')
-rw-r--r-- | src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c | 215 |
1 files changed, 44 insertions, 171 deletions
diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c index bc1ba35b6..cb3e80a69 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Martin Willi * Copyright (C) 2008 Tobias Brunner * Hochschule fuer Technik Rapperswil * @@ -19,7 +20,6 @@ #include <openssl/evp.h> #include <openssl/rsa.h> -#include <openssl/x509.h> typedef struct private_openssl_rsa_public_key_t private_openssl_rsa_public_key_t; @@ -38,16 +38,6 @@ struct private_openssl_rsa_public_key_t { RSA *rsa; /** - * 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; @@ -163,41 +153,14 @@ static bool verify(private_openssl_rsa_public_key_t *this, signature_scheme_t sc /** * Implementation of public_key_t.get_keysize. */ -static bool encrypt_(private_openssl_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain) +static bool encrypt_(private_openssl_rsa_public_key_t *this, + chunk_t crypto, chunk_t *plain) { DBG1("RSA public key encryption not implemented"); return FALSE; } /** - * Implementation of public_key_t.equals. - */ -static bool equals(private_openssl_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; -} - -/** * Implementation of public_key_t.get_keysize. */ static size_t get_keysize(private_openssl_rsa_public_key_t *this) @@ -206,79 +169,55 @@ static size_t get_keysize(private_openssl_rsa_public_key_t *this) } /** - * Implementation of public_key_t.get_id. + * Implementation of public_key_t.get_fingerprint. */ -static identification_t *get_id(private_openssl_rsa_public_key_t *this, - id_type_t type) +static bool get_fingerprint(private_openssl_rsa_public_key_t *this, + key_encoding_type_t type, chunk_t *fingerprint) { - switch (type) - { - case ID_PUBKEY_INFO_SHA1: - return this->keyid_info; - case ID_PUBKEY_SHA1: - return this->keyid; - default: - return NULL; - } -} - -/** - * Encodes the public key - */ -static chunk_t get_encoding_raw(RSA *rsa) -{ - chunk_t enc = chunk_alloc(i2d_RSAPublicKey(rsa, NULL)); - u_char *p = enc.ptr; - i2d_RSAPublicKey(rsa, &p); - return enc; -} - -/** - * Encodes the public key with the algorithm used - */ -static chunk_t get_encoding_with_algo(RSA *rsa) -{ - u_char *p; chunk_t enc; - X509_PUBKEY *pubkey = X509_PUBKEY_new(); - - ASN1_OBJECT_free(pubkey->algor->algorithm); - pubkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption); + bool success; + u_char *p; - if (pubkey->algor->parameter == NULL || - pubkey->algor->parameter->type != V_ASN1_NULL) + if (lib->encoding->get_cache(lib->encoding, type, this, fingerprint)) { - ASN1_TYPE_free(pubkey->algor->parameter); - pubkey->algor->parameter = ASN1_TYPE_new(); - pubkey->algor->parameter->type = V_ASN1_NULL; + return TRUE; } - - enc = get_encoding_raw(rsa); - M_ASN1_BIT_STRING_set(pubkey->public_key, enc.ptr, enc.len); - chunk_free(&enc); - - enc = chunk_alloc(i2d_X509_PUBKEY(pubkey, NULL)); + enc = chunk_alloc(i2d_RSAPublicKey(this->rsa, NULL)); p = enc.ptr; - i2d_X509_PUBKEY(pubkey, &p); - X509_PUBKEY_free(pubkey); - return enc; + i2d_RSAPublicKey(this->rsa, &p); + success = lib->encoding->encode(lib->encoding, type, this, fingerprint, + KEY_PART_RSA_PUB_ASN1_DER, enc, KEY_PART_END); + free(enc.ptr); + + return success; } /* * Implementation of public_key_t.get_encoding. */ -static chunk_t get_encoding(private_openssl_rsa_public_key_t *this) +static bool get_encoding(private_openssl_rsa_public_key_t *this, + key_encoding_type_t type, chunk_t *encoding) { - return get_encoding_raw(this->rsa); + chunk_t enc; + bool success; + u_char *p; + + enc = chunk_alloc(i2d_RSAPublicKey(this->rsa, NULL)); + p = enc.ptr; + i2d_RSAPublicKey(this->rsa, &p); + success = lib->encoding->encode(lib->encoding, type, NULL, encoding, + KEY_PART_RSA_PUB_ASN1_DER, enc, KEY_PART_END); + free(enc.ptr); + return success; } /** * Implementation of public_key_t.get_ref. */ -static private_openssl_rsa_public_key_t* get_ref(private_openssl_rsa_public_key_t *this) +static public_key_t* get_ref(private_openssl_rsa_public_key_t *this) { ref_get(&this->ref); - return this; + return &this->public.interface; } /** @@ -292,8 +231,7 @@ static void destroy(private_openssl_rsa_public_key_t *this) { RSA_free(this->rsa); } - DESTROY_IF(this->keyid); - DESTROY_IF(this->keyid_info); + lib->encoding->clear_cache(lib->encoding, this); free(this); } } @@ -301,109 +239,46 @@ static void destroy(private_openssl_rsa_public_key_t *this) /** * Generic private constructor */ -static private_openssl_rsa_public_key_t *openssl_rsa_public_key_create_empty() +static private_openssl_rsa_public_key_t *create_empty() { private_openssl_rsa_public_key_t *this = malloc_thing(private_openssl_rsa_public_key_t); this->public.interface.get_type = (key_type_t (*)(public_key_t *this))get_type; this->public.interface.verify = (bool (*)(public_key_t *this, signature_scheme_t scheme, chunk_t data, chunk_t signature))verify; this->public.interface.encrypt = (bool (*)(public_key_t *this, chunk_t crypto, chunk_t *plain))encrypt_; - this->public.interface.equals = (bool (*) (public_key_t*, public_key_t*))equals; + this->public.interface.equals = public_key_equals; this->public.interface.get_keysize = (size_t (*) (public_key_t *this))get_keysize; - this->public.interface.get_id = (identification_t* (*) (public_key_t *this,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->rsa = NULL; this->ref = 1; return this; } /** - * Build the RSA key identifier from n and e using SHA1 hashed publicKey(Info). - * Also used in openssl_rsa_private_key.c. - */ -bool openssl_rsa_public_key_build_id(RSA *rsa, 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 = get_encoding_raw(rsa); - - hasher->allocate_hash(hasher, publicKey, &hash); - *keyid = identification_create_from_encoding(ID_PUBKEY_SHA1, hash); - chunk_free(&hash); - - publicKeyInfo = get_encoding_with_algo(rsa); - - 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); - chunk_free(&publicKey); - - return TRUE; -} - -/** - * Create a public key from BIGNUM values, used in openssl_rsa_private_key.c - */ -openssl_rsa_public_key_t *openssl_rsa_public_key_create_from_n_e(BIGNUM *n, BIGNUM *e) -{ - private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty(); - - this->rsa = RSA_new(); - this->rsa->n = BN_dup(n); - this->rsa->e = BN_dup(e); - - if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } - return &this->public; -} - -/** * Load a public key from an ASN1 encoded blob */ static openssl_rsa_public_key_t *load(chunk_t blob) { u_char *p = blob.ptr; - private_openssl_rsa_public_key_t *this = openssl_rsa_public_key_create_empty(); - - this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&p, blob.len); + private_openssl_rsa_public_key_t *this = create_empty(); - chunk_clear(&blob); - + this->rsa = d2i_RSAPublicKey(NULL, (const u_char**)&p, blob.len); if (!this->rsa) { destroy(this); return NULL; } - - if (!openssl_rsa_public_key_build_id(this->rsa, &this->keyid, &this->keyid_info)) - { - destroy(this); - return NULL; - } + return &this->public; } typedef struct private_builder_t private_builder_t; + /** * Builder implementation for key loading */ @@ -433,15 +308,13 @@ static void add(private_builder_t *this, builder_part_t part, ...) if (!this->key) { va_list args; - chunk_t chunk; - + switch (part) { case BUILD_BLOB_ASN1_DER: { va_start(args, part); - chunk = va_arg(args, chunk_t); - this->key = load(chunk_clone(chunk)); + this->key = load(va_arg(args, chunk_t)); va_end(args); return; } |