From 405a65dea4ef1c12aaec4e232dc3a4b123ca3017 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Wed, 16 Sep 2015 00:59:35 -0400 Subject: Add C_SignUpdate(), C_SignFinal(), C_VerifyUpdate(), C_VerifyFinal(). --- pkcs11.c | 239 +++++++++++++++++++++++++++++++++++++++++++------------ py11/__init__.py | 37 +++++++++ 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") -- cgit v1.2.3