Attribute VB_Name = "TestSc14n" Option Explicit Option Base 0 ' Some tests using the VBA/VB6 interface to SC14N ' $Id: TestSc14n.bas $ ' Last updated: ' $Date: 2019-12-12 22:13:00 $ ' $Version: 2.1.0 $ ' ' ------------------------------ LICENSE ------------------------------------- ' Copyright (C) 2018-19 David Ireland, DI Management Services Pty Limited. ' All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net> ' The code in this module is licensed under the terms of the MIT license. ' For a copy, see <http://opensource.org/licenses/MIT> ' ---------------------------------------------------------------------------- ' ' Requires `SC14N` to be installed on your system: available from <https://cryptosys.net/sc14n/>. ' Include the modules `basSc14n.bas` and `basUtf8FromString` in your project. ' ' Test files are in `sc14n-testfiles.zip`. These must be in the current working directory. ' Public Sub DoAllTests() Call Test_General Call Test_sc14nFile2File Call Test_sc14nFile2Bytes Call Test_sc14nError Call Test_sc14nFile2Digest Call Test_sc14nBytes2Digest Call Test_sc14nBytes2Bytes Call Test_Empty Call Test_Exclusive_c14n Call Test_Flatten End Sub Public Sub Test_General() Dim n As Long Dim ch As String Debug.Print ("INTERROGATE THE CORE DISC14N DLL:") n = SC14N_Gen_Version() Debug.Print "Version=" & n If n < 10000 Then MsgBox "Require Sc14n v1.0 or higher", vbCritical Exit Sub End If ch = Chr(SC14N_Gen_LicenceType()) Debug.Print "LicenceType=" & ch Debug.Print "ModuleName=" & sc14nGenModuleName() Debug.Print "CompileTime=" & sc14nGenCompileTime() Debug.Print "Platform=" & sc14nGenPlatform() End Sub Public Sub Test_sc14nFile2File() Dim strFileName As String Dim strFileOUT As String Dim nRet As Long strFileName = "olamundo.xml" strFileOUT = "olamundo-c14n.xml" nRet = sc14nFile2File(strFileOUT, strFileName, "Signature", "", SC14N_TRAN_EXCLUDEBYTAG) Debug.Print "C14N_File2File returns " & nRet & " (expecting 0)" End Sub Public Sub Test_sc14nFile2Bytes() Dim abBuffer() As Byte Dim strFileName As String strFileName = "olamundo.xml" abBuffer = sc14nFile2Bytes(strFileName, "Body", "", SC14N_TRAN_SUBSETBYTAG) Call ShowBytesInArray(abBuffer) Debug.Print Utf8BytesToString(abBuffer) End Sub Public Sub Test_sc14nError() Dim abBuffer() As Byte Dim nBytes As Long Dim strFileName As String Dim nRet As Long Debug.Print "Expecting errors..." ' Input file that does not exist strFileName = "missing.xml" abBuffer = sc14nFile2Bytes(strFileName, "Body", "", SC14N_TRAN_SUBSETBYTAG) ' Result is an empty buffer nBytes = UBound(abBuffer) + 1 Debug.Print "nBytes=" & nBytes Debug.Print "Result='" & Utf8BytesToString(abBuffer) & "'" ' Get last error set Debug.Print "LastError='" & sc14nErrLastError() & "'" ' Function that returns an error code nRet = sc14nFile2File("whatever.xml", strFileName, "", "", 0) Debug.Print "sc14nFile2File() returns " & nRet Debug.Print "sc14nErrErrorLookup(" & nRet & ") => " & sc14nErrErrorLookup(nRet) Debug.Print "LastError='" & sc14nErrLastError() & "'" ' Try again with input file that is not a valid XML file strFileName = "AliceRSASignByCarl.cer" nRet = sc14nFile2File("whatever.xml", strFileName, "", "", 0) Debug.Print "sc14nFile2File() returns " & nRet Debug.Print "sc14nErrErrorLookup(" & nRet & ") => " & sc14nErrErrorLookup(nRet) Debug.Print "LastError='" & sc14nErrLastError() & "'" End Sub Public Sub Test_sc14nFile2Digest() Dim strDigest As String Dim strFileName As String Dim strOK As String strFileName = "olamundo.xml" strOK = "dwWOTcgHoCxU+d3Xyi8GLWnzRPs=" strDigest = sc14nFile2Digest(strFileName, "", "", 0) Debug.Print "DIGEST=" & strDigest Debug.Print "OK =" & strOK Debug.Assert (strDigest = strOK) End Sub Public Sub Test_sc14nBytes2Digest() Dim strDigest As String Dim abBuffer() As Byte Dim nBytes As Long Dim strFileName As String Dim strOK As String strFileName = "olamundo.xml" ' Read in entire XML document (C14N transformed, but could just be read in directly from file) abBuffer = sc14nFile2Bytes(strFileName, "", "", 0) nBytes = UBound(abBuffer) + 1 ' Now perform memory->digest C14N transformation of doc excluding Signature element ' = DigestValue for <Reference URI=""> strOK = "UWuYTYug10J1k5hKfonxthgrAR8=" strDigest = sc14nBytes2Digest(abBuffer, nBytes, "Signature", "", SC14N_TRAN_EXCLUDEBYTAG) Debug.Print "DIGEST=" & strDigest Debug.Print "OK =" & strOK Debug.Assert (strDigest = strOK) ' Again but using SHA-256 instead of SHA-1 strOK = "XmEzFTF6w33nhHfeQqIZKwITz3H2mbBvShxWn+ML/7s=" strDigest = sc14nBytes2Digest(abBuffer, nBytes, "Signature", "", SC14N_TRAN_EXCLUDEBYTAG Or SC14N_DIG_SHA256) Debug.Print "DIGEST(SHA-256)=" & strDigest Debug.Print "OK =" & strOK Debug.Assert (strDigest = strOK) End Sub Public Sub Test_sc14nBytes2Bytes() Dim abBuffer() As Byte Dim nBytes As Long Dim strFileName As String Dim abOut() As Byte Dim nOut As Long strFileName = "olamundo.xml" ' Read in entire XML document (C14N transformed, but could just be read in directly from file) abBuffer = sc14nFile2Bytes(strFileName, "", "", 0) nBytes = UBound(abBuffer) + 1 ' Now perform memory->memory C14N transformation abOut = sc14nBytes2Bytes(abBuffer, nBytes, "Body", "", SC14N_TRAN_SUBSETBYTAG) nOut = UBound(abOut) + 1 Debug.Print "nOut=" & nOut ' Display in "ANSI" string form Debug.Print "Result='" & Utf8BytesToString(abOut) & "'" End Sub Public Sub Test_Empty() Dim s As String Dim b() As Byte Dim abEmpty() As Byte Debug.Print "Test empty input..." b = Utf8BytesFromString(vbNullString) Call ShowBytesInArray(b) ' Undefined array s = Utf8BytesToString(abEmpty) Debug.Print "[" & s & "]" Call ShowStringBytes(s) End Sub Public Sub Test_Exclusive_c14n() Dim strDigest As String Dim abBuffer() As Byte Dim strFileName As String Dim strOK As String Dim strPrefixList As String ' Example files from RFC 3741 "Exclusive XML Canonicalization, Version 1.0", s2.2 ' Transform element <n1:elem2> strOK = "qYwgpdgV1/b3PQ3aSpMx9wKGtqY=" strFileName = "example1.xml" Debug.Print Debug.Print "FILE: " & strFileName abBuffer = sc14nFile2Bytes(strFileName, "n1:elem2", "", SC14N_TRAN_SUBSETBYTAG Or SC14N_METHOD_EXCLUSIVE) Debug.Print "excl-c14n:" Debug.Print Utf8BytesToString(abBuffer) ' Compute digest strDigest = sc14nFile2Digest(strFileName, "n1:elem2", "", SC14N_TRAN_SUBSETBYTAG Or SC14N_METHOD_EXCLUSIVE) Debug.Print "DIGEST=" & strDigest Debug.Print "OK =" & strOK Debug.Assert (strDigest = strOK) strFileName = "example2.xml" Debug.Print Debug.Print "FILE: " & strFileName abBuffer = sc14nFile2Bytes(strFileName, "n1:elem2", "", SC14N_TRAN_SUBSETBYTAG Or SC14N_METHOD_EXCLUSIVE) Debug.Print "excl-c14n:" Debug.Print Utf8BytesToString(abBuffer) ' Compute digest strDigest = sc14nFile2Digest(strFileName, "n1:elem2", "", SC14N_TRAN_SUBSETBYTAG Or SC14N_METHOD_EXCLUSIVE) Debug.Print "DIGEST=" & strDigest Debug.Print "OK =" & strOK Debug.Assert (strDigest = strOK) ' Transform using exclusive c14n with PrefixList ' <ds:Reference URI="#TS-3"> ' <ec:InclusiveNamespaces PrefixList="wsse SOAP-ENV" strFileName = "soap-ts3-signed-by-alice.xml" strPrefixList = "wsse SOAP-ENV" Debug.Print Debug.Print "FILE: " & strFileName Debug.Print "PrefixList='" & strPrefixList & "'" abBuffer = sc14nFile2Bytes(strFileName, "wsu:Id=TS-3", strPrefixList, SC14N_TRAN_SUBSETBYID Or SC14N_METHOD_EXCLUSIVE) Debug.Print Utf8BytesToString(abBuffer) ' Compute SHA-256 digest ' <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" /> strOK = "a4cojI7ZDOI1lKvGD7OHNus7qy1DQgpqNdGZ/YEDJQo=" strDigest = sc14nFile2Digest(strFileName, "wsu:Id=TS-3", strPrefixList, SC14N_TRAN_SUBSETBYID Or SC14N_METHOD_EXCLUSIVE Or SC14N_DIG_SHA256) Debug.Print "DIGEST=" & strDigest Debug.Print "OK =" & strOK Debug.Assert (strDigest = strOK) End Sub Public Sub Test_Flatten() Dim strFileName As String Dim abBuffer() As Byte Dim strDigest As String Dim strOK As String strFileName = "ignorable_ws.xml" Debug.Print Debug.Print "FILE: " & strFileName ' Default c14n... strOK = "JNluoz+Z+MbLrTX8W//wEEgeFpo=" abBuffer = sc14nFile2Bytes(strFileName, "", "", 0) Debug.Print "no-flatten:" Debug.Print Utf8BytesToString(abBuffer) strDigest = sc14nFile2Digest(strFileName, "", "", 0) Debug.Print "DIGEST=" & strDigest Debug.Print "OK =" & strOK Debug.Assert (strDigest = strOK) ' Flatten the XML - remove ignorable whitespace strOK = "4ZKWJnP7dUperStlOKrq7athzxw=" abBuffer = sc14nFile2Bytes(strFileName, "", "", SC14N_OPT_FLATTEN) Debug.Print "FLATTEN:" Debug.Print Utf8BytesToString(abBuffer) strDigest = sc14nFile2Digest(strFileName, "", "", SC14N_OPT_FLATTEN) Debug.Print "DIGEST=" & strDigest Debug.Print "OK =" & strOK Debug.Assert (strDigest = strOK) End Sub ' For debugging Public Sub ShowBytesInArray(vnt As Variant) Dim i As Long Dim b() As Byte b = vnt For i = 0 To UBound(b) Dim ch As Byte ch = b(i) If (ch < 15) Then Debug.Print "0"; Debug.Print Hex(b(i)); Next Debug.Print End Sub ' For debugging Public Sub ShowStringBytes(str As String) Dim i As Long Dim x() As Byte x = str For i = 0 To UBound(x) Debug.Print x(i); Next Debug.Print End Sub