]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Added support for different encryption schemes to private/public keys
authorMartin Willi <martin@revosec.ch>
Tue, 10 Aug 2010 12:38:44 +0000 (14:38 +0200)
committerMartin Willi <martin@revosec.ch>
Tue, 10 Aug 2010 16:46:30 +0000 (18:46 +0200)
19 files changed:
src/libcharon/plugins/unit_tester/tests/test_rsa_gen.c
src/libstrongswan/credentials/keys/private_key.h
src/libstrongswan/credentials/keys/public_key.c
src/libstrongswan/credentials/keys/public_key.h
src/libstrongswan/plugins/agent/agent_private_key.c
src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
src/libstrongswan/plugins/gmp/gmp_rsa_private_key.c
src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c
src/libstrongswan/plugins/openssl/openssl_ec_private_key.c
src/libstrongswan/plugins/openssl/openssl_ec_public_key.c
src/libstrongswan/plugins/openssl/openssl_rsa_private_key.c
src/libstrongswan/plugins/openssl/openssl_rsa_public_key.c
src/libstrongswan/plugins/pgp/pgp_builder.c
src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c
src/libtls/tls_peer.c
src/libtls/tls_server.c
src/pluto/pkcs7.c

index 59da15644c954d999845f39cbd8ec7b8c2e9adb4..43688f60a3d6e7a0e8ee51ea016182bd68fa3fef 100644 (file)
@@ -59,12 +59,12 @@ bool test_rsa_gen()
                        return FALSE;
                }
                free(sig.ptr);
-               if (!public->encrypt(public, data, &crypt))
+               if (!public->encrypt(public, ENCRYPT_RSA_PKCS1, data, &crypt))
                {
                        DBG1(DBG_CFG, "encrypting data with RSA failed");
                        return FALSE;
                }
-               if (!private->decrypt(private, crypt, &plain))
+               if (!private->decrypt(private, ENCRYPT_RSA_PKCS1, crypt, &plain))
                {
                        DBG1(DBG_CFG, "decrypting data with RSA failed");
                        return FALSE;
index 27f4ab098319a576b80cde0afebeab39268c4d96..cec920b02e4ed60532d9ff400f27e5c1e589bc7b 100644 (file)
@@ -51,11 +51,13 @@ struct private_key_t {
        /**
         * Decrypt a chunk of data.
         *
+        * @param scheme        expected encryption scheme used
         * @param crypto        chunk containing encrypted data
         * @param plain         where to allocate decrypted data
         * @return                      TRUE if data decrypted and plaintext allocated
         */
-       bool (*decrypt)(private_key_t *this, chunk_t crypto, chunk_t *plain);
+       bool (*decrypt)(private_key_t *this, encryption_scheme_t scheme,
+                                       chunk_t crypto, chunk_t *plain);
 
        /**
         * Get the strength of the key in bytes.
index ce342de33f081721217a766fb9cb87c0b8569f51..22df5dd1b7f0089e25476079485987dd8d383bde 100644 (file)
@@ -42,6 +42,16 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521,
        "ECDSA-521",
 );
 
+ENUM(encryption_scheme_names, ENCRYPT_UNKNOWN, ENCRYPT_RSA_OAEP_SHA512,
+       "ENCRYPT_UNKNOWN",
+       "ENCRYPT_RSA_PKCS1",
+       "ENCRYPT_RSA_OAEP_SHA1",
+       "ENCRYPT_RSA_OAEP_SHA224",
+       "ENCRYPT_RSA_OAEP_SHA256",
+       "ENCRYPT_RSA_OAEP_SHA384",
+       "ENCRYPT_RSA_OAEP_SHA512",
+);
+
 /**
  * See header.
  */
index ff827a189f4e29fd7d6ed776275d189735dace48..3b45b6c3e80d7c9ea51af0ad83cc7ff26a5fcd3a 100644 (file)
@@ -24,6 +24,7 @@
 typedef struct public_key_t public_key_t;
 typedef enum key_type_t key_type_t;
 typedef enum signature_scheme_t signature_scheme_t;
+typedef enum encryption_scheme_t encryption_scheme_t;
 
 #include <library.h>
 #include <utils/identification.h>
@@ -96,6 +97,31 @@ enum signature_scheme_t {
  */
 extern enum_name_t *signature_scheme_names;
 
+/**
+ * Encryption scheme for public key data encryption.
+ */
+enum encryption_scheme_t {
+       /** Unknown encryption scheme                                      */
+       ENCRYPT_UNKNOWN,
+       /** RSAES-PKCS1-v1_5 as in PKCS#1                                  */
+       ENCRYPT_RSA_PKCS1,
+       /** RSAES-OAEP as in PKCS#1, using SHA1 as hash, no label          */
+       ENCRYPT_RSA_OAEP_SHA1,
+       /** RSAES-OAEP as in PKCS#1, using SHA-224 as hash, no label       */
+       ENCRYPT_RSA_OAEP_SHA224,
+       /** RSAES-OAEP as in PKCS#1, using SHA-256 as hash, no label       */
+       ENCRYPT_RSA_OAEP_SHA256,
+       /** RSAES-OAEP as in PKCS#1, using SHA-384 as hash, no label       */
+       ENCRYPT_RSA_OAEP_SHA384,
+       /** RSAES-OAEP as in PKCS#1, using SHA-512 as hash, no label       */
+       ENCRYPT_RSA_OAEP_SHA512,
+};
+
+/**
+ * Enum names for encryption_scheme_t
+ */
+extern enum_name_t *encryption_scheme_names;
+
 /**
  * Abstract interface of a public key.
  */
@@ -122,11 +148,13 @@ struct public_key_t {
        /**
         * Encrypt a chunk of data.
         *
+        * @param scheme        encryption scheme to use
         * @param plain         chunk containing plaintext data
         * @param crypto        where to allocate encrypted data
         * @return                      TRUE if data successfully encrypted
         */
-       bool (*encrypt)(public_key_t *this, chunk_t plain, chunk_t *crypto);
+       bool (*encrypt)(public_key_t *this, encryption_scheme_t scheme,
+                                       chunk_t plain, chunk_t *crypto);
 
        /**
         * Check if two public keys are equal.
index deef4d80996914aa7c213a6ac5036ebe577a4edc..7fc840f8ba633df9a5cb83e24e0f98c8e41b5c7e 100644 (file)
@@ -299,7 +299,8 @@ METHOD(private_key_t, get_type, key_type_t,
 }
 
 METHOD(private_key_t, decrypt, bool,
-       private_agent_private_key_t *this, chunk_t crypto, chunk_t *plain)
+       private_agent_private_key_t *this, encryption_scheme_t scheme,
+       chunk_t crypto, chunk_t *plain)
 {
        DBG1(DBG_LIB, "private key decryption not supported by ssh-agent");
        return FALSE;
index d94700cf4890c6b8679f8ffcd9e2c18fb3acbabc..63002d2fe868cee1766b3e4fca5476c0f90593ed 100644 (file)
@@ -226,13 +226,20 @@ METHOD(private_key_t, sign, bool,
 }
 
 METHOD(private_key_t, decrypt, bool,
-       private_gcrypt_rsa_private_key_t *this, chunk_t encrypted, chunk_t *plain)
+       private_gcrypt_rsa_private_key_t *this, encryption_scheme_t scheme,
+       chunk_t encrypted, chunk_t *plain)
 {
        gcry_error_t err;
        gcry_sexp_t in, out;
        chunk_t padded;
        u_char *pos = NULL;;
 
+       if (scheme != ENCRYPT_RSA_PKCS1)
+       {
+               DBG1(DBG_LIB, "encryption scheme %N not supported",
+                        encryption_scheme_names, scheme);
+               return FALSE;
+       }
        err = gcry_sexp_build(&in, NULL, "(enc-val(flags)(rsa(a %b)))",
                                                  encrypted.len, encrypted.ptr);
        if (err)
index 4e557c743d418aaedb95c440f8beb709be0d87bc..7eae5949d105df9d12fd3e8527e81bb12f9f1655 100644 (file)
@@ -193,11 +193,18 @@ METHOD(public_key_t, verify, bool,
 }
 
 METHOD(public_key_t, encrypt_, bool,
-       private_gcrypt_rsa_public_key_t *this, chunk_t plain, chunk_t *encrypted)
+       private_gcrypt_rsa_public_key_t *this, encryption_scheme_t scheme,
+       chunk_t plain, chunk_t *encrypted)
 {
        gcry_sexp_t in, out;
        gcry_error_t err;
 
+       if (scheme != ENCRYPT_RSA_PKCS1)
+       {
+               DBG1(DBG_LIB, "encryption scheme %N not supported",
+                        encryption_scheme_names, scheme);
+               return FALSE;
+       }
        /* "pkcs1" uses PKCS 1.5 (section 8.1) block type 2 encryption:
         * 00 | 02 | RANDOM | 00 | DATA */
        err = gcry_sexp_build(&in, NULL, "(data(flags pkcs1)(value %b))",
index a07ace2960fc156226cc11d6335e22d478f65008..e21e7131debfcd75753fdc604be29c0fa4f29912 100644 (file)
@@ -314,11 +314,18 @@ METHOD(private_key_t, sign, bool,
 }
 
 METHOD(private_key_t, decrypt, bool,
-       private_gmp_rsa_private_key_t *this, chunk_t crypto, chunk_t *plain)
+       private_gmp_rsa_private_key_t *this, encryption_scheme_t scheme,
+       chunk_t crypto, chunk_t *plain)
 {
        chunk_t em, stripped;
        bool success = FALSE;
 
+       if (scheme != ENCRYPT_RSA_PKCS1)
+       {
+               DBG1(DBG_LIB, "encryption scheme %N not supported",
+                        encryption_scheme_names, scheme);
+               return FALSE;
+       }
        /* rsa decryption using PKCS#1 RSADP */
        stripped = em = rsadp(this, crypto);
 
index 369021a736b79e01cda1a19c68c8e7a9c240a7d7..762238f49c66f4377d130bdb6c1af5b9b7c93678 100644 (file)
@@ -309,20 +309,20 @@ METHOD(public_key_t, verify, bool,
 #define MIN_PS_PADDING 8
 
 METHOD(public_key_t, encrypt_, bool,
-       private_gmp_rsa_public_key_t *this, chunk_t plain, chunk_t *crypto)
+       private_gmp_rsa_public_key_t *this, encryption_scheme_t scheme,
+       chunk_t plain, chunk_t *crypto)
 {
        chunk_t em;
        u_char *pos;
        int padding, i;
        rng_t *rng;
 
-       rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
-       if (rng == NULL)
+       if (scheme != ENCRYPT_RSA_PKCS1)
        {
-               DBG1(DBG_LIB, "no random generator available");
+               DBG1(DBG_LIB, "encryption scheme %N not supported",
+                        encryption_scheme_names, scheme);
                return FALSE;
        }
-
        /* number of pseudo-random padding octets */
        padding = this->k - plain.len - 3;
        if (padding < MIN_PS_PADDING)
@@ -331,6 +331,12 @@ METHOD(public_key_t, encrypt_, bool,
                         MIN_PS_PADDING);
                return FALSE;
        }
+       rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
+       if (rng == NULL)
+       {
+               DBG1(DBG_LIB, "no random generator available");
+               return FALSE;
+       }
 
        /* padding according to PKCS#1 7.2.1 (RSAES-PKCS1-v1.5-ENCRYPT) */
        DBG2(DBG_LIB, "padding %u bytes of data to the rsa modulus size of"
index 1b5a24f22df4e5ab33d31999310894644368776a..ffd9ac62ea5ce1f464b40835035be639acc3395d 100644 (file)
@@ -171,7 +171,8 @@ METHOD(private_key_t, sign, bool,
 }
 
 METHOD(private_key_t, decrypt, bool,
-       private_openssl_ec_private_key_t *this, chunk_t crypto, chunk_t *plain)
+       private_openssl_ec_private_key_t *this, encryption_scheme_t scheme,
+       chunk_t crypto, chunk_t *plain)
 {
        DBG1(DBG_LIB, "EC private key decryption not implemented");
        return FALSE;
index 814e774d13f3a5bb15d06a0fa089eab8df9ed359..16257178d54f85bcdc48d64de2ada49f4492f7fa 100644 (file)
@@ -169,7 +169,8 @@ METHOD(public_key_t, verify, bool,
 }
 
 METHOD(public_key_t, encrypt, bool,
-       private_openssl_ec_public_key_t *this, chunk_t crypto, chunk_t *plain)
+       private_openssl_ec_public_key_t *this, encryption_scheme_t scheme,
+       chunk_t crypto, chunk_t *plain)
 {
        DBG1(DBG_LIB, "EC public key encryption not implemented");
        return FALSE;
index 14bb25cbcdd61a1a868c29bc3835ac2b8ee3b12c..291acb0c3047d0cc6799b039a003a7cb5549eeb8 100644 (file)
@@ -166,7 +166,8 @@ METHOD(private_key_t, sign, bool,
 }
 
 METHOD(private_key_t, decrypt, bool,
-       private_openssl_rsa_private_key_t *this, chunk_t crypto, chunk_t *plain)
+       private_openssl_rsa_private_key_t *this, encryption_scheme_t scheme,
+       chunk_t crypto, chunk_t *plain)
 {
        DBG1(DBG_LIB, "RSA private key decryption not implemented");
        return FALSE;
index 54701da1cd8f4b3c8025bfe3de8f13270be86565..e3ce66db51725460676029155fd5cef241886d8c 100644 (file)
@@ -148,7 +148,8 @@ METHOD(public_key_t, verify, bool,
 }
 
 METHOD(public_key_t, encrypt, bool,
-       private_openssl_rsa_public_key_t *this, chunk_t crypto, chunk_t *plain)
+       private_openssl_rsa_public_key_t *this, encryption_scheme_t scheme,
+       chunk_t crypto, chunk_t *plain)
 {
        DBG1(DBG_LIB, "RSA public key encryption not implemented");
        return FALSE;
index 84c9bfdddc1bb439c184dfd3dae01c61efc97f5d..440e70a1844e6900c8d6f33890e0ce2dd3e194e7 100644 (file)
@@ -129,7 +129,7 @@ static bool sign_not_allowed(private_key_t *this, signature_scheme_t scheme,
 /**
  * Implementation of private_key_t.decrypt for signature-only keys
  */
-static bool decrypt_not_allowed(private_key_t *this,
+static bool decrypt_not_allowed(private_key_t *this, encryption_scheme_t scheme,
                                                                chunk_t crypto, chunk_t *plain)
 {
        DBG1(DBG_LIB, "decryption failed - signature only key");
index 80c0f00d4f2c4b38f2ef479e9f8d67e931d5a2ff..87ef89e003d7c2de3269055f7dfcafeec3f70d41 100644 (file)
@@ -193,7 +193,8 @@ METHOD(private_key_t, sign, bool,
 }
 
 METHOD(private_key_t, decrypt, bool,
-       private_pkcs11_private_key_t *this, chunk_t crypto, chunk_t *plain)
+       private_pkcs11_private_key_t *this, encryption_scheme_t scheme,
+       chunk_t crypto, chunk_t *plain)
 {
        return FALSE;
 }
index e2677a542c2403a6cc1b64f3b4255384e6946e63..468c2bb27602a83b711bcde236d8f6c7f1214ab2 100644 (file)
@@ -119,7 +119,8 @@ METHOD(public_key_t, verify, bool,
 }
 
 METHOD(public_key_t, encrypt, bool,
-       private_pkcs11_public_key_t *this, chunk_t plain, chunk_t *crypto)
+       private_pkcs11_public_key_t *this, encryption_scheme_t scheme,
+       chunk_t plain, chunk_t *crypto)
 {
        return FALSE;
 }
index cc2c529a93dc8d76ed1f9446048b729ae48f6379..221b629a5bc236ab9a722bb86109ff7298538a8b 100644 (file)
@@ -505,7 +505,8 @@ static status_t send_key_exchange(private_tls_peer_t *this,
                DBG1(DBG_IKE, "no TLS public key found for server '%Y'", this->server);
                return FAILED;
        }
-       if (!public->encrypt(public, chunk_from_thing(premaster), &encrypted))
+       if (!public->encrypt(public, ENCRYPT_RSA_PKCS1,
+                                                chunk_from_thing(premaster), &encrypted))
        {
                public->destroy(public);
                DBG1(DBG_IKE, "encrypting TLS premaster secret failed");
index 712010edcd7957ddf1d99314f08029657e520844..8d2c961ea9e5ca41cbf80c90e43849f42d43b57c 100644 (file)
@@ -228,7 +228,8 @@ static status_t process_key_exchange(private_tls_server_t *this,
        }
 
        if (!this->private ||
-               !this->private->decrypt(this->private, encrypted, &premaster))
+               !this->private->decrypt(this->private, ENCRYPT_RSA_PKCS1,
+                                                               encrypted, &premaster))
        {
                DBG1(DBG_IKE, "decrypting Client Key Exchange data failed");
                return FAILED;
index c0fd041a71ce72901dde615cfb2f201ee8e0376a..938917811dbb3c2d7ae85ffd7ffa923ea7dffcff 100644 (file)
@@ -407,7 +407,7 @@ bool pkcs7_parse_envelopedData(chunk_t blob, chunk_t *data,
                        }
                        break;
                case PKCS7_ENCRYPTED_KEY:
-                       if (!key->decrypt(key, object, &symmetric_key))
+                       if (!key->decrypt(key, ENCRYPT_RSA_PKCS1, object, &symmetric_key))
                        {
                                DBG1(DBG_LIB, "symmetric key could not be decrypted with rsa");
                                goto end;
@@ -710,7 +710,7 @@ chunk_t pkcs7_build_envelopedData(chunk_t data, certificate_t *cert, int enc_alg
                        chunk_free(&out);
                        return chunk_empty;
                }
-               key->encrypt(key, symmetricKey, &protectedKey);
+               key->encrypt(key, ENCRYPT_RSA_PKCS1, symmetricKey, &protectedKey);
                key->destroy(key);
        }