From: Sansar Choinyambuu Date: Mon, 31 Oct 2011 15:08:31 +0000 (+0100) Subject: use openssl rsa_verify function X-Git-Tag: 4.6.2~217 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5fbbfe0a489aee2ea2735f260174d11521a8153e;p=thirdparty%2Fstrongswan.git use openssl rsa_verify function --- diff --git a/src/libpts/pts/pts.c b/src/libpts/pts/pts.c index 3d5e23301a..9c1703de1c 100644 --- a/src/libpts/pts/pts.c +++ b/src/libpts/pts/pts.c @@ -1201,9 +1201,6 @@ METHOD(pts_t, verify_quote_signature, bool, { public_key_t *aik_pub_key; chunk_t key_encoding; - EVP_PKEY *pkey = NULL; - RSA *rsa = NULL; - unsigned char *p; aik_pub_key = this->aik->get_public_key(this->aik); if (!aik_pub_key) @@ -1228,52 +1225,8 @@ METHOD(pts_t, verify_quote_signature, bool, goto cleanup; } - p = key_encoding.ptr; - pkey = d2i_PUBKEY(NULL, (const unsigned char**)&p, key_encoding.len); - if (!pkey) - { - DBG1(DBG_PTS, "failed to get EVP_PKEY object from AIK public key"); - goto cleanup; - } - - rsa = EVP_PKEY_get1_RSA(pkey); - if (!rsa) - { - DBG1(DBG_PTS, "failed to get RSA object from EVP_PKEY"); - goto cleanup; - } - - if (RSA_verify(NID_sha1, data.ptr, data.len, - signature.ptr, signature.len, rsa) != 1) - { - DBG1(DBG_PTS, "signature verification failed for TPM Quote Info"); - goto cleanup; - } - - RSA_free(rsa); - EVP_PKEY_free(pkey); - if (key_encoding.ptr) - { - chunk_clear(&key_encoding); - } aik_pub_key->destroy(aik_pub_key); return TRUE; - -cleanup: - if (rsa) - { - RSA_free(rsa); - } - if (pkey) - { - EVP_PKEY_free(pkey); - } - if (key_encoding.ptr) - { - chunk_clear(&key_encoding); - } - DESTROY_IF(aik_pub_key); - return FALSE; } METHOD(pts_t, destroy, void, diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c index 37bba77d19..9c59ba7987 100644 --- a/src/libstrongswan/credentials/keys/public_key.c +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -26,6 +26,7 @@ ENUM(key_type_names, KEY_ANY, KEY_DSA, ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521, "UNKNOWN", + "RSA_SHA1" "RSA_EMSA_PKCS1_NULL", "RSA_EMSA_PKCS1_MD5", "RSA_EMSA_PKCS1_SHA1", diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h index fdbe17f2c1..303d0b592b 100644 --- a/src/libstrongswan/credentials/keys/public_key.h +++ b/src/libstrongswan/credentials/keys/public_key.h @@ -60,6 +60,8 @@ extern enum_name_t *key_type_names; enum signature_scheme_t { /** Unknown signature scheme */ SIGN_UNKNOWN, + /** Generic PKCS1_v1.5 signature as in PKCS#1 using RSA and SHA-1 */ + SIGN_RSA_SHA1, /** EMSA-PKCS1_v1.5 signature over digest without digestInfo */ SIGN_RSA_EMSA_PKCS1_NULL, /** EMSA-PKCS1_v1.5 signature as in PKCS#1 using RSA and MD5 */ diff --git a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c index a24bae5d6d..2c9ad2a55f 100644 --- a/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c +++ b/src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c @@ -116,6 +116,64 @@ error: return valid; } +/** + * Verification of an EMPSA PKCS1 signature described in PKCS#1 + */ +static bool verify_rsa_signature(private_openssl_rsa_public_key_t *this, + int type, chunk_t data, chunk_t signature) +{ + bool valid = FALSE; + int rsa_size = RSA_size(this->rsa); + + /* OpenSSL expects a signature of exactly RSA size (no leading 0x00) */ + if (signature.len > rsa_size) + { + signature = chunk_skip(signature, signature.len - rsa_size); + } + + if (type == NID_undef) + { + chunk_t hash = chunk_alloc(rsa_size); + + hash.len = RSA_public_decrypt(signature.len, signature.ptr, hash.ptr, + this->rsa, RSA_PKCS1_PADDING); + valid = chunk_equals(data, hash); + free(hash.ptr); + } + else + { + EVP_PKEY *key; + RSA *rsa = NULL; + + key = EVP_PKEY_new(); + if (!EVP_PKEY_set1_RSA(key, this->rsa)) + { + goto error; + } + rsa = EVP_PKEY_get1_RSA(key); + if (!rsa) + { + goto error; + } + + valid = (RSA_verify(type, data.ptr, data.len, + signature.ptr, signature.len, rsa) == 1); + +error: + if (key) + { + EVP_PKEY_free(key); + } + if (rsa) + { + RSA_free(rsa); + } + } + + return valid; +} + + METHOD(public_key_t, get_type, key_type_t, private_openssl_rsa_public_key_t *this) { @@ -128,6 +186,8 @@ METHOD(public_key_t, verify, bool, { switch (scheme) { + case SIGN_RSA_SHA1: + return verify_rsa_signature(this, NID_sha1, data, signature); case SIGN_RSA_EMSA_PKCS1_NULL: return verify_emsa_pkcs1_signature(this, NID_undef, data, signature); case SIGN_RSA_EMSA_PKCS1_SHA1: