[gnome-keyring/dbus-api] [pkcs11] Refactor RSA and DSA mechanism support.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring/dbus-api] [pkcs11] Refactor RSA and DSA mechanism support.
- Date: Sat, 14 Nov 2009 14:26:30 +0000 (UTC)
commit 94abeee297914b50fa3f2f27f8ef4ad9e0b106c3
Author: Stef Walter <stef memberwebs com>
Date: Thu Nov 12 18:35:21 2009 +0000
[pkcs11] Refactor RSA and DSA mechanism support.
This is so we can support other non PK algorithms like
DH and AES (for the wrapping of secret items, eg).
pkcs11/gck/Makefile.am | 4 +-
pkcs11/gck/gck-certificate.c | 4 +-
pkcs11/gck/gck-crypto.c | 786 +++-----------------
pkcs11/gck/gck-crypto.h | 177 ++---
pkcs11/gck/gck-data-der.c | 50 +-
pkcs11/gck/gck-key.h | 71 --
pkcs11/gck/gck-mechanism-dsa.c | 144 ++++
pkcs11/gck/gck-mechanism-dsa.h | 49 ++
pkcs11/gck/gck-mechanism-rsa.c | 387 ++++++++++
pkcs11/gck/gck-mechanism-rsa.h | 92 +++
pkcs11/gck/gck-private-xsa-key.c | 20 +-
pkcs11/gck/gck-private-xsa-key.h | 6 +-
pkcs11/gck/gck-public-xsa-key.c | 32 +-
pkcs11/gck/gck-public-xsa-key.h | 6 +-
pkcs11/gck/gck-session.c | 60 +-
pkcs11/gck/gck-session.h | 6 +
pkcs11/gck/{gck-key.c => gck-sexp-key.c} | 191 ++---
pkcs11/gck/gck-sexp-key.h | 71 ++
pkcs11/gck/gck-sexp.c | 203 +++++
pkcs11/gck/gck-sexp.h | 20 +-
pkcs11/gck/gck-types.h | 2 +-
pkcs11/gck/tests/Makefile.am | 2 +-
pkcs11/gck/tests/unit-test-data-der.c | 3 +-
.../tests/{unit-test-crypto.c => unit-test-sexp.c} | 29 +-
pkcs11/ssh-store/gck-ssh-private-key.c | 4 +-
pkcs11/ssh-store/tests/p11-tests.conf | 6 +-
pkcs11/ssh-store/tests/unit-test-ssh-openssh.c | 10 +-
pkcs11/user-store/gck-user-private-key.c | 12 +-
pkcs11/user-store/gck-user-public-key.c | 4 +-
29 files changed, 1373 insertions(+), 1078 deletions(-)
---
diff --git a/pkcs11/gck/Makefile.am b/pkcs11/gck/Makefile.am
index 3427ada..0833682 100644
--- a/pkcs11/gck/Makefile.am
+++ b/pkcs11/gck/Makefile.am
@@ -29,8 +29,9 @@ libgck_la_SOURCES = \
gck-data-types.h \
gck-factory.c gck-factory.h \
gck-file-tracker.c gck-file-tracker.h \
- gck-key.c gck-key.h \
gck-manager.c gck-manager.h \
+ gck-mechanism-dsa.c gck-mechanism-dsa.h \
+ gck-mechanism-rsa.c gck-mechanism-rsa.h \
gck-memory-store.c gck-memory-store.h \
gck-module.c gck-module.h gck-module-ep.h \
gck-object.c gck-object.h \
@@ -40,6 +41,7 @@ libgck_la_SOURCES = \
gck-serializable.c gck-serializable.h \
gck-session.c gck-session.h \
gck-sexp.c gck-sexp.h \
+ gck-sexp-key.c gck-sexp-key.h \
gck-store.c gck-store.h \
gck-timer.c gck-timer.h \
gck-transaction.c gck-transaction.h \
diff --git a/pkcs11/gck/gck-certificate.c b/pkcs11/gck/gck-certificate.c
index 9292651..a635daf 100644
--- a/pkcs11/gck/gck-certificate.c
+++ b/pkcs11/gck/gck-certificate.c
@@ -28,7 +28,7 @@
#include "gck-data-asn1.h"
#include "gck-data-der.h"
#include "gck-factory.h"
-#include "gck-key.h"
+#include "gck-sexp-key.h"
#include "gck-manager.h"
#include "gck-session.h"
#include "gck-sexp.h"
@@ -562,7 +562,7 @@ gck_certificate_real_load (GckSerializable *base, GckSecret *login, const guchar
self->pv->key = gck_certificate_key_new (gck_object_get_module (GCK_OBJECT (self)),
gck_object_get_manager (GCK_OBJECT (self)),
self);
- gck_key_set_base_sexp (GCK_KEY (self->pv->key), wrapper);
+ gck_sexp_key_set_base (GCK_SEXP_KEY (self->pv->key), wrapper);
gck_sexp_unref (wrapper);
break;
diff --git a/pkcs11/gck/gck-crypto.c b/pkcs11/gck/gck-crypto.c
index 294b0f1..d2a1429 100644
--- a/pkcs11/gck/gck-crypto.c
+++ b/pkcs11/gck/gck-crypto.c
@@ -22,41 +22,22 @@
#include "config.h"
#include "gck-crypto.h"
+#include "gck-mechanism-dsa.h"
+#include "gck-mechanism-rsa.h"
+#include "gck-session.h"
+#include "gck-sexp.h"
+#include "gck-sexp-key.h"
#include "egg/egg-libgcrypt.h"
#include "egg/egg-secure-memory.h"
/* ----------------------------------------------------------------------------
- * INTERNAL
+ * PUBLIC
*/
-static gcry_sexp_t
-sexp_get_childv (gcry_sexp_t sexp, va_list va)
-{
- gcry_sexp_t at = NULL;
- gcry_sexp_t child;
- const char *name;
-
- for(;;) {
- name = va_arg (va, const char*);
- if (!name)
- break;
-
- child = gcry_sexp_find_token (at ? at : sexp, name, 0);
- gcry_sexp_release (at);
- at = child;
- if (at == NULL)
- break;
- }
-
- va_end (va);
-
- return at;
-}
-
-static CK_RV
-data_to_sexp (const gchar *format, guint nbits, GckCryptoPadding padding,
- CK_BYTE_PTR data, CK_ULONG n_data, gcry_sexp_t *sexp)
+CK_RV
+gck_crypto_data_to_sexp (const gchar *format, guint nbits, GckCryptoPadding padding,
+ CK_BYTE_PTR data, CK_ULONG n_data, gcry_sexp_t *sexp)
{
guchar *padded = NULL;
gcry_error_t gcry;
@@ -89,17 +70,11 @@ data_to_sexp (const gchar *format, guint nbits, GckCryptoPadding padding,
g_assert (*sexp);
return CKR_OK;
-}
-
-/* For the sake of checking arguments */
-static CK_RV
-sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
- CK_ULONG *n_data, GckCryptoPadding padding,
- ...) G_GNUC_NULL_TERMINATED;
+}
-static CK_RV
-sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
- CK_ULONG *n_data, GckCryptoPadding padding, ...)
+CK_RV
+gck_crypto_sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
+ CK_ULONG *n_data, GckCryptoPadding padding, ...)
{
gcry_sexp_t at = NULL;
gsize n_block, offset, len;
@@ -115,7 +90,7 @@ sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
/* First try and dig out sexp child based on arguments */
va_start (va, padding);
- at = sexp_get_childv (sexp, va);
+ at = gck_sexp_get_childv (sexp, va);
va_end (va);
/* It's expected we would find it */
@@ -159,81 +134,27 @@ sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
return CKR_OK;
}
-static void
-fill_random_nonzero (guchar *data, gsize n_data)
-{
- guchar *rnd;
- guint n_zero, i, j;
-
- gcry_randomize (data, n_data, GCRY_STRONG_RANDOM);
- /* Find any zeros in random data */
- n_zero = 0;
- for (i = 0; i < n_data; ++i) {
- if (data[i] == 0x00)
- ++n_zero;
- }
+CK_RV
+gck_crypto_encrypt (GckSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
+ CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
+{
+ GckSexp *sexp;
- while (n_zero > 0) {
- rnd = gcry_random_bytes (n_zero, GCRY_STRONG_RANDOM);
- n_zero = 0;
- for (i = 0, j = 0; i < n_data; ++i) {
- if (data[i] != 0x00)
- continue;
-
- /* Use some of the replacement data */
- data[i] = rnd[j];
- ++j;
-
- /* It's zero again :( */
- if (data[i] == 0x00)
- n_zero++;
- }
-
- gcry_free (rnd);
+ switch (mech) {
+ case CKM_RSA_PKCS:
+ case CKM_RSA_X_509:
+ sexp = gck_session_get_crypto_state (session);
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ return gck_crypto_encrypt_xsa (gck_sexp_get (sexp), mech, data, n_data, encrypted, n_encrypted);
+ default:
+ g_return_val_if_reached (CKR_GENERAL_ERROR);
}
}
-static guchar*
-unpad_rsa_pkcs1 (guchar bt, guint n_modulus, const guchar* padded,
- gsize n_padded, gsize *n_raw)
-{
- const guchar *at;
- guint check;
- guchar *raw;
-
- check = (n_modulus + 7) / 8;
-
- /* The absolute minimum size including padding */
- g_return_val_if_fail (check >= 3 + 8, NULL);
-
- if (n_padded != check)
- return NULL;
-
- /* Check the header */
- if (padded[0] != 0x00 || padded[1] != bt)
- return NULL;
-
- /* The first zero byte after the header */
- at = memchr (padded + 2, 0x00, n_padded - 2);
- if (!at)
- return NULL;
-
- ++at;
- *n_raw = n_padded - (at - padded);
- raw = g_new0 (guchar, *n_raw);
- memcpy (raw, at, *n_raw);
- return raw;
-}
-
-
-/* ----------------------------------------------------------------------------
- * PUBLIC
- */
-
CK_RV
-gck_crypto_encrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
+gck_crypto_encrypt_xsa (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
+ CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
{
int algorithm;
CK_RV rv;
@@ -242,7 +163,7 @@ gck_crypto_encrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
+ if (!gck_sexp_parse_key (sexp, &algorithm, NULL, NULL))
g_return_val_if_reached (CKR_GENERAL_ERROR);
/*
@@ -254,11 +175,11 @@ gck_crypto_encrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
switch (mech) {
case CKM_RSA_PKCS:
g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_encrypt_rsa (sexp, gck_crypto_rsa_pad_two, data, n_data, encrypted, n_encrypted);
+ rv = gck_mechanism_rsa_encrypt (sexp, gck_mechanism_rsa_pad_two, data, n_data, encrypted, n_encrypted);
break;
case CKM_RSA_X_509:
g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_encrypt_rsa (sexp, gck_crypto_rsa_pad_raw, data, n_data, encrypted, n_encrypted);
+ rv = gck_mechanism_rsa_encrypt (sexp, gck_mechanism_rsa_pad_raw, data, n_data, encrypted, n_encrypted);
break;
default:
/* Again shouldn't be reached */
@@ -269,53 +190,25 @@ gck_crypto_encrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
}
CK_RV
-gck_crypto_encrypt_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
+gck_crypto_decrypt (GckSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encrypted,
+ CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
{
- gcry_sexp_t splain, sdata;
- gcry_error_t gcry;
- guint nbits;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- nbits = gcry_pk_get_nbits (sexp);
- g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
- /* Just want to know the length */
- if (!encrypted) {
- *n_encrypted = (nbits + 7) / 8;
- return CKR_OK;
- }
+ GckSexp *sexp;
- /* Prepare the input s expression */
- rv = data_to_sexp ("(data (flags raw) (value %m))",
- nbits, padding, data, n_data, &splain);
- if (rv != CKR_OK)
- return rv;
-
- /* Do the magic */
- gcry = gcry_pk_encrypt (&sdata, splain, sexp);
- gcry_sexp_release (splain);
-
- /* TODO: Certain codes should be returned (data too big etc... ) */
- if (gcry) {
- g_message ("encrypting of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
+ switch (mech) {
+ case CKM_RSA_PKCS:
+ case CKM_RSA_X_509:
+ sexp = gck_session_get_crypto_state (session);
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ return gck_crypto_decrypt_xsa (gck_sexp_get (sexp), mech, encrypted, n_encrypted, data, n_data);
+ default:
+ g_return_val_if_reached (CKR_GENERAL_ERROR);
}
-
- /* Now extract and send it back out */
- rv = sexp_to_data (sdata, nbits, encrypted, n_encrypted, NULL, "enc-val", "rsa", "a", NULL);
- gcry_sexp_release (sdata);
-
- return rv;
}
CK_RV
-gck_crypto_decrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encrypted,
- CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
+gck_crypto_decrypt_xsa (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encrypted,
+ CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
{
int algorithm;
CK_RV rv;
@@ -324,7 +217,7 @@ gck_crypto_decrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encryp
g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
+ if (!gck_sexp_parse_key (sexp, &algorithm, NULL, NULL))
g_return_val_if_reached (CKR_GENERAL_ERROR);
/*
@@ -336,11 +229,11 @@ gck_crypto_decrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encryp
switch (mech) {
case CKM_RSA_PKCS:
g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_decrypt_rsa (sexp, gck_crypto_rsa_unpad_two, encrypted, n_encrypted, data, n_data);
+ rv = gck_mechanism_rsa_decrypt (sexp, gck_mechanism_rsa_unpad_two, encrypted, n_encrypted, data, n_data);
break;
case CKM_RSA_X_509:
g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_decrypt_rsa (sexp, NULL, encrypted, n_encrypted, data, n_data);
+ rv = gck_mechanism_rsa_decrypt (sexp, NULL, encrypted, n_encrypted, data, n_data);
break;
default:
/* Again shouldn't be reached */
@@ -351,56 +244,26 @@ gck_crypto_decrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encryp
}
CK_RV
-gck_crypto_decrypt_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR encrypted,
- CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
+gck_crypto_sign (GckSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
+ CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
{
- gcry_sexp_t splain, sdata;
- gcry_error_t gcry;
- guint nbits;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);
+ GckSexp *sexp;
- nbits = gcry_pk_get_nbits (sexp);
- g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
- /* Just want to know the length */
- if (!data) {
- *n_data = (nbits + 7) / 8;
- return CKR_OK;
- }
-
- if (n_encrypted != (nbits + 7) / 8)
- return CKR_DATA_LEN_RANGE;
-
- /* Prepare the input s expression */
- rv = data_to_sexp ("(enc-val (flags) (rsa (a %m)))",
- nbits, NULL, encrypted, n_encrypted, &sdata);
- if (rv != CKR_OK)
- return rv;
-
- /* Do the magic */
- gcry = gcry_pk_decrypt (&splain, sdata, sexp);
- gcry_sexp_release (sdata);
-
- /* TODO: Certain codes should be returned (data too big etc... ) */
- if (gcry) {
- g_message ("decrypting of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
+ switch (mech) {
+ case CKM_RSA_PKCS:
+ case CKM_RSA_X_509:
+ case CKM_DSA:
+ sexp = gck_session_get_crypto_state (session);
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ return gck_crypto_sign_xsa (gck_sexp_get (sexp), mech, data, n_data, signature, n_signature);
+ default:
+ g_return_val_if_reached (CKR_GENERAL_ERROR);
}
-
- /* Now extract and send it back out */
- rv = sexp_to_data (splain, nbits, data, n_data, padding, "value", NULL);
- gcry_sexp_release (splain);
-
- return rv;
}
CK_RV
-gck_crypto_sign (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
+gck_crypto_sign_xsa (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
+ CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
{
int algorithm;
CK_RV rv;
@@ -409,7 +272,7 @@ gck_crypto_sign (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
+ if (!gck_sexp_parse_key (sexp, &algorithm, NULL, NULL))
g_return_val_if_reached (CKR_GENERAL_ERROR);
/*
@@ -421,15 +284,15 @@ gck_crypto_sign (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
switch (mech) {
case CKM_RSA_PKCS:
g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_sign_rsa (sexp, gck_crypto_rsa_pad_one, data, n_data, signature, n_signature);
+ rv = gck_mechanism_rsa_sign (sexp, gck_mechanism_rsa_pad_one, data, n_data, signature, n_signature);
break;
case CKM_RSA_X_509:
g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_sign_rsa (sexp, gck_crypto_rsa_pad_raw, data, n_data, signature, n_signature);
+ rv = gck_mechanism_rsa_sign (sexp, gck_mechanism_rsa_pad_raw, data, n_data, signature, n_signature);
break;
case CKM_DSA:
g_return_val_if_fail (algorithm == GCRY_PK_DSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_sign_dsa (sexp, data, n_data, signature, n_signature);
+ rv = gck_mechanism_dsa_sign (sexp, data, n_data, signature, n_signature);
break;
default:
/* Again shouldn't be reached */
@@ -440,113 +303,26 @@ gck_crypto_sign (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
}
CK_RV
-gck_crypto_sign_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
-{
- gcry_sexp_t ssig, sdata;
- guint nbits;
- gcry_error_t gcry;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- nbits = gcry_pk_get_nbits (sexp);
- g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
- /* Just want to know the length */
- if (!signature) {
- *n_signature = (nbits + 7) / 8;
- return CKR_OK;
- }
-
- /* Prepare the input sexp */
- rv = data_to_sexp ("(data (flags raw) (value %m))",
- nbits, padding, data, n_data, &sdata);
- if (rv != CKR_OK)
- return rv;
-
- /* Do the magic */
- gcry = gcry_pk_sign (&ssig, sdata, sexp);
- gcry_sexp_release (sdata);
-
- /* TODO: Certain codes should be returned (data too big etc... ) */
- if (gcry) {
- g_message ("signing of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
-
- /* Now extract and send it back out */
- rv = sexp_to_data (ssig, nbits, signature, n_signature, NULL, "rsa", "s", NULL);
- gcry_sexp_release (ssig);
-
- return rv;
-}
-
-CK_RV
-gck_crypto_sign_dsa (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data,
- CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
+gck_crypto_verify (GckSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
+ CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
{
- gcry_sexp_t ssig, splain;
- gcry_error_t gcry;
- gcry_mpi_t mpi;
- CK_ULONG size;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- if (n_data != 20)
- return CKR_DATA_LEN_RANGE;
-
- /* If no output, then don't process */
- if (!signature) {
- *n_signature = 40;
- return CKR_OK;
- } else if (*n_signature < 40) {
- *n_signature = 40;
- return CKR_BUFFER_TOO_SMALL;
- }
-
- /* Prepare the input s-expression */
- gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
- gcry_mpi_release (mpi);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
- /* Do the magic */
- gcry = gcry_pk_sign (&ssig, splain, sexp);
- gcry_sexp_release (splain);
-
- /* TODO: Certain codes should be returned (data too big etc... ) */
- if (gcry) {
- g_message ("signing of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
+ GckSexp *sexp;
- g_assert (*n_signature >= 40);
-
- size = 20;
- rv = sexp_to_data (ssig, 20 * 8, signature, &size, NULL, "dsa", "r", NULL);
- if (rv == CKR_OK) {
- g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
- rv = sexp_to_data (ssig, 20 * 8, signature + 20, &size, NULL, "dsa", "s", NULL);
- if (rv == CKR_OK) {
- g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
- *n_signature = 40;
- }
+ switch (mech) {
+ case CKM_RSA_PKCS:
+ case CKM_RSA_X_509:
+ case CKM_DSA:
+ sexp = gck_session_get_crypto_state (session);
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ return gck_crypto_verify_xsa (gck_sexp_get (sexp), mech, data, n_data, signature, n_signature);
+ default:
+ g_return_val_if_reached (CKR_GENERAL_ERROR);
}
-
- gcry_sexp_release (ssig);
- return CKR_OK;
}
CK_RV
-gck_crypto_verify (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
+gck_crypto_verify_xsa (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
+ CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
{
int algorithm;
CK_RV rv;
@@ -555,7 +331,7 @@ gck_crypto_verify (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
+ if (!gck_sexp_parse_key (sexp, &algorithm, NULL, NULL))
g_return_val_if_reached (CKR_GENERAL_ERROR);
/*
@@ -567,15 +343,15 @@ gck_crypto_verify (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
switch (mech) {
case CKM_RSA_PKCS:
g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_verify_rsa (sexp, gck_crypto_rsa_pad_one, data, n_data, signature, n_signature);
+ rv = gck_mechanism_rsa_verify (sexp, gck_mechanism_rsa_pad_one, data, n_data, signature, n_signature);
break;
case CKM_RSA_X_509:
g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_verify_rsa (sexp, gck_crypto_rsa_pad_raw, data, n_data, signature, n_signature);
+ rv = gck_mechanism_rsa_verify (sexp, gck_mechanism_rsa_pad_raw, data, n_data, signature, n_signature);
break;
case CKM_DSA:
g_return_val_if_fail (algorithm == GCRY_PK_DSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_verify_dsa (sexp, data, n_data, signature, n_signature);
+ rv = gck_mechanism_dsa_verify (sexp, data, n_data, signature, n_signature);
break;
default:
/* Again shouldn't be reached */
@@ -585,400 +361,62 @@ gck_crypto_verify (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
return rv;
}
-CK_RV
-gck_crypto_verify_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
-{
- gcry_sexp_t ssig, sdata;
- gcry_error_t gcry;
- guint nbits;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- /* The key size */
- nbits = gcry_pk_get_nbits (sexp);
- g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
- if (n_signature != (nbits + 7) / 8)
- return CKR_SIGNATURE_LEN_RANGE;
-
- /* Prepare the input s expressions */
- rv = data_to_sexp ("(data (flags raw) (value %m))",
- nbits, padding, data, n_data, &sdata);
- if (rv != CKR_OK)
- return rv;
-
- rv = data_to_sexp ("(sig-val (rsa (s %m)))",
- nbits, NULL, signature, n_signature, &ssig);
- if (rv != CKR_OK) {
- gcry_sexp_release (sdata);
- return rv;
- }
-
- /* Do the magic */
- gcry = gcry_pk_verify (ssig, sdata, sexp);
- gcry_sexp_release (sdata);
- gcry_sexp_release (ssig);
-
- /* TODO: See if any other codes should be mapped */
- if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
- return CKR_SIGNATURE_INVALID;
- } else if (gcry) {
- g_message ("signing of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
-
- return CKR_OK;
-}
-
-CK_RV
-gck_crypto_verify_dsa (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data,
- CK_BYTE_PTR signature, CK_ULONG n_signature)
-{
- gcry_sexp_t ssig, splain;
- gcry_error_t gcry;
- gcry_mpi_t mpi, mpi2;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- if (n_data != 20)
- return CKR_DATA_LEN_RANGE;
- if (n_signature != 40)
- return CKR_SIGNATURE_LEN_RANGE;
-
- /* Prepare the input s-expressions */
- gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
- gcry_mpi_release (mpi);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
- gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, signature, 20, NULL);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- gcry = gcry_mpi_scan (&mpi2, GCRYMPI_FMT_USG, signature + 20, 20, NULL);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- gcry = gcry_sexp_build (&ssig, NULL, "(sig-val (dsa (r %m) (s %m)))", mpi, mpi2);
- gcry_mpi_release (mpi);
- gcry_mpi_release (mpi2);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
- /* Do the magic */
- gcry = gcry_pk_verify (ssig, splain, sexp);
- gcry_sexp_release (splain);
- gcry_sexp_release (ssig);
-
- /* TODO: See if any other codes should be mapped */
- if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
- return CKR_SIGNATURE_INVALID;
- } else if (gcry) {
- g_message ("signing of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
-
- return CKR_OK;
-}
-
CK_RV
-gck_crypto_perform (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_ATTRIBUTE_TYPE method,
+gck_crypto_perform (GckSession *session, CK_MECHANISM_TYPE mech, CK_ATTRIBUTE_TYPE method,
CK_BYTE_PTR bufone, CK_ULONG n_bufone, CK_BYTE_PTR buftwo, CK_ULONG_PTR n_buftwo)
{
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (GCK_IS_SESSION (session), CKR_GENERAL_ERROR);
g_return_val_if_fail (method, CKR_GENERAL_ERROR);
g_return_val_if_fail (n_buftwo, CKR_GENERAL_ERROR);
switch (method) {
case CKA_ENCRYPT:
- return gck_crypto_encrypt (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
+ return gck_crypto_encrypt (session, mech, bufone, n_bufone, buftwo, n_buftwo);
case CKA_DECRYPT:
- return gck_crypto_decrypt (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
+ return gck_crypto_decrypt (session, mech, bufone, n_bufone, buftwo, n_buftwo);
case CKA_SIGN:
- return gck_crypto_sign (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
+ return gck_crypto_sign (session, mech, bufone, n_bufone, buftwo, n_buftwo);
case CKA_VERIFY:
- return gck_crypto_verify (sexp, mech, bufone, n_bufone, buftwo, *n_buftwo);
+ return gck_crypto_verify (session, mech, bufone, n_bufone, buftwo, *n_buftwo);
default:
g_return_val_if_reached (CKR_GENERAL_ERROR);
}
}
/* ----------------------------------------------------------------------------
- * SEXP FUNCTIONS
+ * PREPARE FUNCTIONS
*/
-#define PUBLIC_KEY "public-key"
-#define PUBLIC_KEY_L 10
-#define PRIVATE_KEY "private-key"
-#define PRIVATE_KEY_L 11
-
-gboolean
-gck_crypto_sexp_parse_key (gcry_sexp_t s_key, int *algorithm, gboolean *is_private,
- gcry_sexp_t *numbers)
-{
- gboolean ret = FALSE;
- gcry_sexp_t child = NULL;
- gchar *str = NULL;
- const gchar *data;
- gsize n_data;
- gboolean priv;
- int algo;
-
- data = gcry_sexp_nth_data (s_key, 0, &n_data);
- if (!data)
- goto done;
-
- if (n_data == PUBLIC_KEY_L && strncmp (data, PUBLIC_KEY, PUBLIC_KEY_L) == 0)
- priv = FALSE;
- else if (n_data == PRIVATE_KEY_L && strncmp (data, PRIVATE_KEY, PRIVATE_KEY_L) == 0)
- priv = TRUE;
- else
- goto done;
-
- child = gcry_sexp_nth (s_key, 1);
- if (!child)
- goto done;
-
- data = gcry_sexp_nth_data (child, 0, &n_data);
- if (!data)
- goto done;
-
- str = g_alloca (n_data + 1);
- memcpy (str, data, n_data);
- str[n_data] = 0;
-
- algo = gcry_pk_map_name (str);
- if (!algo)
- goto done;
-
- /* Yay all done */
- if (algorithm)
- *algorithm = algo;
- if (numbers) {
- *numbers = child;
- child = NULL;
- }
- if (is_private)
- *is_private = priv;
-
- ret = TRUE;
-
-done:
- gcry_sexp_release (child);
- return ret;
-}
-
-static gcry_sexp_t
-rsa_numbers_to_public (gcry_sexp_t rsa)
-{
- gcry_sexp_t pubkey = NULL;
- gcry_mpi_t n, e;
- gcry_error_t gcry;
-
- n = e = NULL;
-
- if (!gck_crypto_sexp_extract_mpi (rsa, &n, "n", NULL) ||
- !gck_crypto_sexp_extract_mpi (rsa, &e, "e", NULL))
- goto done;
-
- gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (rsa (n %m) (e %m)))",
- n, e);
- if (gcry)
- goto done;
- g_assert (pubkey);
-
-done:
- gcry_mpi_release (n);
- gcry_mpi_release (e);
-
- return pubkey;
-}
-
-static gcry_sexp_t
-dsa_numbers_to_public (gcry_sexp_t dsa)
-{
- gcry_mpi_t p, q, g, y;
- gcry_sexp_t pubkey = NULL;
- gcry_error_t gcry;
-
- p = q = g = y = NULL;
-
- if (!gck_crypto_sexp_extract_mpi (dsa, &p, "p", NULL) ||
- !gck_crypto_sexp_extract_mpi (dsa, &q, "q", NULL) ||
- !gck_crypto_sexp_extract_mpi (dsa, &g, "g", NULL) ||
- !gck_crypto_sexp_extract_mpi (dsa, &y, "y", NULL))
- goto done;
-
- gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (dsa (p %m) (q %m) (g %m) (y %m)))",
- p, q, g, y);
- if (gcry)
- goto done;
- g_assert (pubkey);
-
-done:
- gcry_mpi_release (p);
- gcry_mpi_release (q);
- gcry_mpi_release (g);
- gcry_mpi_release (y);
-
- return pubkey;
-}
-
-gboolean
-gck_crypto_sexp_key_to_public (gcry_sexp_t privkey, gcry_sexp_t *pubkey)
+CK_RV
+gck_crypto_prepare (GckSession *session, CK_MECHANISM_TYPE mech, GckObject *key)
{
- gcry_sexp_t numbers;
- int algorithm;
+ g_return_val_if_fail (GCK_IS_SESSION (session), CKR_GENERAL_ERROR);
- if (!gck_crypto_sexp_parse_key (privkey, &algorithm, NULL, &numbers))
- g_return_val_if_reached (FALSE);
-
- switch (algorithm) {
- case GCRY_PK_RSA:
- *pubkey = rsa_numbers_to_public (numbers);
- break;
- case GCRY_PK_DSA:
- *pubkey = dsa_numbers_to_public (numbers);
- break;
+ switch (mech) {
+ case CKM_RSA_PKCS:
+ case CKM_RSA_X_509:
+ case CKM_DSA:
+ return gck_crypto_prepare_xsa (session, mech, key);
default:
- g_return_val_if_reached (FALSE);
- }
-
- gcry_sexp_release (numbers);
- return *pubkey ? TRUE : FALSE;
-}
-
-gboolean
-gck_crypto_sexp_extract_mpi (gcry_sexp_t sexp, gcry_mpi_t *mpi, ...)
-{
- gcry_sexp_t at = NULL;
- va_list va;
-
- g_assert (sexp);
- g_assert (mpi);
-
- va_start (va, mpi);
- at = sexp_get_childv (sexp, va);
- va_end (va);
-
- *mpi = NULL;
- if (at)
- *mpi = gcry_sexp_nth_mpi (at ? at : sexp, 1, GCRYMPI_FMT_USG);
- if (at)
- gcry_sexp_release (at);
-
- return (*mpi) ? TRUE : FALSE;
-}
-
-void
-gck_crypto_sexp_dump (gcry_sexp_t sexp)
-{
- gsize len;
- gchar *buf;
-
- len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
- buf = g_malloc (len);
- gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buf, len);
- g_printerr ("%s", buf);
- g_free (buf);
-}
-
-/* ----------------------------------------------------------------------------
- * PADDING FUNCTIONS
- */
-
-
-guchar*
-gck_crypto_rsa_pad_raw (guint n_modulus, const guchar* raw,
- gsize n_raw, gsize *n_padded)
-{
- gint total, n_pad;
- guchar *padded;
-
- /*
- * 0x00 0x00 0x00 ... 0x?? 0x?? 0x?? ...
- * padding data
- */
-
- total = (n_modulus + 7) / 8;
- n_pad = total - n_raw;
- if (n_pad < 0) /* minumum padding */
- return NULL;
-
- padded = g_new0 (guchar, total);
- memset (padded, 0x00, n_pad);
- memcpy (padded + n_pad, raw, n_raw);
-
- *n_padded = total;
- return padded;
+ g_return_val_if_reached (CKR_GENERAL_ERROR);
+ }
}
-guchar*
-gck_crypto_rsa_pad_one (guint n_modulus, const guchar* raw,
- gsize n_raw, gsize *n_padded)
+CK_RV
+gck_crypto_prepare_xsa (GckSession *session, CK_MECHANISM_TYPE mech, GckObject *key)
{
- gint total, n_pad;
- guchar *padded;
-
- /*
- * 0x00 0x01 0xFF 0xFF ... 0x00 0x?? 0x?? 0x?? ...
- * type padding data
- */
-
- total = (n_modulus + 7) / 8;
- n_pad = total - 3 - n_raw;
- if (n_pad < 8) /* minumum padding */
- return NULL;
-
- padded = g_new0 (guchar, total);
- padded[1] = 1; /* Block type */
- memset (padded + 2, 0xff, n_pad);
- memcpy (padded + 3 + n_pad, raw, n_raw);
-
- *n_padded = total;
- return padded;
-}
+ GckSexp *sexp;
-guchar*
-gck_crypto_rsa_pad_two (guint n_modulus, const guchar* raw,
- gsize n_raw, gsize *n_padded)
-{
- gint total, n_pad;
- guchar *padded;
-
- /*
- * 0x00 0x01 0x?? 0x?? ... 0x00 0x?? 0x?? 0x?? ...
- * type padding data
- */
-
- total = (n_modulus + 7) / 8;
- n_pad = total - 3 - n_raw;
- if (n_pad < 8) /* minumum padding */
- return NULL;
-
- padded = g_new0 (guchar, total);
- padded[1] = 2; /* Block type */
- fill_random_nonzero (padded + 2, n_pad);
- memcpy (padded + 3 + n_pad, raw, n_raw);
-
- *n_padded = total;
- return padded;
-}
+ g_return_val_if_fail (GCK_IS_SESSION (session), CKR_GENERAL_ERROR);
+ g_return_val_if_fail (GCK_IS_SEXP_KEY (key), CKR_GENERAL_ERROR);
-guchar*
-gck_crypto_rsa_unpad_one (guint bits, const guchar *padded,
- gsize n_padded, gsize *n_raw)
-{
- return unpad_rsa_pkcs1 (0x01, bits, padded, n_padded, n_raw);
-}
+ /* Load up the actual sexp we're going to use */
+ sexp = gck_sexp_key_acquire_crypto_sexp (GCK_SEXP_KEY (key), session);
+ if (sexp == NULL)
+ return CKR_USER_NOT_LOGGED_IN;
-guchar*
-gck_crypto_rsa_unpad_two (guint bits, const guchar *padded,
- gsize n_padded, gsize *n_raw)
-{
- return unpad_rsa_pkcs1 (0x02, bits, padded, n_padded, n_raw);
+ gck_session_set_crypto_state (session, sexp, gck_sexp_unref);
+ return CKR_OK;
}
/* --------------------------------------------------------------------------
diff --git a/pkcs11/gck/gck-crypto.h b/pkcs11/gck/gck-crypto.h
index 623b544..1b2598a 100644
--- a/pkcs11/gck/gck-crypto.h
+++ b/pkcs11/gck/gck-crypto.h
@@ -22,141 +22,104 @@
#ifndef GCKCRYPTO_H_
#define GCKCRYPTO_H_
+#include "gck-types.h"
+
+#include "pkcs11/pkcs11.h"
+
#include <glib.h>
#include <gcrypt.h>
-#include "pkcs11/pkcs11.h"
-
typedef guchar* (*GckCryptoPadding) (guint n_modulus, const guchar* raw,
gsize n_raw, gsize *n_padded);
-static const CK_MECHANISM_TYPE GCK_CRYPTO_RSA_MECHANISMS[] = {
- CKM_RSA_PKCS,
- CKM_RSA_X_509
-};
-
-static const CK_MECHANISM_TYPE GCK_CRYPTO_DSA_MECHANISMS[] = {
- CKM_DSA
-};
void gck_crypto_initialize (void);
-CK_RV gck_crypto_perform (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_ATTRIBUTE_TYPE method,
- CK_BYTE_PTR bufone,
- CK_ULONG n_bufone,
- CK_BYTE_PTR buftwo,
+CK_RV gck_crypto_prepare (GckSession *session,
+ CK_MECHANISM_TYPE mech,
+ GckObject *key);
+
+CK_RV gck_crypto_prepare_xsa (GckSession *session,
+ CK_MECHANISM_TYPE mech,
+ GckObject *key);
+
+CK_RV gck_crypto_perform (GckSession *session,
+ CK_MECHANISM_TYPE mech,
+ CK_ATTRIBUTE_TYPE method,
+ CK_BYTE_PTR bufone,
+ CK_ULONG n_bufone,
+ CK_BYTE_PTR buftwo,
CK_ULONG_PTR n_buftwo);
-CK_RV gck_crypto_encrypt (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR encrypted,
+CK_RV gck_crypto_encrypt (GckSession *session,
+ CK_MECHANISM_TYPE mech,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR encrypted,
CK_ULONG_PTR n_encrypted);
-CK_RV gck_crypto_encrypt_rsa (gcry_sexp_t sexp,
- GckCryptoPadding padding,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR encrypted,
+CK_RV gck_crypto_encrypt_xsa (gcry_sexp_t sexp,
+ CK_MECHANISM_TYPE mech,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR encrypted,
CK_ULONG_PTR n_encrypted);
-
-CK_RV gck_crypto_decrypt (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_BYTE_PTR encrypted,
- CK_ULONG n_encrypted,
- CK_BYTE_PTR data,
- CK_ULONG_PTR n_data);
-
-CK_RV gck_crypto_decrypt_rsa (gcry_sexp_t sexp,
- GckCryptoPadding padding,
- CK_BYTE_PTR encrypted,
- CK_ULONG n_encrypted,
- CK_BYTE_PTR data,
+CK_RV gck_crypto_decrypt (GckSession *session,
+ CK_MECHANISM_TYPE mech,
+ CK_BYTE_PTR encrypted,
+ CK_ULONG n_encrypted,
+ CK_BYTE_PTR data,
CK_ULONG_PTR n_data);
-CK_RV gck_crypto_sign (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
- CK_ULONG_PTR n_signature);
+CK_RV gck_crypto_decrypt_xsa (gcry_sexp_t sexp,
+ CK_MECHANISM_TYPE mech,
+ CK_BYTE_PTR encrypted,
+ CK_ULONG n_encrypted,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR n_data);
-CK_RV gck_crypto_sign_rsa (gcry_sexp_t sexp,
- GckCryptoPadding padding,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
+CK_RV gck_crypto_sign (GckSession *session,
+ CK_MECHANISM_TYPE mech,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR signature,
CK_ULONG_PTR n_signature);
-CK_RV gck_crypto_sign_dsa (gcry_sexp_t sexp,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
+CK_RV gck_crypto_sign_xsa (gcry_sexp_t sexp,
+ CK_MECHANISM_TYPE mech,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR signature,
CK_ULONG_PTR n_signature);
-CK_RV gck_crypto_verify (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
- CK_ULONG n_signature);
-
-CK_RV gck_crypto_verify_rsa (gcry_sexp_t sexp,
- GckCryptoPadding padding,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
+CK_RV gck_crypto_verify (GckSession *session,
+ CK_MECHANISM_TYPE mech,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR signature,
CK_ULONG n_signature);
-
-CK_RV gck_crypto_verify_dsa (gcry_sexp_t sexp,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
+CK_RV gck_crypto_verify_xsa (gcry_sexp_t sexp,
+ CK_MECHANISM_TYPE mech,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR signature,
CK_ULONG n_signature);
-gboolean gck_crypto_sexp_parse_key (gcry_sexp_t sexp,
- int *algorithm,
- gboolean *is_private,
- gcry_sexp_t *numbers);
-
-gboolean gck_crypto_sexp_key_to_public (gcry_sexp_t sexp,
- gcry_sexp_t *pub);
-
-gboolean gck_crypto_sexp_extract_mpi (gcry_sexp_t sexp,
- gcry_mpi_t *mpi,
+CK_RV gck_crypto_sexp_to_data (gcry_sexp_t sexp,
+ guint bits,
+ CK_BYTE_PTR data,
+ CK_ULONG *n_data,
+ GckCryptoPadding padding,
...) G_GNUC_NULL_TERMINATED;
-void gck_crypto_sexp_dump (gcry_sexp_t sexp);
-
-guchar* gck_crypto_rsa_pad_raw (guint bits,
- const guchar* raw,
- gsize n_raw,
- gsize *n_padded);
-
-guchar* gck_crypto_rsa_pad_one (guint bits,
- const guchar* raw,
- gsize n_raw,
- gsize *n_padded);
-
-guchar* gck_crypto_rsa_pad_two (guint bits,
- const guchar* raw,
- gsize n_raw,
- gsize *n_padded);
-
-guchar* gck_crypto_rsa_unpad_one (guint bits,
- const guchar *padded,
- gsize n_padded,
- gsize *n_raw);
-
-guchar* gck_crypto_rsa_unpad_two (guint bits,
- const guchar* padded,
- gsize n_padded,
- gsize *n_raw);
+CK_RV gck_crypto_data_to_sexp (const gchar *format,
+ guint nbits,
+ GckCryptoPadding padding,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ gcry_sexp_t *sexp);
#endif /* GCKCRYPTO_H_ */
diff --git a/pkcs11/gck/gck-data-der.c b/pkcs11/gck/gck-data-der.c
index b1e4e6c..37d8003 100644
--- a/pkcs11/gck/gck-data-der.c
+++ b/pkcs11/gck/gck-data-der.c
@@ -23,10 +23,10 @@
#include "config.h"
-#include "gck-crypto.h"
#include "gck-data-asn1.h"
#include "gck-data-der.h"
#include "gck-data-types.h"
+#include "gck-sexp.h"
#include "egg/egg-secure-memory.h"
#include "egg/egg-symkey.h"
@@ -674,8 +674,8 @@ gck_data_der_write_public_key_rsa (gcry_sexp_t s_key, gsize *len)
"PK.RSAPublicKey", &asn);
g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
- if (!gck_crypto_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL))
+ if (!gck_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL))
goto done;
if (!gck_data_asn1_write_mpi (asn, "modulus", n) ||
@@ -707,12 +707,12 @@ gck_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
"PK.RSAPrivateKey", &asn);
g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
- if (!gck_crypto_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &d, "rsa", "d", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &p, "rsa", "p", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &q, "rsa", "q", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &u, "rsa", "u", NULL))
+ if (!gck_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &d, "rsa", "d", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &p, "rsa", "p", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &q, "rsa", "q", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &u, "rsa", "u", NULL))
goto done;
if (!gck_data_asn1_write_mpi (asn, "modulus", n) ||
@@ -778,10 +778,10 @@ gck_data_der_write_public_key_dsa (gcry_sexp_t s_key, gsize *len)
"PK.DSAPublicKey", &asn);
g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
- if (!gck_crypto_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL))
+ if (!gck_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL))
goto done;
if (!gck_data_asn1_write_mpi (asn, "p", p) ||
@@ -820,7 +820,7 @@ gck_data_der_write_private_key_dsa_part (gcry_sexp_t skey, gsize *n_key)
"PK.DSAPrivatePart", &asn);
g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
- if (!gck_crypto_sexp_extract_mpi (skey, &x, "dsa", "x", NULL))
+ if (!gck_sexp_extract_mpi (skey, &x, "dsa", "x", NULL))
goto done;
if (!gck_data_asn1_write_mpi (asn, "", x))
@@ -850,9 +850,9 @@ gck_data_der_write_private_key_dsa_params (gcry_sexp_t skey, gsize *n_params)
"PK.DSAParameters", &asn);
g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
- if (!gck_crypto_sexp_extract_mpi (skey, &p, "dsa", "p", NULL) ||
- !gck_crypto_sexp_extract_mpi (skey, &q, "dsa", "q", NULL) ||
- !gck_crypto_sexp_extract_mpi (skey, &g, "dsa", "g", NULL))
+ if (!gck_sexp_extract_mpi (skey, &p, "dsa", "p", NULL) ||
+ !gck_sexp_extract_mpi (skey, &q, "dsa", "q", NULL) ||
+ !gck_sexp_extract_mpi (skey, &g, "dsa", "g", NULL))
goto done;
if (!gck_data_asn1_write_mpi (asn, "p", p) ||
@@ -886,11 +886,11 @@ gck_data_der_write_private_key_dsa (gcry_sexp_t s_key, gsize *len)
"PK.DSAPrivateKey", &asn);
g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
- if (!gck_crypto_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL) ||
- !gck_crypto_sexp_extract_mpi (s_key, &x, "dsa", "x", NULL))
+ if (!gck_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL) ||
+ !gck_sexp_extract_mpi (s_key, &x, "dsa", "x", NULL))
goto done;
if (!gck_data_asn1_write_mpi (asn, "p", p) ||
@@ -925,7 +925,7 @@ gck_data_der_write_public_key (gcry_sexp_t s_key, gsize *len)
g_return_val_if_fail (s_key != NULL, NULL);
- if (!gck_crypto_sexp_parse_key (s_key, &algorithm, &is_priv, NULL))
+ if (!gck_sexp_parse_key (s_key, &algorithm, &is_priv, NULL))
g_return_val_if_reached (NULL);
g_return_val_if_fail (!is_priv, NULL);
@@ -948,7 +948,7 @@ gck_data_der_write_private_key (gcry_sexp_t s_key, gsize *len)
g_return_val_if_fail (s_key != NULL, NULL);
- if (!gck_crypto_sexp_parse_key (s_key, &algorithm, &is_priv, NULL))
+ if (!gck_sexp_parse_key (s_key, &algorithm, &is_priv, NULL))
g_return_val_if_reached (NULL);
g_return_val_if_fail (is_priv, NULL);
@@ -1043,7 +1043,7 @@ gck_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
init_quarks ();
/* Parse and check that the key is for real */
- if (!gck_crypto_sexp_parse_key (skey, &algorithm, &is_priv, NULL))
+ if (!gck_sexp_parse_key (skey, &algorithm, &is_priv, NULL))
g_return_val_if_reached (NULL);
g_return_val_if_fail (is_priv == TRUE, NULL);
diff --git a/pkcs11/gck/gck-mechanism-dsa.c b/pkcs11/gck/gck-mechanism-dsa.c
new file mode 100644
index 0000000..8b75a67
--- /dev/null
+++ b/pkcs11/gck/gck-mechanism-dsa.c
@@ -0,0 +1,144 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gck-crypto.h"
+#include "gck-mechanism-dsa.h"
+#include "gck-session.h"
+#include "gck-sexp.h"
+#include "gck-sexp-key.h"
+
+#include "egg/egg-libgcrypt.h"
+#include "egg/egg-secure-memory.h"
+
+/* ----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+CK_RV
+gck_mechanism_dsa_sign (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data,
+ CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
+{
+ gcry_sexp_t ssig, splain;
+ gcry_error_t gcry;
+ gcry_mpi_t mpi;
+ CK_ULONG size;
+ CK_RV rv;
+
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
+
+ if (n_data != 20)
+ return CKR_DATA_LEN_RANGE;
+
+ /* If no output, then don't process */
+ if (!signature) {
+ *n_signature = 40;
+ return CKR_OK;
+ } else if (*n_signature < 40) {
+ *n_signature = 40;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ /* Prepare the input s-expression */
+ gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
+ g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
+ gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
+ gcry_mpi_release (mpi);
+ g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
+
+ /* Do the magic */
+ gcry = gcry_pk_sign (&ssig, splain, sexp);
+ gcry_sexp_release (splain);
+
+ /* TODO: Certain codes should be returned (data too big etc... ) */
+ if (gcry) {
+ g_message ("signing of the data failed: %s", gcry_strerror (gcry));
+ return CKR_FUNCTION_FAILED;
+ }
+
+ g_assert (*n_signature >= 40);
+
+ size = 20;
+ rv = gck_crypto_sexp_to_data (ssig, 20 * 8, signature, &size, NULL, "dsa", "r", NULL);
+ if (rv == CKR_OK) {
+ g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
+ rv = gck_crypto_sexp_to_data (ssig, 20 * 8, signature + 20, &size, NULL, "dsa", "s", NULL);
+ if (rv == CKR_OK) {
+ g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
+ *n_signature = 40;
+ }
+ }
+
+ gcry_sexp_release (ssig);
+ return CKR_OK;
+}
+
+CK_RV
+gck_mechanism_dsa_verify (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data,
+ CK_BYTE_PTR signature, CK_ULONG n_signature)
+{
+ gcry_sexp_t ssig, splain;
+ gcry_error_t gcry;
+ gcry_mpi_t mpi, mpi2;
+
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
+
+ if (n_data != 20)
+ return CKR_DATA_LEN_RANGE;
+ if (n_signature != 40)
+ return CKR_SIGNATURE_LEN_RANGE;
+
+ /* Prepare the input s-expressions */
+ gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
+ g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
+ gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
+ gcry_mpi_release (mpi);
+ g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
+
+ gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, signature, 20, NULL);
+ g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
+ gcry = gcry_mpi_scan (&mpi2, GCRYMPI_FMT_USG, signature + 20, 20, NULL);
+ g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
+ gcry = gcry_sexp_build (&ssig, NULL, "(sig-val (dsa (r %m) (s %m)))", mpi, mpi2);
+ gcry_mpi_release (mpi);
+ gcry_mpi_release (mpi2);
+ g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
+
+ /* Do the magic */
+ gcry = gcry_pk_verify (ssig, splain, sexp);
+ gcry_sexp_release (splain);
+ gcry_sexp_release (ssig);
+
+ /* TODO: See if any other codes should be mapped */
+ if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
+ return CKR_SIGNATURE_INVALID;
+ } else if (gcry) {
+ g_message ("signing of the data failed: %s", gcry_strerror (gcry));
+ return CKR_FUNCTION_FAILED;
+ }
+
+ return CKR_OK;
+}
diff --git a/pkcs11/gck/gck-mechanism-dsa.h b/pkcs11/gck/gck-mechanism-dsa.h
new file mode 100644
index 0000000..2434a5c
--- /dev/null
+++ b/pkcs11/gck/gck-mechanism-dsa.h
@@ -0,0 +1,49 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef GCK_MECHANISM_DSA_H_
+#define GCK_MECHANISM_DSA_H_
+
+#include "gck-types.h"
+
+#include "pkcs11/pkcs11.h"
+
+#include <glib.h>
+
+#include <gcrypt.h>
+
+static const CK_MECHANISM_TYPE GCK_CRYPTO_DSA_MECHANISMS[] = {
+ CKM_DSA
+};
+
+CK_RV gck_mechanism_dsa_sign (gcry_sexp_t sexp,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR n_signature);
+
+CK_RV gck_mechanism_dsa_verify (gcry_sexp_t sexp,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR signature,
+ CK_ULONG n_signature);
+
+#endif /* GCK_MECHANISM_DSA_H_ */
diff --git a/pkcs11/gck/gck-mechanism-rsa.c b/pkcs11/gck/gck-mechanism-rsa.c
new file mode 100644
index 0000000..fea02f7
--- /dev/null
+++ b/pkcs11/gck/gck-mechanism-rsa.c
@@ -0,0 +1,387 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gck-mechanism-rsa.h"
+#include "gck-sexp.h"
+
+#include "egg/egg-libgcrypt.h"
+#include "egg/egg-secure-memory.h"
+
+/* ----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static void
+fill_random_nonzero (guchar *data, gsize n_data)
+{
+ guchar *rnd;
+ guint n_zero, i, j;
+
+ gcry_randomize (data, n_data, GCRY_STRONG_RANDOM);
+
+ /* Find any zeros in random data */
+ n_zero = 0;
+ for (i = 0; i < n_data; ++i) {
+ if (data[i] == 0x00)
+ ++n_zero;
+ }
+
+ while (n_zero > 0) {
+ rnd = gcry_random_bytes (n_zero, GCRY_STRONG_RANDOM);
+ n_zero = 0;
+ for (i = 0, j = 0; i < n_data; ++i) {
+ if (data[i] != 0x00)
+ continue;
+
+ /* Use some of the replacement data */
+ data[i] = rnd[j];
+ ++j;
+
+ /* It's zero again :( */
+ if (data[i] == 0x00)
+ n_zero++;
+ }
+
+ gcry_free (rnd);
+ }
+}
+
+static guchar*
+unpad_rsa_pkcs1 (guchar bt, guint n_modulus, const guchar* padded,
+ gsize n_padded, gsize *n_raw)
+{
+ const guchar *at;
+ guint check;
+ guchar *raw;
+
+ check = (n_modulus + 7) / 8;
+
+ /* The absolute minimum size including padding */
+ g_return_val_if_fail (check >= 3 + 8, NULL);
+
+ if (n_padded != check)
+ return NULL;
+
+ /* Check the header */
+ if (padded[0] != 0x00 || padded[1] != bt)
+ return NULL;
+
+ /* The first zero byte after the header */
+ at = memchr (padded + 2, 0x00, n_padded - 2);
+ if (!at)
+ return NULL;
+
+ ++at;
+ *n_raw = n_padded - (at - padded);
+ raw = g_new0 (guchar, *n_raw);
+ memcpy (raw, at, *n_raw);
+ return raw;
+}
+
+/* ----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+CK_RV
+gck_mechanism_rsa_encrypt (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data,
+ CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
+{
+ gcry_sexp_t splain, sdata;
+ gcry_error_t gcry;
+ guint nbits;
+ CK_RV rv;
+
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
+
+ nbits = gcry_pk_get_nbits (sexp);
+ g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
+
+ /* Just want to know the length */
+ if (!encrypted) {
+ *n_encrypted = (nbits + 7) / 8;
+ return CKR_OK;
+ }
+
+ /* Prepare the input s expression */
+ rv = gck_crypto_data_to_sexp ("(data (flags raw) (value %m))",
+ nbits, padding, data, n_data, &splain);
+ if (rv != CKR_OK)
+ return rv;
+
+ /* Do the magic */
+ gcry = gcry_pk_encrypt (&sdata, splain, sexp);
+ gcry_sexp_release (splain);
+
+ /* TODO: Certain codes should be returned (data too big etc... ) */
+ if (gcry) {
+ g_message ("encrypting of the data failed: %s", gcry_strerror (gcry));
+ return CKR_FUNCTION_FAILED;
+ }
+
+ /* Now extract and send it back out */
+ rv = gck_crypto_sexp_to_data (sdata, nbits, encrypted, n_encrypted, NULL,
+ "enc-val", "rsa", "a", NULL);
+ gcry_sexp_release (sdata);
+
+ return rv;
+}
+
+CK_RV
+gck_mechanism_rsa_decrypt (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR encrypted,
+ CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
+{
+ gcry_sexp_t splain, sdata;
+ gcry_error_t gcry;
+ guint nbits;
+ CK_RV rv;
+
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);
+
+ nbits = gcry_pk_get_nbits (sexp);
+ g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
+
+ /* Just want to know the length */
+ if (!data) {
+ *n_data = (nbits + 7) / 8;
+ return CKR_OK;
+ }
+
+ if (n_encrypted != (nbits + 7) / 8)
+ return CKR_DATA_LEN_RANGE;
+
+ /* Prepare the input s expression */
+ rv = gck_crypto_data_to_sexp ("(enc-val (flags) (rsa (a %m)))",
+ nbits, NULL, encrypted, n_encrypted, &sdata);
+ if (rv != CKR_OK)
+ return rv;
+
+ /* Do the magic */
+ gcry = gcry_pk_decrypt (&splain, sdata, sexp);
+ gcry_sexp_release (sdata);
+
+ /* TODO: Certain codes should be returned (data too big etc... ) */
+ if (gcry) {
+ g_message ("decrypting of the data failed: %s", gcry_strerror (gcry));
+ return CKR_FUNCTION_FAILED;
+ }
+
+ /* Now extract and send it back out */
+ rv = gck_crypto_sexp_to_data (splain, nbits, data, n_data, padding, "value", NULL);
+ gcry_sexp_release (splain);
+
+ return rv;
+}
+
+CK_RV
+gck_mechanism_rsa_sign (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data,
+ CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
+{
+ gcry_sexp_t ssig, sdata;
+ guint nbits;
+ gcry_error_t gcry;
+ CK_RV rv;
+
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
+
+ nbits = gcry_pk_get_nbits (sexp);
+ g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
+
+ /* Just want to know the length */
+ if (!signature) {
+ *n_signature = (nbits + 7) / 8;
+ return CKR_OK;
+ }
+
+ /* Prepare the input sexp */
+ rv = gck_crypto_data_to_sexp ("(data (flags raw) (value %m))",
+ nbits, padding, data, n_data, &sdata);
+ if (rv != CKR_OK)
+ return rv;
+
+ /* Do the magic */
+ gcry = gcry_pk_sign (&ssig, sdata, sexp);
+ gcry_sexp_release (sdata);
+
+ /* TODO: Certain codes should be returned (data too big etc... ) */
+ if (gcry) {
+ g_message ("signing of the data failed: %s", gcry_strerror (gcry));
+ return CKR_FUNCTION_FAILED;
+ }
+
+ /* Now extract and send it back out */
+ rv = gck_crypto_sexp_to_data (ssig, nbits, signature, n_signature, NULL, "rsa", "s", NULL);
+ gcry_sexp_release (ssig);
+
+ return rv;
+}
+
+CK_RV
+gck_mechanism_rsa_verify (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data,
+ CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
+{
+ gcry_sexp_t ssig, sdata;
+ gcry_error_t gcry;
+ guint nbits;
+ CK_RV rv;
+
+ g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
+
+ /* The key size */
+ nbits = gcry_pk_get_nbits (sexp);
+ g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
+
+ if (n_signature != (nbits + 7) / 8)
+ return CKR_SIGNATURE_LEN_RANGE;
+
+ /* Prepare the input s expressions */
+ rv = gck_crypto_data_to_sexp ("(data (flags raw) (value %m))",
+ nbits, padding, data, n_data, &sdata);
+ if (rv != CKR_OK)
+ return rv;
+
+ rv = gck_crypto_data_to_sexp ("(sig-val (rsa (s %m)))",
+ nbits, NULL, signature, n_signature, &ssig);
+ if (rv != CKR_OK) {
+ gcry_sexp_release (sdata);
+ return rv;
+ }
+
+ /* Do the magic */
+ gcry = gcry_pk_verify (ssig, sdata, sexp);
+ gcry_sexp_release (sdata);
+ gcry_sexp_release (ssig);
+
+ /* TODO: See if any other codes should be mapped */
+ if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
+ return CKR_SIGNATURE_INVALID;
+ } else if (gcry) {
+ g_message ("signing of the data failed: %s", gcry_strerror (gcry));
+ return CKR_FUNCTION_FAILED;
+ }
+
+ return CKR_OK;
+}
+
+/* ----------------------------------------------------------------------------
+ * PADDING FUNCTIONS
+ */
+
+
+guchar*
+gck_mechanism_rsa_pad_raw (guint n_modulus, const guchar* raw,
+ gsize n_raw, gsize *n_padded)
+{
+ gint total, n_pad;
+ guchar *padded;
+
+ /*
+ * 0x00 0x00 0x00 ... 0x?? 0x?? 0x?? ...
+ * padding data
+ */
+
+ total = (n_modulus + 7) / 8;
+ n_pad = total - n_raw;
+ if (n_pad < 0) /* minumum padding */
+ return NULL;
+
+ padded = g_new0 (guchar, total);
+ memset (padded, 0x00, n_pad);
+ memcpy (padded + n_pad, raw, n_raw);
+
+ *n_padded = total;
+ return padded;
+}
+
+guchar*
+gck_mechanism_rsa_pad_one (guint n_modulus, const guchar* raw,
+ gsize n_raw, gsize *n_padded)
+{
+ gint total, n_pad;
+ guchar *padded;
+
+ /*
+ * 0x00 0x01 0xFF 0xFF ... 0x00 0x?? 0x?? 0x?? ...
+ * type padding data
+ */
+
+ total = (n_modulus + 7) / 8;
+ n_pad = total - 3 - n_raw;
+ if (n_pad < 8) /* minumum padding */
+ return NULL;
+
+ padded = g_new0 (guchar, total);
+ padded[1] = 1; /* Block type */
+ memset (padded + 2, 0xff, n_pad);
+ memcpy (padded + 3 + n_pad, raw, n_raw);
+
+ *n_padded = total;
+ return padded;
+}
+
+guchar*
+gck_mechanism_rsa_pad_two (guint n_modulus, const guchar* raw,
+ gsize n_raw, gsize *n_padded)
+{
+ gint total, n_pad;
+ guchar *padded;
+
+ /*
+ * 0x00 0x01 0x?? 0x?? ... 0x00 0x?? 0x?? 0x?? ...
+ * type padding data
+ */
+
+ total = (n_modulus + 7) / 8;
+ n_pad = total - 3 - n_raw;
+ if (n_pad < 8) /* minumum padding */
+ return NULL;
+
+ padded = g_new0 (guchar, total);
+ padded[1] = 2; /* Block type */
+ fill_random_nonzero (padded + 2, n_pad);
+ memcpy (padded + 3 + n_pad, raw, n_raw);
+
+ *n_padded = total;
+ return padded;
+}
+
+guchar*
+gck_mechanism_rsa_unpad_one (guint bits, const guchar *padded,
+ gsize n_padded, gsize *n_raw)
+{
+ return unpad_rsa_pkcs1 (0x01, bits, padded, n_padded, n_raw);
+}
+
+guchar*
+gck_mechanism_rsa_unpad_two (guint bits, const guchar *padded,
+ gsize n_padded, gsize *n_raw)
+{
+ return unpad_rsa_pkcs1 (0x02, bits, padded, n_padded, n_raw);
+}
diff --git a/pkcs11/gck/gck-mechanism-rsa.h b/pkcs11/gck/gck-mechanism-rsa.h
new file mode 100644
index 0000000..b263a57
--- /dev/null
+++ b/pkcs11/gck/gck-mechanism-rsa.h
@@ -0,0 +1,92 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef GCK_MECHANISM_RSA_H_
+#define GCK_MECHANISM_RSA_H_
+
+#include "gck-crypto.h"
+#include "gck-types.h"
+
+#include "pkcs11/pkcs11.h"
+
+#include <glib.h>
+
+#include <gcrypt.h>
+
+static const CK_MECHANISM_TYPE GCK_CRYPTO_RSA_MECHANISMS[] = {
+ CKM_RSA_PKCS,
+ CKM_RSA_X_509
+};
+
+CK_RV gck_mechanism_rsa_encrypt (gcry_sexp_t sexp,
+ GckCryptoPadding padding,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR encrypted,
+ CK_ULONG_PTR n_encrypted);
+
+CK_RV gck_mechanism_rsa_decrypt (gcry_sexp_t sexp,
+ GckCryptoPadding padding,
+ CK_BYTE_PTR encrypted,
+ CK_ULONG n_encrypted,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR n_data);
+
+CK_RV gck_mechanism_rsa_sign (gcry_sexp_t sexp,
+ GckCryptoPadding padding,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR n_signature);
+
+CK_RV gck_mechanism_rsa_verify (gcry_sexp_t sexp,
+ GckCryptoPadding padding,
+ CK_BYTE_PTR data,
+ CK_ULONG n_data,
+ CK_BYTE_PTR signature,
+ CK_ULONG n_signature);
+
+guchar* gck_mechanism_rsa_pad_raw (guint bits,
+ const guchar* raw,
+ gsize n_raw,
+ gsize *n_padded);
+
+guchar* gck_mechanism_rsa_pad_one (guint bits,
+ const guchar* raw,
+ gsize n_raw,
+ gsize *n_padded);
+
+guchar* gck_mechanism_rsa_pad_two (guint bits,
+ const guchar* raw,
+ gsize n_raw,
+ gsize *n_padded);
+
+guchar* gck_mechanism_rsa_unpad_one (guint bits,
+ const guchar *padded,
+ gsize n_padded,
+ gsize *n_raw);
+
+guchar* gck_mechanism_rsa_unpad_two (guint bits,
+ const guchar* padded,
+ gsize n_padded,
+ gsize *n_raw);
+
+#endif /* GCK_MECHANISM_RSA_H_ */
diff --git a/pkcs11/gck/gck-private-xsa-key.c b/pkcs11/gck/gck-private-xsa-key.c
index fa310ad..7b86b85 100644
--- a/pkcs11/gck/gck-private-xsa-key.c
+++ b/pkcs11/gck/gck-private-xsa-key.c
@@ -35,7 +35,7 @@ struct _GckPrivateXsaKeyPrivate {
GckSexp *sexp;
};
-G_DEFINE_TYPE (GckPrivateXsaKey, gck_private_xsa_key, GCK_TYPE_KEY);
+G_DEFINE_TYPE (GckPrivateXsaKey, gck_private_xsa_key, GCK_TYPE_SEXP_KEY);
/* -----------------------------------------------------------------------------
* INTERNAL
@@ -201,6 +201,7 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
{
GckPrivateXsaKey *self = GCK_PRIVATE_XSA_KEY (base);
gboolean have;
+ gint algorithm;
switch (attr->type) {
case CKA_CLASS:
@@ -213,7 +214,8 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
return gck_attribute_set_bool (attr, TRUE);
case CKA_DECRYPT:
- return gck_attribute_set_bool (attr, gck_key_get_algorithm (GCK_KEY (self)) == GCRY_PK_RSA);
+ algorithm = gck_sexp_key_get_algorithm (GCK_SEXP_KEY (self));
+ return gck_attribute_set_bool (attr, algorithm == GCRY_PK_RSA);
case CKA_SIGN:
return gck_attribute_set_bool (attr, TRUE);
@@ -246,10 +248,10 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
return gck_attribute_set_bool (attr, !have);
case CKA_MODULUS:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_RSA, "n", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_RSA, "n", attr);
case CKA_PUBLIC_EXPONENT:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_RSA, "e", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_RSA, "e", attr);
/* RSA private key parts */
case CKA_PRIVATE_EXPONENT:
@@ -261,13 +263,13 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
return CKR_ATTRIBUTE_SENSITIVE;
case CKA_PRIME:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "p", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "p", attr);
case CKA_SUBPRIME:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "q", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "q", attr);
case CKA_BASE:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "g", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "g", attr);
/* DSA private parts */
case CKA_VALUE:
@@ -278,7 +280,7 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
}
static GckSexp*
-gck_private_xsa_key_real_acquire_crypto_sexp (GckKey *base, GckSession *session)
+gck_private_xsa_key_real_acquire_crypto_sexp (GckSexpKey *base, GckSession *session)
{
GckPrivateXsaKey *self = GCK_PRIVATE_XSA_KEY (base);
GckSexp *sexp = NULL;
@@ -328,7 +330,7 @@ gck_private_xsa_key_class_init (GckPrivateXsaKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
- GckKeyClass *key_class = GCK_KEY_CLASS (klass);
+ GckSexpKeyClass *key_class = GCK_SEXP_KEY_CLASS (klass);
gck_private_xsa_key_parent_class = g_type_class_peek_parent (klass);
g_type_class_add_private (klass, sizeof (GckPrivateXsaKeyPrivate));
diff --git a/pkcs11/gck/gck-private-xsa-key.h b/pkcs11/gck/gck-private-xsa-key.h
index ddc2823..1a5dbde 100644
--- a/pkcs11/gck/gck-private-xsa-key.h
+++ b/pkcs11/gck/gck-private-xsa-key.h
@@ -24,7 +24,7 @@
#include <glib-object.h>
-#include "gck-key.h"
+#include "gck-sexp-key.h"
#include "gck-types.h"
#define GCK_FACTORY_PRIVATE_XSA_KEY (gck_private_xsa_key_get_factory ())
@@ -40,12 +40,12 @@ typedef struct _GckPrivateXsaKeyClass GckPrivateXsaKeyClass;
typedef struct _GckPrivateXsaKeyPrivate GckPrivateXsaKeyPrivate;
struct _GckPrivateXsaKey {
- GckKey parent;
+ GckSexpKey parent;
GckPrivateXsaKeyPrivate *pv;
};
struct _GckPrivateXsaKeyClass {
- GckKeyClass parent_class;
+ GckSexpKeyClass parent_class;
};
GType gck_private_xsa_key_get_type (void);
diff --git a/pkcs11/gck/gck-public-xsa-key.c b/pkcs11/gck/gck-public-xsa-key.c
index 5cdd093..5ab32bf 100644
--- a/pkcs11/gck/gck-public-xsa-key.c
+++ b/pkcs11/gck/gck-public-xsa-key.c
@@ -24,14 +24,14 @@
#include "pkcs11/pkcs11.h"
#include "gck-attributes.h"
-#include "gck-crypto.h"
#include "gck-factory.h"
#include "gck-public-xsa-key.h"
#include "gck-session.h"
+#include "gck-sexp.h"
#include "gck-transaction.h"
#include "gck-util.h"
-G_DEFINE_TYPE (GckPublicXsaKey, gck_public_xsa_key, GCK_TYPE_KEY);
+G_DEFINE_TYPE (GckPublicXsaKey, gck_public_xsa_key, GCK_TYPE_SEXP_KEY);
/* -----------------------------------------------------------------------------
* INTERNAL
@@ -45,8 +45,8 @@ return_modulus_bits (GckPublicXsaKey *self, CK_ATTRIBUTE_PTR attr)
int algorithm;
CK_RV rv;
- if (!gck_crypto_sexp_parse_key (gck_sexp_get (gck_key_get_base_sexp (GCK_KEY (self))),
- &algorithm, NULL, &numbers))
+ if (!gck_sexp_parse_key (gck_sexp_get (gck_sexp_key_get_base (GCK_SEXP_KEY (self))),
+ &algorithm, NULL, &numbers))
g_return_val_if_reached (CKR_GENERAL_ERROR);
if (algorithm != GCRY_PK_RSA) {
@@ -55,7 +55,7 @@ return_modulus_bits (GckPublicXsaKey *self, CK_ATTRIBUTE_PTR attr)
}
g_assert (numbers);
- if (!gck_crypto_sexp_extract_mpi (numbers, &mpi, "n", NULL))
+ if (!gck_sexp_extract_mpi (numbers, &mpi, "n", NULL))
g_return_val_if_reached (CKR_GENERAL_ERROR);
gcry_sexp_release (numbers);
@@ -166,6 +166,7 @@ static CK_RV
gck_public_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
{
GckPublicXsaKey *self = GCK_PUBLIC_XSA_KEY (base);
+ gint algorithm;
switch (attr->type)
{
@@ -174,7 +175,8 @@ gck_public_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK_
return gck_attribute_set_ulong (attr, CKO_PUBLIC_KEY);
case CKA_ENCRYPT:
- return gck_attribute_set_bool (attr, gck_key_get_algorithm (GCK_KEY (self)) == GCRY_PK_RSA);
+ algorithm = gck_sexp_key_get_algorithm (GCK_SEXP_KEY (self));
+ return gck_attribute_set_bool (attr, algorithm == GCRY_PK_RSA);
case CKA_VERIFY:
return gck_attribute_set_bool (attr, TRUE);
@@ -195,34 +197,34 @@ gck_public_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK_
return return_modulus_bits (self, attr);
case CKA_MODULUS:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_RSA, "n", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_RSA, "n", attr);
case CKA_PUBLIC_EXPONENT:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_RSA, "e", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_RSA, "e", attr);
case CKA_PRIME:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "p", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "p", attr);
case CKA_SUBPRIME:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "q", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "q", attr);
case CKA_BASE:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "g", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "g", attr);
/* DSA public value */
case CKA_VALUE:
- return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "y", attr);
+ return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "y", attr);
};
return GCK_OBJECT_CLASS (gck_public_xsa_key_parent_class)->get_attribute (base, session, attr);
}
static GckSexp*
-gck_public_xsa_key_acquire_crypto_sexp (GckKey *self, GckSession *session)
+gck_public_xsa_key_acquire_crypto_sexp (GckSexpKey *self, GckSession *session)
{
GckSexp* sexp;
- sexp = gck_key_get_base_sexp (self);
+ sexp = gck_sexp_key_get_base (self);
if (sexp != NULL)
gck_sexp_ref (sexp);
@@ -239,7 +241,7 @@ static void
gck_public_xsa_key_class_init (GckPublicXsaKeyClass *klass)
{
GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
- GckKeyClass *key_class = GCK_KEY_CLASS (klass);
+ GckSexpKeyClass *key_class = GCK_SEXP_KEY_CLASS (klass);
gck_public_xsa_key_parent_class = g_type_class_peek_parent (klass);
diff --git a/pkcs11/gck/gck-public-xsa-key.h b/pkcs11/gck/gck-public-xsa-key.h
index 5cfd99a..d5f08f0 100644
--- a/pkcs11/gck/gck-public-xsa-key.h
+++ b/pkcs11/gck/gck-public-xsa-key.h
@@ -24,7 +24,7 @@
#include <glib-object.h>
-#include "gck-key.h"
+#include "gck-sexp-key.h"
#include "gck-types.h"
#define GCK_FACTORY_PUBLIC_XSA_KEY (gck_public_xsa_key_get_factory ())
@@ -40,12 +40,12 @@ typedef struct _GckPublicXsaKeyClass GckPublicXsaKeyClass;
typedef struct _GckPublicXsaKeyPrivate GckPublicXsaKeyPrivate;
struct _GckPublicXsaKey {
- GckKey parent;
+ GckSexpKey parent;
GckPublicXsaKeyPrivate *pv;
};
struct _GckPublicXsaKeyClass {
- GckKeyClass parent_class;
+ GckSexpKeyClass parent_class;
};
GType gck_public_xsa_key_get_type (void);
diff --git a/pkcs11/gck/gck-session.c b/pkcs11/gck/gck-session.c
index 906b6ca..44c9175 100644
--- a/pkcs11/gck/gck-session.c
+++ b/pkcs11/gck/gck-session.c
@@ -27,12 +27,12 @@
#include "gck-attributes.h"
#include "gck-credential.h"
#include "gck-crypto.h"
-#include "gck-key.h"
#include "gck-factory.h"
#include "gck-manager.h"
#include "gck-memory-store.h"
#include "gck-session.h"
#include "gck-sexp.h"
+#include "gck-sexp-key.h"
#include "gck-transaction.h"
#include "gck-util.h"
@@ -73,9 +73,10 @@ struct _GckSessionPrivate {
/* Used for find operations */
GArray *found_objects;
-
+
/* Used for crypto operations */
- GckSexp *crypto_sexp;
+ gpointer crypto_state;
+ GDestroyNotify crypto_destroy;
CK_MECHANISM_TYPE crypto_mechanism;
CK_ATTRIBUTE_TYPE crypto_method;
};
@@ -94,15 +95,14 @@ cleanup_crypto (GckSession *self)
{
g_assert (self->pv->current_operation == cleanup_crypto);
- if (self->pv->crypto_sexp) {
- gck_sexp_unref (self->pv->crypto_sexp);
- self->pv->crypto_sexp = NULL;
- }
-
+ if (self->pv->crypto_state && self->pv->crypto_destroy)
+ (self->pv->crypto_destroy) (self->pv->crypto_state);
+ self->pv->crypto_state = NULL;
+ self->pv->crypto_destroy = NULL;
self->pv->crypto_mechanism = 0;
self->pv->crypto_method = 0;
- g_assert (GCK_IS_KEY (self->pv->current_object));
+ g_assert (GCK_IS_OBJECT (self->pv->current_object));
if (self->pv->current_object)
g_object_unref (self->pv->current_object);
self->pv->current_object = NULL;
@@ -134,15 +134,15 @@ prepare_crypto (GckSession *self, CK_MECHANISM_PTR mech,
(self->pv->current_operation) (self);
g_assert (!self->pv->current_operation);
}
-
- g_assert (!self->pv->crypto_sexp);
-
+
+ g_assert (!self->pv->crypto_state);
+
/* First find the object */
rv = gck_session_lookup_readable_object (self, handle, &object);
if (rv != CKR_OK)
return rv;
-
- if (!GCK_IS_KEY (object))
+
+ if (!GCK_IS_OBJECT (object))
return CKR_KEY_HANDLE_INVALID;
/* Lookup the mechanisms this object can do */
@@ -197,18 +197,16 @@ process_crypto (GckSession *self, CK_ATTRIBUTE_TYPE method, CK_BYTE_PTR bufone,
if (rv == CKR_OK) {
/* Load up the actual sexp we're going to use */
- if (!self->pv->crypto_sexp) {
- g_return_val_if_fail (GCK_IS_KEY (self->pv->current_object), CKR_GENERAL_ERROR);
- self->pv->crypto_sexp = gck_key_acquire_crypto_sexp (GCK_KEY (self->pv->current_object), self);
- if (!self->pv->crypto_sexp)
- rv = CKR_USER_NOT_LOGGED_IN;
+ if (!self->pv->crypto_state) {
+ g_return_val_if_fail (GCK_IS_OBJECT (self->pv->current_object), CKR_GENERAL_ERROR);
+ rv = gck_crypto_prepare (self, self->pv->crypto_mechanism, self->pv->current_object);
}
}
if (rv == CKR_OK) {
g_assert (self->pv->crypto_mechanism);
- rv = gck_crypto_perform (gck_sexp_get (self->pv->crypto_sexp), self->pv->crypto_mechanism,
- method, bufone, n_bufone, buftwo, n_buftwo);
+ rv = gck_crypto_perform (self, self->pv->crypto_mechanism, method,
+ bufone, n_bufone, buftwo, n_buftwo);
}
/* Under these conditions the operation isn't complete */
@@ -639,6 +637,26 @@ gck_session_set_logged_in (GckSession *self, gulong logged_in)
g_object_notify (G_OBJECT (self), "logged-in");
}
+gpointer
+gck_session_get_crypto_state (GckSession *self)
+{
+ g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
+ return self->pv->crypto_state;
+}
+
+void
+gck_session_set_crypto_state (GckSession *self, gpointer state,
+ GDestroyNotify destroy)
+{
+ g_return_if_fail (GCK_IS_SESSION (self));
+ if (self->pv->crypto_state != state) {
+ if (self->pv->crypto_state && self->pv->crypto_destroy)
+ (self->pv->crypto_destroy) (self->pv->crypto_state);
+ }
+ self->pv->crypto_state = state;
+ self->pv->crypto_destroy = destroy;
+}
+
gboolean
gck_session_get_read_only (GckSession *self)
{
diff --git a/pkcs11/gck/gck-session.h b/pkcs11/gck/gck-session.h
index 62124c8..6afb563 100644
--- a/pkcs11/gck/gck-session.h
+++ b/pkcs11/gck/gck-session.h
@@ -79,6 +79,12 @@ gulong gck_session_get_logged_in (GckSess
void gck_session_set_logged_in (GckSession *self,
gulong logged_in);
+gpointer gck_session_get_crypto_state (GckSession *self);
+
+void gck_session_set_crypto_state (GckSession *self,
+ gpointer state,
+ GDestroyNotify destroy);
+
CK_RV gck_session_lookup_readable_object (GckSession *self,
CK_OBJECT_HANDLE handle,
GckObject **result);
diff --git a/pkcs11/gck/gck-key.c b/pkcs11/gck/gck-sexp-key.c
similarity index 56%
rename from pkcs11/gck/gck-key.c
rename to pkcs11/gck/gck-sexp-key.c
index 134fc7e..e899a42 100644
--- a/pkcs11/gck/gck-key.c
+++ b/pkcs11/gck/gck-sexp-key.c
@@ -1,22 +1,22 @@
-/*
+/*
* gnome-keyring
- *
+ *
* Copyright (C) 2008 Stefan Walter
- *
- * This program is free software; you can redistribute it and/or modify
+ *
+ * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General License for more details.
- *
- * You should have received a copy of the GNU Lesser General
+ *
+ * You should have received a copy of the GNU Lesser General
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
#include "config.h"
@@ -24,8 +24,9 @@
#include "pkcs11/pkcs11.h"
#include "gck-attributes.h"
-#include "gck-crypto.h"
-#include "gck-key.h"
+#include "gck-mechanism-dsa.h"
+#include "gck-mechanism-rsa.h"
+#include "gck-sexp-key.h"
#include "gck-util.h"
enum {
@@ -34,29 +35,29 @@ enum {
PROP_ALGORITHM
};
-struct _GckKeyPrivate {
+struct _GckSexpKeyPrivate {
GckSexp *base_sexp;
};
-G_DEFINE_TYPE (GckKey, gck_key, GCK_TYPE_OBJECT);
+G_DEFINE_TYPE (GckSexpKey, gck_sexp_key, GCK_TYPE_OBJECT);
/* -----------------------------------------------------------------------------
- * INTERNAL
+ * INTERNAL
*/
/* -----------------------------------------------------------------------------
- * KEY
+ * KEY
*/
-static CK_RV
-gck_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
+static CK_RV
+gck_sexp_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
{
- GckKey *self = GCK_KEY (base);
-
+ GckSexpKey *self = GCK_SEXP_KEY (base);
+
switch (attr->type) {
case CKA_KEY_TYPE:
{
- switch (gck_key_get_algorithm (self)) {
+ switch (gck_sexp_key_get_algorithm (self)) {
case GCRY_PK_RSA:
return gck_attribute_set_ulong (attr, CKK_RSA);
case GCRY_PK_DSA:
@@ -66,7 +67,7 @@ gck_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE*
};
}
break;
-
+
case CKA_ID:
{
guchar hash[20];
@@ -76,89 +77,68 @@ gck_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE*
return gck_attribute_set_data (attr, hash, sizeof (hash));
}
break;
-
+
case CKA_START_DATE:
case CKA_END_DATE:
return gck_attribute_set_data (attr, "", 0);
-
+
case CKA_DERIVE:
return gck_attribute_set_bool (attr, FALSE);
-
+
case CKA_LOCAL:
return gck_attribute_set_bool (attr, FALSE);
-
+
case CKA_KEY_GEN_MECHANISM:
return gck_attribute_set_ulong (attr, CK_UNAVAILABLE_INFORMATION);
-
+
case CKA_ALLOWED_MECHANISMS:
- switch (gck_key_get_algorithm (self)) {
+ switch (gck_sexp_key_get_algorithm (self)) {
case GCRY_PK_RSA:
- return gck_attribute_set_data (attr, (CK_VOID_PTR)GCK_CRYPTO_RSA_MECHANISMS,
- sizeof (GCK_CRYPTO_RSA_MECHANISMS));
+ return gck_attribute_set_data (attr, (CK_VOID_PTR)GCK_CRYPTO_RSA_MECHANISMS,
+ sizeof (GCK_CRYPTO_RSA_MECHANISMS));
case GCRY_PK_DSA:
- return gck_attribute_set_data (attr, (CK_VOID_PTR)GCK_CRYPTO_DSA_MECHANISMS,
- sizeof (GCK_CRYPTO_DSA_MECHANISMS));
+ return gck_attribute_set_data (attr, (CK_VOID_PTR)GCK_CRYPTO_DSA_MECHANISMS,
+ sizeof (GCK_CRYPTO_DSA_MECHANISMS));
default:
g_return_val_if_reached (CKR_GENERAL_ERROR);
};
-
+
/* Lookup the certificate subject */
case CKA_SUBJECT:
/* TODO: When we have certificates, implement this */
return gck_attribute_set_data (attr, "", 0);
};
- return GCK_OBJECT_CLASS (gck_key_parent_class)->get_attribute (base, session, attr);
-}
-
-static GObject*
-gck_key_constructor (GType type, guint n_props, GObjectConstructParam *props)
-{
- GckKey *self = GCK_KEY (G_OBJECT_CLASS (gck_key_parent_class)->constructor(type, n_props, props));
- g_return_val_if_fail (self, NULL);
-
-
- return G_OBJECT (self);
+ return GCK_OBJECT_CLASS (gck_sexp_key_parent_class)->get_attribute (base, session, attr);
}
static void
-gck_key_init (GckKey *self)
+gck_sexp_key_init (GckSexpKey *self)
{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_KEY, GckKeyPrivate);
-
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_SEXP_KEY, GckSexpKeyPrivate);
}
static void
-gck_key_dispose (GObject *obj)
+gck_sexp_key_finalize (GObject *obj)
{
-#if 0
- GckKey *self = GCK_KEY (obj);
-#endif
-
- G_OBJECT_CLASS (gck_key_parent_class)->dispose (obj);
-}
+ GckSexpKey *self = GCK_SEXP_KEY (obj);
-static void
-gck_key_finalize (GObject *obj)
-{
- GckKey *self = GCK_KEY (obj);
-
if (self->pv->base_sexp)
gck_sexp_unref (self->pv->base_sexp);
self->pv->base_sexp = NULL;
- G_OBJECT_CLASS (gck_key_parent_class)->finalize (obj);
+ G_OBJECT_CLASS (gck_sexp_key_parent_class)->finalize (obj);
}
static void
-gck_key_set_property (GObject *obj, guint prop_id, const GValue *value,
+gck_sexp_key_set_property (GObject *obj, guint prop_id, const GValue *value,
GParamSpec *pspec)
{
- GckKey *self = GCK_KEY (obj);
-
+ GckSexpKey *self = GCK_SEXP_KEY (obj);
+
switch (prop_id) {
case PROP_BASE_SEXP:
- gck_key_set_base_sexp (self, g_value_get_boxed (value));
+ gck_sexp_key_set_base (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -167,17 +147,17 @@ gck_key_set_property (GObject *obj, guint prop_id, const GValue *value,
}
static void
-gck_key_get_property (GObject *obj, guint prop_id, GValue *value,
+gck_sexp_key_get_property (GObject *obj, guint prop_id, GValue *value,
GParamSpec *pspec)
{
- GckKey *self = GCK_KEY (obj);
-
+ GckSexpKey *self = GCK_SEXP_KEY (obj);
+
switch (prop_id) {
case PROP_BASE_SEXP:
- g_value_set_boxed (value, gck_key_get_base_sexp (self));
+ g_value_set_boxed (value, gck_sexp_key_get_base (self));
break;
case PROP_ALGORITHM:
- g_value_set_int (value, gck_key_get_algorithm (self));
+ g_value_set_int (value, gck_sexp_key_get_algorithm (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -186,36 +166,27 @@ gck_key_get_property (GObject *obj, guint prop_id, GValue *value,
}
static void
-gck_key_class_init (GckKeyClass *klass)
+gck_sexp_key_class_init (GckSexpKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
-
- gck_key_parent_class = g_type_class_peek_parent (klass);
- g_type_class_add_private (klass, sizeof (GckKeyPrivate));
-
- gobject_class->constructor = gck_key_constructor;
- gobject_class->dispose = gck_key_dispose;
- gobject_class->finalize = gck_key_finalize;
- gobject_class->set_property = gck_key_set_property;
- gobject_class->get_property = gck_key_get_property;
-
- gck_class->get_attribute = gck_key_real_get_attribute;
-
+
+ gck_sexp_key_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GckSexpKeyPrivate));
+
+ gobject_class->finalize = gck_sexp_key_finalize;
+ gobject_class->set_property = gck_sexp_key_set_property;
+ gobject_class->get_property = gck_sexp_key_get_property;
+
+ gck_class->get_attribute = gck_sexp_key_real_get_attribute;
+
g_object_class_install_property (gobject_class, PROP_BASE_SEXP,
- g_param_spec_boxed ("base-sexp", "Base S-Exp", "Base Key S-Expression",
+ g_param_spec_boxed ("base-sexp", "Base S-Exp", "Base Key S-Expression",
GCK_BOXED_SEXP, G_PARAM_READWRITE));
-
+
g_object_class_install_property (gobject_class, PROP_ALGORITHM,
- g_param_spec_int ("algorithm", "Algorithm", "GCrypt Algorithm",
+ g_param_spec_int ("algorithm", "Algorithm", "GCrypt Algorithm",
0, G_MAXINT, 0, G_PARAM_READABLE));
-
-#if 0
- signals[SIGNAL] = g_signal_new ("signal", GCK_TYPE_KEY,
- G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GckKeyClass, signal),
- NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 0);
-#endif
}
/* -----------------------------------------------------------------------------
@@ -223,16 +194,16 @@ gck_key_class_init (GckKeyClass *klass)
*/
GckSexp*
-gck_key_get_base_sexp (GckKey *self)
+gck_sexp_key_get_base (GckSexpKey *self)
{
- g_return_val_if_fail (GCK_IS_KEY (self), NULL);
+ g_return_val_if_fail (GCK_IS_SEXP_KEY (self), NULL);
return self->pv->base_sexp;
}
void
-gck_key_set_base_sexp (GckKey *self, GckSexp *sexp)
+gck_sexp_key_set_base (GckSexpKey *self, GckSexp *sexp)
{
- g_return_if_fail (GCK_IS_KEY (self));
+ g_return_if_fail (GCK_IS_SEXP_KEY (self));
if (sexp)
gck_sexp_ref (sexp);
if (self->pv->base_sexp)
@@ -243,50 +214,48 @@ gck_key_set_base_sexp (GckKey *self, GckSexp *sexp)
}
int
-gck_key_get_algorithm (GckKey *self)
+gck_sexp_key_get_algorithm (GckSexpKey *self)
{
int algorithm;
g_return_val_if_fail (self->pv->base_sexp, 0);
- if (!gck_crypto_sexp_parse_key (gck_sexp_get (self->pv->base_sexp), &algorithm, NULL, NULL))
+ if (!gck_sexp_parse_key (gck_sexp_get (self->pv->base_sexp), &algorithm, NULL, NULL))
g_return_val_if_reached (0);
return algorithm;
}
CK_RV
-gck_key_set_key_part (GckKey *self, int algo, const char *part,
- CK_ATTRIBUTE_PTR attr)
+gck_sexp_key_set_part (GckSexpKey *self, int algo, const char *part, CK_ATTRIBUTE_PTR attr)
{
gcry_sexp_t numbers;
gcry_mpi_t mpi;
int algorithm;
CK_RV rv;
-
- g_return_val_if_fail (GCK_IS_KEY (self), CKR_GENERAL_ERROR);
+
+ g_return_val_if_fail (GCK_IS_SEXP_KEY (self), CKR_GENERAL_ERROR);
g_return_val_if_fail (self->pv->base_sexp, CKR_GENERAL_ERROR);
-
- if (!gck_crypto_sexp_parse_key (gck_sexp_get (self->pv->base_sexp),
+
+ if (!gck_sexp_parse_key (gck_sexp_get (self->pv->base_sexp),
&algorithm, NULL, &numbers))
g_return_val_if_reached (CKR_GENERAL_ERROR);
-
+
if (algorithm != algo) {
gcry_sexp_release (numbers);
return CKR_ATTRIBUTE_TYPE_INVALID;
}
-
- if (!gck_crypto_sexp_extract_mpi (numbers, &mpi, part, NULL))
+
+ if (!gck_sexp_extract_mpi (numbers, &mpi, part, NULL))
g_return_val_if_reached (CKR_GENERAL_ERROR);
rv = gck_attribute_set_mpi (attr, mpi);
gcry_sexp_release (numbers);
gcry_mpi_release (mpi);
-
+
return rv;
}
GckSexp*
-gck_key_acquire_crypto_sexp (GckKey *self, GckSession *session)
+gck_sexp_key_acquire_crypto_sexp (GckSexpKey *self, GckSession *session)
{
- g_return_val_if_fail (GCK_IS_KEY (self), NULL);
- g_return_val_if_fail (GCK_KEY_GET_CLASS (self)->acquire_crypto_sexp, NULL);
- return GCK_KEY_GET_CLASS (self)->acquire_crypto_sexp (self, session);
+ g_return_val_if_fail (GCK_IS_SEXP_KEY (self), NULL);
+ g_return_val_if_fail (GCK_SEXP_KEY_GET_CLASS (self)->acquire_crypto_sexp, NULL);
+ return GCK_SEXP_KEY_GET_CLASS (self)->acquire_crypto_sexp (self, session);
}
-
diff --git a/pkcs11/gck/gck-sexp-key.h b/pkcs11/gck/gck-sexp-key.h
new file mode 100644
index 0000000..05160e4
--- /dev/null
+++ b/pkcs11/gck/gck-sexp-key.h
@@ -0,0 +1,71 @@
+/*
+ * gnome-sexp_keyring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __GCK_SEXP_KEY_H__
+#define __GCK_SEXP_KEY_H__
+
+#include <glib-object.h>
+
+#include "gck-sexp.h"
+#include "gck-object.h"
+#include "gck-types.h"
+
+#define GCK_TYPE_SEXP_KEY (gck_sexp_key_get_type ())
+#define GCK_SEXP_KEY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCK_TYPE_SEXP_KEY, GckSexpKey))
+#define GCK_SEXP_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCK_TYPE_SEXP_KEY, GckSexpKeyClass))
+#define GCK_IS_SEXP_KEY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCK_TYPE_SEXP_KEY))
+#define GCK_IS_SEXP_KEY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCK_TYPE_SEXP_KEY))
+#define GCK_SEXP_KEY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCK_TYPE_SEXP_KEY, GckSexpKeyClass))
+
+typedef struct _GckSexpKeyClass GckSexpKeyClass;
+typedef struct _GckSexpKeyPrivate GckSexpKeyPrivate;
+
+struct _GckSexpKey {
+ GckObject parent;
+ GckSexpKeyPrivate *pv;
+};
+
+struct _GckSexpKeyClass {
+ GckObjectClass parent_class;
+
+ /* virtual methods */
+
+ GckSexp* (*acquire_crypto_sexp) (GckSexpKey *self, GckSession *session);
+};
+
+GType gck_sexp_key_get_type (void);
+
+GckSexp* gck_sexp_key_get_base (GckSexpKey *self);
+
+void gck_sexp_key_set_base (GckSexpKey *self,
+ GckSexp *sexp);
+
+int gck_sexp_key_get_algorithm (GckSexpKey *self);
+
+CK_RV gck_sexp_key_set_part (GckSexpKey *self,
+ int algorithm,
+ const char *part,
+ CK_ATTRIBUTE_PTR attr);
+
+GckSexp* gck_sexp_key_acquire_crypto_sexp (GckSexpKey *self,
+ GckSession *session);
+
+#endif /* __GCK_SEXP_KEY_H__ */
diff --git a/pkcs11/gck/gck-sexp.c b/pkcs11/gck/gck-sexp.c
index a15549d..a8d8ae0 100644
--- a/pkcs11/gck/gck-sexp.c
+++ b/pkcs11/gck/gck-sexp.c
@@ -77,3 +77,206 @@ gck_sexp_boxed_type (void)
(GBoxedFreeFunc)gck_sexp_unref);
return type;
}
+
+#define PUBLIC_KEY "public-key"
+#define PUBLIC_KEY_L 10
+#define PRIVATE_KEY "private-key"
+#define PRIVATE_KEY_L 11
+
+gboolean
+gck_sexp_parse_key (gcry_sexp_t s_key, int *algorithm, gboolean *is_private,
+ gcry_sexp_t *numbers)
+{
+ gboolean ret = FALSE;
+ gcry_sexp_t child = NULL;
+ gchar *str = NULL;
+ const gchar *data;
+ gsize n_data;
+ gboolean priv;
+ int algo;
+
+ data = gcry_sexp_nth_data (s_key, 0, &n_data);
+ if (!data)
+ goto done;
+
+ if (n_data == PUBLIC_KEY_L && strncmp (data, PUBLIC_KEY, PUBLIC_KEY_L) == 0)
+ priv = FALSE;
+ else if (n_data == PRIVATE_KEY_L && strncmp (data, PRIVATE_KEY, PRIVATE_KEY_L) == 0)
+ priv = TRUE;
+ else
+ goto done;
+
+ child = gcry_sexp_nth (s_key, 1);
+ if (!child)
+ goto done;
+
+ data = gcry_sexp_nth_data (child, 0, &n_data);
+ if (!data)
+ goto done;
+
+ str = g_alloca (n_data + 1);
+ memcpy (str, data, n_data);
+ str[n_data] = 0;
+
+ algo = gcry_pk_map_name (str);
+ if (!algo)
+ goto done;
+
+ /* Yay all done */
+ if (algorithm)
+ *algorithm = algo;
+ if (numbers) {
+ *numbers = child;
+ child = NULL;
+ }
+ if (is_private)
+ *is_private = priv;
+
+ ret = TRUE;
+
+done:
+ gcry_sexp_release (child);
+ return ret;
+}
+
+static gcry_sexp_t
+rsa_numbers_to_public (gcry_sexp_t rsa)
+{
+ gcry_sexp_t pubkey = NULL;
+ gcry_mpi_t n, e;
+ gcry_error_t gcry;
+
+ n = e = NULL;
+
+ if (!gck_sexp_extract_mpi (rsa, &n, "n", NULL) ||
+ !gck_sexp_extract_mpi (rsa, &e, "e", NULL))
+ goto done;
+
+ gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (rsa (n %m) (e %m)))",
+ n, e);
+ if (gcry)
+ goto done;
+ g_assert (pubkey);
+
+done:
+ gcry_mpi_release (n);
+ gcry_mpi_release (e);
+
+ return pubkey;
+}
+
+static gcry_sexp_t
+dsa_numbers_to_public (gcry_sexp_t dsa)
+{
+ gcry_mpi_t p, q, g, y;
+ gcry_sexp_t pubkey = NULL;
+ gcry_error_t gcry;
+
+ p = q = g = y = NULL;
+
+ if (!gck_sexp_extract_mpi (dsa, &p, "p", NULL) ||
+ !gck_sexp_extract_mpi (dsa, &q, "q", NULL) ||
+ !gck_sexp_extract_mpi (dsa, &g, "g", NULL) ||
+ !gck_sexp_extract_mpi (dsa, &y, "y", NULL))
+ goto done;
+
+ gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (dsa (p %m) (q %m) (g %m) (y %m)))",
+ p, q, g, y);
+ if (gcry)
+ goto done;
+ g_assert (pubkey);
+
+done:
+ gcry_mpi_release (p);
+ gcry_mpi_release (q);
+ gcry_mpi_release (g);
+ gcry_mpi_release (y);
+
+ return pubkey;
+}
+
+gboolean
+gck_sexp_key_to_public (gcry_sexp_t privkey, gcry_sexp_t *pubkey)
+{
+ gcry_sexp_t numbers;
+ int algorithm;
+
+ if (!gck_sexp_parse_key (privkey, &algorithm, NULL, &numbers))
+ g_return_val_if_reached (FALSE);
+
+ switch (algorithm) {
+ case GCRY_PK_RSA:
+ *pubkey = rsa_numbers_to_public (numbers);
+ break;
+ case GCRY_PK_DSA:
+ *pubkey = dsa_numbers_to_public (numbers);
+ break;
+ default:
+ g_return_val_if_reached (FALSE);
+ }
+
+ gcry_sexp_release (numbers);
+ return *pubkey ? TRUE : FALSE;
+}
+
+gboolean
+gck_sexp_extract_mpi (gcry_sexp_t sexp, gcry_mpi_t *mpi, ...)
+{
+ gcry_sexp_t at = NULL;
+ va_list va;
+
+ g_assert (sexp);
+ g_assert (mpi);
+
+ va_start (va, mpi);
+ at = gck_sexp_get_childv (sexp, va);
+ va_end (va);
+
+ *mpi = NULL;
+ if (at)
+ *mpi = gcry_sexp_nth_mpi (at ? at : sexp, 1, GCRYMPI_FMT_USG);
+ if (at)
+ gcry_sexp_release (at);
+
+ return (*mpi) ? TRUE : FALSE;
+}
+
+gcry_sexp_t
+gck_sexp_get_childv (gcry_sexp_t sexp, va_list va)
+{
+ gcry_sexp_t at = NULL;
+ gcry_sexp_t child;
+ const char *name;
+
+ g_assert (sexp);
+ g_assert (va);
+
+ for(;;) {
+ name = va_arg (va, const char*);
+ if (!name)
+ break;
+
+ child = gcry_sexp_find_token (at ? at : sexp, name, 0);
+ gcry_sexp_release (at);
+ at = child;
+ if (at == NULL)
+ break;
+ }
+
+ va_end (va);
+
+ return at;
+}
+
+void
+gck_sexp_dump (gcry_sexp_t sexp)
+{
+ gsize len;
+ gchar *buf;
+
+ len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = g_malloc (len);
+ gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buf, len);
+ g_printerr ("%s", buf);
+ g_free (buf);
+}
diff --git a/pkcs11/gck/gck-sexp.h b/pkcs11/gck/gck-sexp.h
index e3f9089..1bfd463 100644
--- a/pkcs11/gck/gck-sexp.h
+++ b/pkcs11/gck/gck-sexp.h
@@ -40,4 +40,22 @@ gcry_sexp_t gck_sexp_get (GckSexp *sexp);
GType gck_sexp_boxed_type (void);
-#endif /* GCKSEXPHANDLE_H_ */
+
+gboolean gck_sexp_parse_key (gcry_sexp_t sexp,
+ int *algorithm,
+ gboolean *is_private,
+ gcry_sexp_t *numbers);
+
+gboolean gck_sexp_key_to_public (gcry_sexp_t sexp,
+ gcry_sexp_t *pub);
+
+gboolean gck_sexp_extract_mpi (gcry_sexp_t sexp,
+ gcry_mpi_t *mpi,
+ ...) G_GNUC_NULL_TERMINATED;
+
+gcry_sexp_t gck_sexp_get_childv (gcry_sexp_t sexp,
+ va_list va);
+
+void gck_sexp_dump (gcry_sexp_t sexp);
+
+#endif /* GCKSEXP_H_ */
diff --git a/pkcs11/gck/gck-types.h b/pkcs11/gck/gck-types.h
index 034214b..5ad1c76 100644
--- a/pkcs11/gck/gck-types.h
+++ b/pkcs11/gck/gck-types.h
@@ -26,7 +26,6 @@ typedef struct _GckCertificate GckCertificate;
typedef struct _GckCertificateKey GckCertificateKey;
typedef struct _GckCertificateTrust GckCertificateTrust;
typedef struct _GckCredential GckCredential;
-typedef struct _GckKey GckKey;
typedef struct _GckFactory GckFactory;
typedef struct _GckManager GckManager;
typedef struct _GckModule GckModule;
@@ -38,6 +37,7 @@ typedef struct _GckSession GckSession;
typedef struct _GckSessionPrivateKey GckSessionPrivateKey;
typedef struct _GckSessionPublicKey GckSessionPublicKey;
typedef struct _GckSexp GckSexp;
+typedef struct _GckSexpKey GckSexpKey;
typedef struct _GckStore GckStore;
typedef struct _GckTimer GckTimer;
typedef struct _GckTransaction GckTransaction;
diff --git a/pkcs11/gck/tests/Makefile.am b/pkcs11/gck/tests/Makefile.am
index 1f82931..1a16b2b 100644
--- a/pkcs11/gck/tests/Makefile.am
+++ b/pkcs11/gck/tests/Makefile.am
@@ -5,7 +5,7 @@ asn1-def-test.h: test.asn
# Test files should be listed in order they need to run
UNIT_AUTO = \
unit-test-attributes.c \
- unit-test-crypto.c \
+ unit-test-sexp.c \
unit-test-data-asn1.c \
unit-test-data-der.c \
unit-test-object.c \
diff --git a/pkcs11/gck/tests/unit-test-data-der.c b/pkcs11/gck/tests/unit-test-data-der.c
index 46804f5..412f2cf 100644
--- a/pkcs11/gck/tests/unit-test-data-der.c
+++ b/pkcs11/gck/tests/unit-test-data-der.c
@@ -28,6 +28,7 @@
#include "gck/gck-crypto.h"
#include "gck/gck-data-asn1.h"
#include "gck/gck-data-der.h"
+#include "gck/gck-sexp.h"
#include "egg/egg-openssl.h"
@@ -425,7 +426,7 @@ DEFINE_TEST(read_all_pkcs8)
res = gck_data_der_read_private_pkcs8 (data, n_data, "booo", 4, &sexp);
g_assert (res == GCK_DATA_SUCCESS);
- g_assert (gck_crypto_sexp_parse_key (sexp, NULL, NULL, NULL));
+ g_assert (gck_sexp_parse_key (sexp, NULL, NULL, NULL));
gcry_sexp_release (sexp);
g_free (data);
}
diff --git a/pkcs11/gck/tests/unit-test-crypto.c b/pkcs11/gck/tests/unit-test-sexp.c
similarity index 93%
rename from pkcs11/gck/tests/unit-test-crypto.c
rename to pkcs11/gck/tests/unit-test-sexp.c
index 457306f..1136fc1 100644
--- a/pkcs11/gck/tests/unit-test-crypto.c
+++ b/pkcs11/gck/tests/unit-test-sexp.c
@@ -1,5 +1,5 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* unit-test-crypto.c: Test crypto stuff
+/* unit-test-sexp.c: Test sexp stuff
Copyright (C) 2007 Stefan Walter
@@ -28,6 +28,7 @@
#include "run-auto-test.h"
#include "gck/gck-crypto.h"
+#include "gck/gck-sexp.h"
#include <gcrypt.h>
@@ -55,9 +56,9 @@ gcry_sexp_t dsakey = NULL;
DEFINE_SETUP(crypto_setup)
{
gcry_error_t gcry;
-
+
gck_crypto_initialize ();
-
+
gcry = gcry_sexp_new (&rsakey, TEST_RSA, strlen (TEST_RSA), 1);
g_return_if_fail (gcry == 0);
gcry = gcry_sexp_new (&dsakey, TEST_DSA, strlen (TEST_DSA), 1);
@@ -79,15 +80,15 @@ DEFINE_TEST(parse_key)
gboolean ret;
gboolean is_priv = FALSE;
int algorithm = 0;
-
+
/* Get the private key out */
- ret = gck_crypto_sexp_parse_key (rsakey, &algorithm, &is_priv, &sexp);
+ ret = gck_sexp_parse_key (rsakey, &algorithm, &is_priv, &sexp);
g_assert (ret);
g_assert (algorithm == GCRY_PK_RSA);
g_assert (is_priv == TRUE);
g_assert (sexp != NULL);
-
- ret = gck_crypto_sexp_extract_mpi (rsakey, &mpi, "p", NULL);
+
+ ret = gck_sexp_extract_mpi (rsakey, &mpi, "p", NULL);
g_assert (ret);
g_assert (mpi != NULL);
}
@@ -98,34 +99,34 @@ DEFINE_TEST(sexp_key_to_public)
guchar id1[20], id2[20];
gboolean ret;
guchar *p;
-
+
/* RSA */
- ret = gck_crypto_sexp_key_to_public (rsakey, &pubkey);
+ ret = gck_sexp_key_to_public (rsakey, &pubkey);
g_assert (ret);
g_assert (pubkey != NULL);
-
+
p = gcry_pk_get_keygrip (rsakey, id1);
g_return_if_fail (p == id1);
p = gcry_pk_get_keygrip (pubkey, id2);
g_return_if_fail (p == id2);
g_assert (memcmp (id1, id2, sizeof (id1)) == 0);
-
+
gcry_sexp_release (pubkey);
/* DSA */
- ret = gck_crypto_sexp_key_to_public (dsakey, &pubkey);
+ ret = gck_sexp_key_to_public (dsakey, &pubkey);
g_assert (ret);
g_assert (pubkey != NULL);
-
+
p = gcry_pk_get_keygrip (dsakey, id1);
g_return_if_fail (p == id1);
p = gcry_pk_get_keygrip (pubkey, id2);
g_return_if_fail (p == id2);
g_assert (memcmp (id1, id2, sizeof (id1)) == 0);
-
+
gcry_sexp_release (pubkey);
}
diff --git a/pkcs11/ssh-store/gck-ssh-private-key.c b/pkcs11/ssh-store/gck-ssh-private-key.c
index 3b4a0d7..eb28786 100644
--- a/pkcs11/ssh-store/gck-ssh-private-key.c
+++ b/pkcs11/ssh-store/gck-ssh-private-key.c
@@ -108,8 +108,8 @@ realize_and_take_data (GckSshPrivateKey *self, gcry_sexp_t sexp, gchar *comment,
/* The base public key gets setup. */
wrapper = gck_sexp_new (sexp);
- gck_key_set_base_sexp (GCK_KEY (self), wrapper);
- gck_key_set_base_sexp (GCK_KEY (self->pubkey), wrapper);
+ gck_sexp_key_set_base (GCK_SEXP_KEY (self), wrapper);
+ gck_sexp_key_set_base (GCK_SEXP_KEY (self->pubkey), wrapper);
gck_sexp_unref (wrapper);
/* Own the comment */
diff --git a/pkcs11/ssh-store/tests/p11-tests.conf b/pkcs11/ssh-store/tests/p11-tests.conf
index fbc86d5..1578a78 100644
--- a/pkcs11/ssh-store/tests/p11-tests.conf
+++ b/pkcs11/ssh-store/tests/p11-tests.conf
@@ -1,3 +1,3 @@
-# Configuration for running p11-tests on this module
-init-string = directory='test-data'
-login-context-pin = password
+# Configuration for running p11-tests on this module
+init-string = directory='pkcs11/ssh-store/tests/test-data'
+login-context-pin = password
diff --git a/pkcs11/ssh-store/tests/unit-test-ssh-openssh.c b/pkcs11/ssh-store/tests/unit-test-ssh-openssh.c
index 121245c..3b27120 100644
--- a/pkcs11/ssh-store/tests/unit-test-ssh-openssh.c
+++ b/pkcs11/ssh-store/tests/unit-test-ssh-openssh.c
@@ -27,7 +27,7 @@
#include "gck-ssh-openssh.h"
-#include "gck/gck-crypto.h"
+#include "gck/gck-sexp.h"
#include <glib.h>
@@ -70,8 +70,8 @@ DEFINE_TEST(parse_public)
g_warning ("couldn't parse public key: %s", PUBLIC_FILES[i]);
g_assert_cmpint (res, ==, GCK_DATA_SUCCESS);
}
-
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, &is_private, NULL))
+
+ if (!gck_sexp_parse_key (sexp, &algorithm, &is_private, NULL))
g_assert_not_reached ();
g_assert_cmpstr (comment, ==, COMMENT);
@@ -104,8 +104,8 @@ DEFINE_TEST(parse_private)
g_warning ("couldn't parse private key: %s", PRIVATE_FILES[i]);
g_assert_cmpint (res, ==, GCK_DATA_SUCCESS);
}
-
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, &is_private, NULL))
+
+ if (!gck_sexp_parse_key (sexp, &algorithm, &is_private, NULL))
g_assert_not_reached ();
g_assert_cmpint (algorithm, !=, 0);
diff --git a/pkcs11/user-store/gck-user-private-key.c b/pkcs11/user-store/gck-user-private-key.c
index 93ee0be..c6bff36 100644
--- a/pkcs11/user-store/gck-user-private-key.c
+++ b/pkcs11/user-store/gck-user-private-key.c
@@ -102,7 +102,7 @@ gck_user_private_key_real_get_attribute (GckObject *base, GckSession *session, C
}
static GckSexp*
-gck_user_private_key_real_acquire_crypto_sexp (GckKey *base, GckSession *unused)
+gck_user_private_key_real_acquire_crypto_sexp (GckSexpKey *base, GckSession *unused)
{
GckUserPrivateKey *self = GCK_USER_PRIVATE_KEY (base);
gcry_sexp_t sexp;
@@ -187,8 +187,8 @@ gck_user_private_key_class_init (GckUserPrivateKeyClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
- GckKeyClass *key_class = GCK_KEY_CLASS (klass);
-
+ GckSexpKeyClass *key_class = GCK_SEXP_KEY_CLASS (klass);
+
gobject_class->dispose = gck_user_private_key_dispose;
gobject_class->finalize = gck_user_private_key_finalize;
gobject_class->set_property = gck_user_private_key_set_property;
@@ -248,12 +248,12 @@ gck_user_private_key_real_load (GckSerializable *base, GckSecret *login, const g
}
/* Calculate a public key as our 'base' */
- if (!gck_crypto_sexp_key_to_public (sexp, &pub))
+ if (!gck_sexp_key_to_public (sexp, &pub))
g_return_val_if_reached (FALSE);
/* Keep the public part of the key around for answering queries */
wrapper = gck_sexp_new (pub);
- gck_key_set_base_sexp (GCK_KEY (self), wrapper);
+ gck_sexp_key_set_base (GCK_SEXP_KEY (self), wrapper);
gck_sexp_unref (wrapper);
/* Encrypted private key, keep login and data */
@@ -297,7 +297,7 @@ gck_user_private_key_real_save (GckSerializable *base, GckSecret *login, guchar
g_return_val_if_fail (data, FALSE);
g_return_val_if_fail (n_data, FALSE);
- sexp = gck_user_private_key_real_acquire_crypto_sexp (GCK_KEY (self), NULL);
+ sexp = gck_user_private_key_real_acquire_crypto_sexp (GCK_SEXP_KEY (self), NULL);
g_return_val_if_fail (sexp, FALSE);
password = gck_secret_get_password (login, &n_password);
diff --git a/pkcs11/user-store/gck-user-public-key.c b/pkcs11/user-store/gck-user-public-key.c
index 0eef087..6f7e255 100644
--- a/pkcs11/user-store/gck-user-public-key.c
+++ b/pkcs11/user-store/gck-user-public-key.c
@@ -145,7 +145,7 @@ gck_user_public_key_real_load (GckSerializable *base, GckSecret *login, const gu
}
wrapper = gck_sexp_new (sexp);
- gck_key_set_base_sexp (GCK_KEY (self), wrapper);
+ gck_sexp_key_set_base (GCK_SEXP_KEY (self), wrapper);
gck_sexp_unref (wrapper);
return TRUE;
@@ -161,7 +161,7 @@ gck_user_public_key_real_save (GckSerializable *base, GckSecret *login, guchar *
g_return_val_if_fail (data, FALSE);
g_return_val_if_fail (n_data, FALSE);
- wrapper = gck_key_get_base_sexp (GCK_KEY (self));
+ wrapper = gck_sexp_key_get_base (GCK_SEXP_KEY (self));
g_return_val_if_fail (wrapper, FALSE);
*data = gck_data_der_write_public_key (gck_sexp_get (wrapper), n_data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]