aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2015-09-16 00:59:35 -0400
committerRob Austein <sra@hactrn.net>2015-09-16 00:59:35 -0400
commit405a65dea4ef1c12aaec4e232dc3a4b123ca3017 (patch)
treeb851a8d01418a82e966c012f78c50b0423d04165
parentf12a5e82f66c0da735bcca8c5010f867a5067946 (diff)
Add C_SignUpdate(), C_SignFinal(), C_VerifyUpdate(), C_VerifyFinal().
-rw-r--r--pkcs11.c239
-rw-r--r--py11/__init__.py37
2 files changed, 226 insertions, 50 deletions
diff --git a/pkcs11.c b/pkcs11.c
index cfd14da..93a5f36 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -2312,9 +2312,8 @@ static CK_RV sign_rsa_pkcs(p11_session_t *session,
assert(session != NULL && pulSignatureLen != NULL);
- const hal_hash_descriptor_t * const desc = session->sign_digest_descriptor;
- const size_t digest_info_len = desc == NULL ? 1 : desc->digest_length + 4 + desc->digest_algorithm_id_length;
- uint8_t digest_info[digest_info_len];
+ const hal_hash_descriptor_t * const descriptor = session->sign_digest_descriptor;
+ uint8_t digest_info[descriptor == NULL ? 1 : descriptor->digest_length + 4 + descriptor->digest_algorithm_id_length];
if (!p11_object_get_rsa_private_key(session->sign_key_handle,
&key, keybuf, sizeof(keybuf)))
@@ -2334,9 +2333,9 @@ static CK_RV sign_rsa_pkcs(p11_session_t *session,
if (pSignature != NULL && rv == CKR_BUFFER_TOO_SMALL)
lose(CKR_BUFFER_TOO_SMALL);
- if (pSignature != NULL && desc != NULL) {
+ if (pSignature != NULL && descriptor != NULL) {
- if (!pkcs1_construct_digestinfo(desc, session->sign_digest_state, digest_info, sizeof(digest_info)))
+ if (!pkcs1_construct_digestinfo(descriptor, session->sign_digest_state, digest_info, sizeof(digest_info)))
lose(CKR_FUNCTION_FAILED);
pData = digest_info;
@@ -2381,9 +2380,8 @@ static CK_RV verify_rsa_pkcs(p11_session_t *session,
assert(session != NULL);
- const hal_hash_descriptor_t * const desc = session->verify_digest_descriptor;
- const size_t digest_info_len = desc == NULL ? 1 : desc->digest_length + 4 + desc->digest_algorithm_id_length;
- uint8_t digest_info[digest_info_len];
+ const hal_hash_descriptor_t * const descriptor = session->verify_digest_descriptor;
+ uint8_t digest_info[descriptor == NULL ? 1 : descriptor->digest_length + 4 + descriptor->digest_algorithm_id_length];
uint8_t expected[ulSignatureLen], received[ulSignatureLen];
unsigned diff = 0;
@@ -2442,9 +2440,8 @@ static CK_RV sign_ecdsa(p11_session_t *session,
assert(session != NULL && pulSignatureLen != NULL);
- const hal_hash_descriptor_t * const desc = session->sign_digest_descriptor;
- const size_t digest_len = desc == NULL ? 1 : desc->digest_length;
- uint8_t digest[digest_len];
+ const hal_hash_descriptor_t * const descriptor = session->sign_digest_descriptor;
+ uint8_t digest[descriptor == NULL ? 1 : descriptor->digest_length];
if (!p11_object_get_ec_private_key(session->sign_key_handle, &key, keybuf, sizeof(keybuf)))
lose(CKR_FUNCTION_FAILED);
@@ -2472,7 +2469,7 @@ static CK_RV sign_ecdsa(p11_session_t *session,
if (pSignature != NULL && rv == CKR_BUFFER_TOO_SMALL)
lose(CKR_BUFFER_TOO_SMALL);
- if (pSignature != NULL && desc != NULL) {
+ if (pSignature != NULL && descriptor != NULL) {
if (!hal_check(hal_hash_finalize(session->sign_digest_state, digest, sizeof(digest))))
lose(CKR_FUNCTION_FAILED);
@@ -2511,9 +2508,8 @@ static CK_RV verify_ecdsa(p11_session_t *session,
assert(session != NULL && pSignature != NULL);
- const hal_hash_descriptor_t * const desc = session->verify_digest_descriptor;
- const size_t digest_len = desc == NULL ? 1 : desc->digest_length;
- uint8_t digest[digest_len];
+ const hal_hash_descriptor_t * const descriptor = session->verify_digest_descriptor;
+ uint8_t digest[descriptor == NULL ? 1 : descriptor->digest_length];
if (!p11_object_get_ec_public_key(session->verify_key_handle, &key, keybuf, sizeof(keybuf)))
lose(CKR_FUNCTION_FAILED);
@@ -2525,7 +2521,6 @@ static CK_RV verify_ecdsa(p11_session_t *session,
pData = digest;
ulDataLen = sizeof(digest);
-
}
if (!hal_check(hal_ecdsa_verify(key, pData, ulDataLen, pSignature, ulSignatureLen, HAL_ECDSA_SIGNATURE_FORMAT_PKCS11)))
@@ -3900,9 +3895,96 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
default:
lose(CKR_FUNCTION_FAILED);
}
+ /* Fall through */
+ fail:
+ if (session != NULL && pSignature != NULL) {
+ session->sign_key_handle = CK_INVALID_HANDLE;
+ session->sign_digest_descriptor = NULL;
+ hal_hash_cleanup(&session->sign_digest_state);
+ }
- fail: /* Fall through */
+ mutex_unlock_return_with_rv(rv, p11_global_mutex);
+}
+
+CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen)
+{
+ ENTER_PUBLIC_FUNCTION(C_SignUpdate);
+
+ p11_session_t *session;
+ CK_RV rv;
+
+ mutex_lock_or_return_failure(p11_global_mutex);
+
+ if ((session = p11_session_find(hSession)) == NULL)
+ lose(CKR_SESSION_HANDLE_INVALID);
+
+ if (pPart == NULL)
+ lose(CKR_ARGUMENTS_BAD);
+
+ if (session->sign_key_handle == CK_INVALID_HANDLE)
+ lose(CKR_OPERATION_NOT_INITIALIZED);
+
+ if (session->sign_digest_descriptor == NULL || !session->sign_digest_descriptor->can_restore_state)
+ lose(CKR_FUNCTION_FAILED);
+
+ if ((rv = digest_update(session->sign_digest_descriptor,
+ &session->sign_digest_state,
+ pPart, ulPartLen)) != CKR_OK)
+ goto fail;
+
+ return mutex_unlock(p11_global_mutex);
+
+ fail:
+ if (session != NULL) {
+ session->sign_key_handle = CK_INVALID_HANDLE;
+ session->sign_digest_descriptor = NULL;
+ hal_hash_cleanup(&session->sign_digest_state);
+ }
+
+ mutex_unlock_return_with_rv(rv, p11_global_mutex);
+}
+
+CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen)
+{
+ ENTER_PUBLIC_FUNCTION(C_SignFinal);
+
+ p11_session_t *session;
+ CK_KEY_TYPE key_type;
+ CK_RV rv;
+
+ mutex_lock_or_return_failure(p11_global_mutex);
+
+ if ((session = p11_session_find(hSession)) == NULL)
+ lose(CKR_SESSION_HANDLE_INVALID);
+
+ if (pulSignatureLen == NULL)
+ lose(CKR_ARGUMENTS_BAD);
+
+ if (session->sign_key_handle == CK_INVALID_HANDLE || session->sign_digest_state == NULL)
+ lose(CKR_OPERATION_NOT_INITIALIZED);
+
+ if (!p11_attribute_get_ulong(session->sign_key_handle, CKA_KEY_TYPE, &key_type))
+ lose(CKR_FUNCTION_FAILED);
+
+ switch (key_type) {
+
+ case CKK_RSA:
+ rv = sign_rsa_pkcs(session, NULL, 0, pSignature, pulSignatureLen);
+ break;
+ case CKK_EC:
+ rv = sign_ecdsa(session, NULL, 0, pSignature, pulSignatureLen);
+ break;
+
+ default:
+ lose(CKR_FUNCTION_FAILED);
+ }
+ /* Fall through */
+ fail:
if (session != NULL && pSignature != NULL) {
session->sign_key_handle = CK_INVALID_HANDLE;
session->sign_digest_descriptor = NULL;
@@ -4020,7 +4102,7 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession,
if ((session = p11_session_find(hSession)) == NULL)
lose(CKR_SESSION_HANDLE_INVALID);
- if (pData == NULL)
+ if (pData == NULL || pSignature == NULL)
lose(CKR_ARGUMENTS_BAD);
if (session->verify_key_handle == CK_INVALID_HANDLE)
@@ -4059,6 +4141,95 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession,
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
+CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen)
+{
+ ENTER_PUBLIC_FUNCTION(C_VerifyUpdate);
+
+ p11_session_t *session;
+ CK_RV rv;
+
+ mutex_lock_or_return_failure(p11_global_mutex);
+
+ if ((session = p11_session_find(hSession)) == NULL)
+ lose(CKR_SESSION_HANDLE_INVALID);
+
+ if (pPart == NULL)
+ lose(CKR_ARGUMENTS_BAD);
+
+ if (session->verify_key_handle == CK_INVALID_HANDLE)
+ lose(CKR_OPERATION_NOT_INITIALIZED);
+
+ if (session->verify_digest_descriptor == NULL || !session->verify_digest_descriptor->can_restore_state)
+ lose(CKR_FUNCTION_FAILED);
+
+ if ((rv = digest_update(session->verify_digest_descriptor,
+ &session->verify_digest_state,
+ pPart, ulPartLen)) != CKR_OK)
+ goto fail;
+
+ return mutex_unlock(p11_global_mutex);
+
+ fail:
+ if (session != NULL) {
+ session->verify_key_handle = CK_INVALID_HANDLE;
+ session->verify_digest_descriptor = NULL;
+ hal_hash_cleanup(&session->verify_digest_state);
+ }
+
+ mutex_unlock_return_with_rv(rv, p11_global_mutex);
+}
+
+CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen)
+{
+ ENTER_PUBLIC_FUNCTION(C_VerifyFinal);
+
+ p11_session_t *session;
+ CK_KEY_TYPE key_type;
+ CK_RV rv;
+
+ mutex_lock_or_return_failure(p11_global_mutex);
+
+ if ((session = p11_session_find(hSession)) == NULL)
+ lose(CKR_SESSION_HANDLE_INVALID);
+
+ if (pSignature == NULL)
+ lose(CKR_ARGUMENTS_BAD);
+
+ if (session->verify_key_handle == CK_INVALID_HANDLE || session->verify_digest_state == NULL)
+ lose(CKR_OPERATION_NOT_INITIALIZED);
+
+ if (!p11_attribute_get_ulong(session->verify_key_handle, CKA_KEY_TYPE, &key_type))
+ lose(CKR_FUNCTION_FAILED);
+
+ switch (key_type) {
+
+ case CKK_RSA:
+ rv = verify_rsa_pkcs(session, NULL, 0, pSignature, ulSignatureLen);
+ break;
+
+ case CKK_EC:
+ rv = verify_ecdsa(session, NULL, 0, pSignature, ulSignatureLen);
+ break;
+
+ default:
+ lose(CKR_FUNCTION_FAILED);
+ }
+
+ fail: /* Fall through */
+
+ if (session != NULL) {
+ session->verify_key_handle = CK_INVALID_HANDLE;
+ session->verify_digest_descriptor = NULL;
+ hal_hash_cleanup(&session->verify_digest_state);
+ }
+
+ mutex_unlock_return_with_rv(rv, p11_global_mutex);
+}
+
/*
* If there's any method in this entire package which really needs a
* more complex mutex structure than the single global mutex, it's
@@ -4505,22 +4676,6 @@ CK_RV C_DigestKey(CK_SESSION_HANDLE hSession,
return CKR_FUNCTION_NOT_SUPPORTED;
}
-CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen)
-{
- ENTER_PUBLIC_FUNCTION(C_SignUpdate);
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen)
-{
- ENTER_PUBLIC_FUNCTION(C_SignFinal);
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
CK_RV C_SignRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey)
@@ -4539,22 +4694,6 @@ CK_RV C_SignRecover(CK_SESSION_HANDLE hSession,
return CKR_FUNCTION_NOT_SUPPORTED;
}
-CK_RV C_VerifyUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen)
-{
- ENTER_PUBLIC_FUNCTION(C_VerifyUpdate);
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen)
-{
- ENTER_PUBLIC_FUNCTION(C_VerifyFinal);
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey)
diff --git a/py11/__init__.py b/py11/__init__.py
index fa6e0f5..af7e053 100644
--- a/py11/__init__.py
+++ b/py11/__init__.py
@@ -109,6 +109,16 @@ class PKCS11 (object):
self.so.C_Sign(session, data, len(data), sig, byref(n))
return sig.raw
+ def C_SignUpdate(self, session, data):
+ self.so.C_SignUpdate(session, data, len(data))
+
+ def C_SignFinal(self, session):
+ n = CK_ULONG()
+ self.so.C_Sign(session, None, byref(n))
+ sig = create_string_buffer(n.value)
+ self.so.C_Sign(session, sig, byref(n))
+ return sig.raw
+
def C_VerifyInit(self, session, mechanism_type, public_key):
mechanism = CK_MECHANISM(mechanism_type, None, 0)
self.so.C_VerifyInit(session, byref(mechanism), public_key)
@@ -116,12 +126,39 @@ class PKCS11 (object):
def C_Verify(self, session, data, signature):
self.so.C_Verify(session, data, len(data), signature, len(signature))
+ def C_VerifyUpdate(self, session, data):
+ self.so.C_Verify(session, data, len(data))
+
+ def C_VerifyFinal(self, session, signature):
+ self.so.C_Verify(session, signature, len(signature))
+
def C_CreateObject(self, session, template):
template = self.adb.to_ctypes(template)
handle = CK_OBJECT_HANDLE()
self.so.C_CreateObject(session, template, len(template), byref(handle))
return handle.value
+ def C_DigestInit(self, session, mechanism_type):
+ mechanism = CK_MECHANISM(mechanism_type, None, 0)
+ self.so.C_DigestInit(session, byref(mechanism))
+
+ def C_Digest(self, session, data):
+ n = CK_ULONG()
+ self.so.C_Digest(session, data, len(data), None, byref(n))
+ hash = create_string_buffer(n.value)
+ self.so.C_Digest(session, data, len(data), hash, byref(n))
+ return hash.raw
+
+ def C_DigestUpdate(self, session, data):
+ self.so.C_DigestUpdate(session, data, len(data))
+
+ def C_DigestFinal(self, session):
+ n = CK_ULONG()
+ self.so.C_Digest(session, None, byref(n))
+ hash = create_string_buffer(n.value)
+ self.so.C_Digest(session, hash, byref(n))
+ return hash.raw
+
__all__ = ["PKCS11"]
__all__.extend(name for name in globals()
if name.startswith("CK")