aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2009-06-15 18:07:57 +0200
committerMartin Willi <martin@strongswan.org>2009-06-15 18:07:57 +0200
commitd32b14db5eb0a75b281af75ae9622153de16ff6d (patch)
tree465217f36f60614598599e873788a72dc2c2568e
parent810ce1f336fffd3ca14344060cfd1ba800ca8940 (diff)
downloadstrongswan-d32b14db5eb0a75b281af75ae9622153de16ff6d.tar.bz2
strongswan-d32b14db5eb0a75b281af75ae9622153de16ff6d.tar.xz
implemented gcrypt RSA encrypt/decrypt operations
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c43
-rw-r--r--src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c30
2 files changed, 65 insertions, 8 deletions
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
index b9b7d8bf7..14a14704c 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_private_key.c
@@ -214,10 +214,47 @@ static bool sign(private_gcrypt_rsa_private_key_t *this, signature_scheme_t sche
* Implementation of gcrypt_rsa_private_key.destroy.
*/
static bool decrypt(private_gcrypt_rsa_private_key_t *this,
- chunk_t crypto, chunk_t *plain)
+ chunk_t encrypted, chunk_t *plain)
{
- DBG1("RSA private key decryption not implemented");
- return FALSE;
+ gcry_error_t err;
+ gcry_sexp_t in, out;
+ chunk_t padded;
+ u_char *pos = NULL;;
+
+ err = gcry_sexp_build(&in, NULL, "(enc-val(flags)(rsa(a %b)))",
+ encrypted.len, encrypted.ptr);
+ if (err)
+ {
+ DBG1("building decryption S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ err = gcry_pk_decrypt(&out, in, this->key);
+ gcry_sexp_release(in);
+ if (err)
+ {
+ DBG1("decrypting pkcs1 data failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ padded.ptr = (u_char*)gcry_sexp_nth_data(out, 1, &padded.len);
+ /* result is padded, but gcrypt strips leading zero:
+ * 00 | 02 | RANDOM | 00 | DATA */
+ if (padded.ptr && padded.len > 2 && padded.ptr[0] == 0x02)
+ {
+ pos = memchr(padded.ptr, 0x00, padded.len - 1);
+ if (pos)
+ {
+ pos++;
+ *plain = chunk_clone(chunk_create(
+ pos, padded.len - (pos - padded.ptr)));
+ }
+ }
+ gcry_sexp_release(out);
+ if (!pos)
+ {
+ DBG1("decrypted data has invalid pkcs1 padding");
+ return FALSE;
+ }
+ return TRUE;
}
/**
diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
index 42c478c28..909c43c74 100644
--- a/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
+++ b/src/libstrongswan/plugins/gcrypt/gcrypt_rsa_public_key.c
@@ -202,13 +202,33 @@ static bool verify(private_gcrypt_rsa_public_key_t *this,
}
/**
- * Implementation of public_key_t.get_keysize.
+ * Implementation of public_key_t.encrypt.
*/
-static bool encrypt_(private_gcrypt_rsa_public_key_t *this, chunk_t crypto,
- chunk_t *plain)
+static bool encrypt_(private_gcrypt_rsa_public_key_t *this, chunk_t plain,
+ chunk_t *encrypted)
{
- DBG1("RSA public key encryption not implemented");
- return FALSE;
+ gcry_sexp_t in, out;
+ gcry_error_t err;
+
+ /* "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))",
+ plain.len, plain.ptr);
+ if (err)
+ {
+ DBG1("building encryption S-expression failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ err = gcry_pk_encrypt(&out, in, this->key);
+ gcry_sexp_release(in);
+ if (err)
+ {
+ DBG1("encrypting data using pkcs1 failed: %s", gpg_strerror(err));
+ return FALSE;
+ }
+ *encrypted = gcrypt_rsa_find_token(out, "a");
+ gcry_sexp_release(out);
+ return !!encrypted->len;
}
/**