CK_RV C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pData, /* the data (digest) to be signed */ CK_ULONG ulDataLen, /* count of bytes to be signed */ CK_BYTE_PTR pSignature, /* receives the signature */ CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */ { CK_RV rv; struct sc_pkcs11_session *session; CK_ULONG length; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = get_session(hSession, &session); if (rv != CKR_OK) goto out; /* According to the pkcs11 specs, we must not do any calls that * change our crypto state if the caller is just asking for the * signature buffer size, or if the result would be * CKR_BUFFER_TOO_SMALL. Thus we cannot do the sign_update call * below. */ if ((rv = sc_pkcs11_sign_size(session, &length)) != CKR_OK) goto out; if (pSignature == NULL || length > *pulSignatureLen) { *pulSignatureLen = length; rv = pSignature ? CKR_BUFFER_TOO_SMALL : CKR_OK; goto out; } rv = sc_pkcs11_sign_update(session, pData, ulDataLen); if (rv == CKR_OK) { rv = restore_login_state(session->slot); if (rv == CKR_OK) rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen); rv = reset_login_state(session->slot, rv); } out: sc_log(context, "C_Sign() = %s", lookup_enum ( RV_T, rv )); sc_pkcs11_unlock(); return rv; }
CK_RV C_Sign(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pData, /* the data (digest) to be signed */ CK_ULONG ulDataLen, /* count of bytes to be signed */ CK_BYTE_PTR pSignature, /* receives the signature */ CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */ { int rv; struct sc_pkcs11_session *session; CK_ULONG length; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = pool_find(&session_pool, hSession, (void**) &session); if (rv != CKR_OK) goto out; /* According to the pkcs11 specs, we must not do any calls that * change our crypto state if the caller is just asking for the * signature buffer size, or if the result would be * CKR_BUFFER_TOO_SMALL. Thus we cannot do the sign_update call * below. */ if ((rv = sc_pkcs11_sign_size(session, &length)) != CKR_OK) goto out; if (pSignature == NULL || length > *pulSignatureLen) { *pulSignatureLen = length; rv = pSignature? CKR_BUFFER_TOO_SMALL : CKR_OK; goto out; } rv = sc_pkcs11_sign_update(session, pData, ulDataLen); if (rv == CKR_OK) rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen); out: sc_debug(context, "Signing result was %d\n", rv); sc_pkcs11_unlock(); return rv; }
CK_RV C_SignFinal(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_BYTE_PTR pSignature, /* receives the signature */ CK_ULONG_PTR pulSignatureLen) /* receives byte count of signature */ { struct sc_pkcs11_session *session; CK_ULONG length; CK_RV rv; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; rv = get_session(hSession, &session); if (rv != CKR_OK) goto out; /* According to the pkcs11 specs, we must not do any calls that * change our crypto state if the caller is just asking for the * signature buffer size, or if the result would be * CKR_BUFFER_TOO_SMALL. */ if ((rv = sc_pkcs11_sign_size(session, &length)) != CKR_OK) goto out; if (pSignature == NULL || length > *pulSignatureLen) { *pulSignatureLen = length; rv = pSignature ? CKR_BUFFER_TOO_SMALL : CKR_OK; } else { rv = sc_pkcs11_sign_final(session, pSignature, pulSignatureLen); } out: sc_log(context, "C_SignFinal() = %s", lookup_enum ( RV_T, rv )); sc_pkcs11_unlock(); return rv; }