CryptoSys PKI Pro Manual

CMS_GetSigDataDigest

Extracts the message digest from a signed-data CMS object file and verifies the signature.

VBA/VB6 Syntax

Public Declare Function CMS_GetSigDataDigest Lib "diCrPKI.dll" (ByVal strHexDigest As String, ByVal nHexDigestLen As Long, ByVal strFileIn As String, ByVal strCertFile As String, ByVal nOptions As Long) As Long

nRet = CMS_GetSigDataDigest(strHexDigest, nHexDigestLen, strFileIn, strCertFile, nOptions) As Long

C/C++ Syntax

long __stdcall CMS_GetSigDataDigest(char *szOutput, long nOutChars, const char *szFileIn, const char *szCertFile, long nOptions);

Parameters

szOutput
[out] to receive the message digest output.
nOutChars
[in] specifying the length of the output string.
szFileIn
[in] with name of signed-data CMS object file or the data as a base64 or PEM string.
szCertFile
[in] specifying an (optional) X.509 certificate file to be used to identify the signer.
nOptions
[in] option flags:
PKI_DEFAULT (0) for default options

Returns (VBA/C)

If successful, the return value is a non-negative value indicating the message digest algorithm (CAUTION: this is not the number of characters in the output); otherwise it returns a negative error code.

VBA Wrapper Syntax

Public Function cmsGetSigDataDigest (szFileIn As String, Optional szCertFile As String = "", Optional nOptions As Long = 0) As String

.NET Equivalent

Cms.GetSigDataDigest Method

C++ (STL) Equivalent

static std::string dipki::Cms::GetSigDataDigest (const std::string &inputFile, const std::string &certFile="")

Remarks

This function extracts the message digest of the signed encapsulated content. In doing so, it also verifies that the signature is valid. The object may be a "detached signature" object. If signed attributes are present, the function will extract the messageDigest attribute for RSA and DSA signature algorithms. If signed attributes are not present, the message digest is extracted directly from the signature value, but only for RSASSA-PKCS1-v1_5 signatures, as the message digest cannot be directly extracted from a DSA or RSA-PSS signature. If given, the function will use the public key from the specified X.509 certificate to validate the signature; otherwise it will use the first valid SignerInfo and certificate pair it finds in the SignedData. The message digest, if found, is copied into szHexDigest. The maximum expected length of szHexDigest is PKI_MAX_HASH_CHARS characters. ANSI C users must add one to this value when allocating memory. The message digest is encoded in hexadecimal format using lower-case letters [a-f].

The message digest algorithm is indicated by the return code:

CodeAlgorithm
PKI_HASH_SHA1 (0) SHA-1
PKI_HASH_MD5 (1) MD5
PKI_HASH_MD2 (2) MD2
PKI_HASH_SHA256 (3) SHA-256
PKI_HASH_SHA384 (4) SHA-384
PKI_HASH_SHA512 (5) SHA-512
PKI_HASH_SHA224 (6) SHA-224

CAUTION: unlike other hash-related functions, this function does not return the length of the digest string; it returns the code for the digest algorithm.

Note that this does not verify that the message digest is that of the content. It does, however, verify that the message digest was indeed signed by the purported signer, but it does not check the content itself. To verify that the SignedData object is validly signed, the user must extract the content separately and verify that its message digest matches the digest extracted by this function. To do this, use the functions CMS_ReadSigDataToString() and HASH_HexFromBytes(). VB6 users can use HASH_HexFromString. See the examples below.

Alternatively, use the CMS_VerifySigData() to verify the signature and message digest directly and use CMS_QuerySigData() to extract the messageDigest attribute, if present, without validation.

Example (VBA core function)

This example extracts the message digest from the "detached signature" signed CMS object created by CMS_MakeDetachedSig above.

Dim nDigAlg As Long
Dim strCMSFile As String
Dim strHexDigest As String
strCMSFile = "DetSignByAlice.bin"
strHexDigest = String(PKI_MAX_HASH_CHARS, " ")
nDigAlg = CMS_GetSigDataDigest(strHexDigest, Len(strHexDigest), strCMSFile, "", 0)
Debug.Print "CMS_GetSigDataDigest returns " & nDigAlg
If nDigAlg < 0 Then
    Exit Function
End If
Debug.Print "Extracted digest is"
Debug.Print "[" & strHexDigest & "]"

This should produce the output

CMS_GetSigDataDigest returns 0
Extracted digest is
[406aec085279ba6e16022d9e0629c0229687dd48]

This second example shows how to retrieve the message digest and independently verify this against a hash of the content.

Dim strCMSFile As String
Dim strHexDigest As String
Dim nDigAlg As Long
Dim strData As String
Dim nDataLen As Long
Dim strContentDigest As String
Dim nHashLen As Long

strCMSFile = "4.2.bin"

' 1. Get the digest value
strHexDigest = String(PKI_MAX_HASH_CHARS, " ")
nDigAlg = CMS_GetSigDataDigest(strHexDigest, _
    Len(strHexDigest), strCMSFile, "", 0)
Debug.Print "CMS_GetSigDataDigest returns " & nDigAlg
If nDigAlg < 0 Then
    Exit Function
End If
Debug.Print "Extracted digest is"
Debug.Print "[" & strHexDigest & "]"

' 2. Go get the content - in this case it's in the signed-data object
nDataLen = CMS_ReadSigDataToString("", 0, strCMSFile, 0)
If nDataLen <= 0 Then
    Exit Function
End If
strData = String(nDataLen, " ")
nDataLen = CMS_ReadSigDataToString(strData, nDataLen, strCMSFile, 0)
Debug.Print "CMS_ReadSigDataToString returns " & nDataLen
Debug.Print "Data is [" & strData & "]"

' 3. Compute independently the hash of what we found
' (Note how we use the digest algorithm code returned above)
strContentDigest = String(PKI_MAX_HASH_CHARS, " ")
nHashLen = HASH_HexFromString(strContentDigest, _
    Len(strContentDigest), strData, nDataLen, nDigAlg)
Debug.Print "Computed hash of content is"
Debug.Print "[" & strContentDigest & "]"

' 4. Can we match this hash digest with 
'    what we extracted from the signed-data?
strContentDigest = Left(strContentDigest, nHashLen)
strHexDigest = Left(strHexDigest, nHashLen)
If strContentDigest = strHexDigest Then
    Debug.Print "SUCCESS - digests match!"
Else
    Debug.Print "FAILS! - no match"
End If

This should produce the output

CMS_GetSigDataDigest returns 0
Extracted digest is
[406aec085279ba6e16022d9e0629c0229687dd48]
CMS_ReadSigDataToString returns 28
Data is [This is some sample content.]
Computed hash of content is
[406aec085279ba6e16022d9e0629c0229687dd48]
SUCCESS - digests match!

And again, this time using C:

char *infile = "C:\\Test\\4.2.bin";
long ndigalg, mlen, hlen;
char hexdigest[41];
char conthash[41];
char *message;

/* 1. Get the digest string */
ndigalg = CMS_GetSigDataDigest(hexdigest, sizeof(hexdigest)-1, 
	infile, NULL, 0);
printf("CMS_GetSigDataDigest returns %ld\n", ndigalg);
if (ndigalg < 0) disp_error(ndigalg);
printf("SigDataDigest = %s\n", hexdigest);
//assert(lRet >= 0);

/* 2. Get the content from the signed-data object */
mlen = CMS_ReadSigDataToString(NULL, 0, infile, 0);
printf("Message data is %ld bytes long\n", mlen);
if (mlen < 0) disp_error(mlen);
assert(mlen >= 0);

/* Allocate some memory - NB add an extra byte */
message = malloc(mlen + 1);
assert(message);

/* Now read in */
mlen = CMS_ReadSigDataToString(message, mlen, infile, 0);
printf("CMS_ReadSigDataToString returns %ld\n", mlen);
if (mlen < 0) disp_error(mlen);
assert(mlen >= 0);
printf("Message is '%s'\n", message);

/* 3. Create a digest of this content 
   -- use the algorithm we got above */
hlen = HASH_HexFromBytes(conthash, sizeof(conthash)-1, 
	(unsigned char*)message, mlen, ndigalg);
printf("ContentDigest = %s\n", conthash);

/* 4. Finally we can compare */
if (strncmp(conthash, hexdigest, hlen) == 0)
	printf("SUCCESS - digests match!\n");
else
	printf("FAILS! - no match\n");

/* Clean up */
free(message);

Example (VBA wrapper function)

Dim strHexDigest As String
Dim strData As String
Const strCMSFile As String = "4.2.bin"

' Extract the digest value
strHexDigest = cmsGetSigDataDigest(strCMSFile, "")
Debug.Print "extracted digest=[" & strHexDigest & "]"
' Extract content from signed-data file
strData = cmsReadSigDataToString(strCMSFile)
Debug.Print "content='" & strData & "'"
' Compute digest value over the content
Debug.Print "computed digest =[" & hashHexFromBytes(StrConv(strData, vbFromUnicode), PKI_HASH_SHA1) & "]"

See Also

CMS_ReadSigData CMS_ReadSigDataToString CMS_QuerySigData CMS_VerifySigData

[Contents] [Index]

[PREV: CIPHER_KeyUnwrap...]   [Contents]   [Index]   
   [NEXT: CMS_MakeComprData...]

Copyright © 2004-24 D.I. Management Services Pty Ltd. All rights reserved. Generated 2024-09-23T07:52:09Z.