summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2010-10-27 18:12:02 +0200
committerMiloslav Trmač <mitr@redhat.com>2010-10-29 19:52:25 +0200
commit79adc0a7a1c8a1817b8aea1545fd9559314f4450 (patch)
treee1bad362f63b194ebad5a8844f6395fb027f2893
parent8f1254b8085ba2b189457e8f04abf19b5027f6a5 (diff)
downloadncrypto-79adc0a7a1c8a1817b8aea1545fd9559314f4450.tar.gz
ncrypto-79adc0a7a1c8a1817b8aea1545fd9559314f4450.tar.xz
ncrypto-79adc0a7a1c8a1817b8aea1545fd9559314f4450.zip
Add digest session cloning
-rw-r--r--include/ncrypto/ncrypto.h2
-rw-r--r--lib/ncrypto_local.c29
-rw-r--r--tests/digests.c43
3 files changed, 74 insertions, 0 deletions
diff --git a/include/ncrypto/ncrypto.h b/include/ncrypto/ncrypto.h
index f82cf0e..367ffed 100644
--- a/include/ncrypto/ncrypto.h
+++ b/include/ncrypto/ncrypto.h
@@ -124,6 +124,8 @@ struct ncr_digest_session;
CK_RV ncr_digest_alloc (struct ncr_digest_session **sess,
CK_MECHANISM_TYPE mech);
CK_RV ncr_digest_free (struct ncr_digest_session *sess);
+CK_RV ncr_digest_clone (struct ncr_digest_session **clone,
+ struct ncr_digest_session *sess);
/* Use either ncr_digest_{init,update*,final} (), or
ncr_{digest_init,digest} (). After finishing such a call sequence, a new
sequence can be started within the same session. */
diff --git a/lib/ncrypto_local.c b/lib/ncrypto_local.c
index 16bd781..15ae38c 100644
--- a/lib/ncrypto_local.c
+++ b/lib/ncrypto_local.c
@@ -269,6 +269,35 @@ ncr_digest_free (struct ncr_digest_session *sess)
}
CK_RV
+ncr_digest_clone (struct ncr_digest_session **clone,
+ struct ncr_digest_session *sess)
+{
+ struct ncr_digest_session *c;
+
+ g_return_val_if_fail (clone != NULL, CKR_ARGUMENTS_BAD);
+ g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
+ g_return_val_if_fail (sess->state == NDS_INITIALIZED
+ || sess->state == NDS_UPDATED,
+ CKR_OPERATION_NOT_INITIALIZED);
+
+ c = malloc (sizeof (*c));
+ if (c == NULL)
+ return CKR_HOST_MEMORY;
+
+ EVP_MD_CTX_init (&c->ctx);
+ if (EVP_MD_CTX_copy_ex (&c->ctx, &sess->ctx) == 0)
+ {
+ free (c);
+ return ckr_openssl ();
+ }
+ c->state = sess->state;
+ c->md = sess->md;
+ c->md_size = sess->md_size;
+ *clone = c;
+ return CKR_OK;
+}
+
+CK_RV
ncr_digest_init (struct ncr_digest_session *sess)
{
g_return_val_if_fail (sess != NULL, CKR_SESSION_HANDLE_INVALID);
diff --git a/tests/digests.c b/tests/digests.c
index 8013698..d8ca31c 100644
--- a/tests/digests.c
+++ b/tests/digests.c
@@ -142,6 +142,49 @@ main (void)
assert (res == CKR_OK);
for (j = 0; j < 2; j++)
{
+ struct ncr_digest_session *clone;
+
+ res = ncr_digest_init (sess);
+ assert (res == CKR_OK);
+
+ res = ncr_digest_update (sess, tvs[i].input, tvs[i].input_size / 2);
+ assert (res == CKR_OK);
+
+ res = ncr_digest_clone (&clone, sess);
+ assert (res == CKR_OK);
+
+ res = ncr_digest_update (sess, "", 1);
+ assert (res == CKR_OK);
+
+ dest_size = sizeof (dest);
+ res = ncr_digest_final (sess, dest, &dest_size);
+ assert (res == CKR_OK);
+ assert (dest_size == tvs[i].output_size);
+ assert (memcmp (dest, tvs[i].output, dest_size) != 0);
+
+ res = ncr_digest_update (clone, tvs[i].input + tvs[i].input_size / 2,
+ tvs[i].input_size - tvs[i].input_size / 2);
+ assert (res == CKR_OK);
+
+ dest_size = sizeof (dest);
+ res = ncr_digest_final (clone, dest, &dest_size);
+ assert (res == CKR_OK);
+ assert (dest_size == tvs[i].output_size);
+ assert (memcmp (dest, tvs[i].output, dest_size) == 0);
+
+ res = ncr_digest_free (clone);
+ assert (res == CKR_OK);
+ }
+ res = ncr_digest_free (sess);
+ assert (res == CKR_OK);
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (tvs); i++)
+ {
+ res = ncr_digest_alloc (&sess, tvs[i].mech);
+ assert (res == CKR_OK);
+ for (j = 0; j < 2; j++)
+ {
res = ncr_digest_init (sess);
assert (res == CKR_OK);