From cd01a73cafd89ef7672c9d5602428dccb549f32d Mon Sep 17 00:00:00 2001 From: Doug Engert Date: Wed, 19 Nov 2014 19:31:18 -0600 Subject: [PATCH] C_Digest does not check if buffer too small before update. Issue #327 C_Digest will now query for the buffer size using sc_pkcs15_md_final before calling sc_pkcs15_md_update. This avoids doing a double update when the user passes in a buffer to small, then gets the buffer and calls C_Digest again. --- src/pkcs11/pkcs11-object.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-object.c b/src/pkcs11/pkcs11-object.c index 1be59d9b..90b5e1d5 100644 --- a/src/pkcs11/pkcs11-object.c +++ b/src/pkcs11/pkcs11-object.c @@ -511,6 +511,7 @@ C_Digest(CK_SESSION_HANDLE hSession, /* the session's handle */ { CK_RV rv; struct sc_pkcs11_session *session; + CK_ULONG ulBuflen = 0; rv = sc_pkcs11_lock(); if (rv != CKR_OK) @@ -521,7 +522,21 @@ C_Digest(CK_SESSION_HANDLE hSession, /* the session's handle */ if (rv != CKR_OK) goto out; - rv = sc_pkcs11_md_update(session, pData, ulDataLen); + /* if pDigest == NULL, buffer size request */ + if (pDigest) { + /* As per PKCS#11 2.20 we need to check if buffer too small before update */ + rv = sc_pkcs11_md_final(session, NULL, &ulBuflen); + if (rv != CKR_OK) + goto out; + + if (ulBuflen > *pulDigestLen) { + *pulDigestLen = ulBuflen; + rv = CKR_BUFFER_TOO_SMALL; + goto out; + } + + rv = sc_pkcs11_md_update(session, pData, ulDataLen); + } if (rv == CKR_OK) rv = sc_pkcs11_md_final(session, pDigest, pulDigestLen);