Attribute VB_Name = "TestPKI"
' $Id: TestPKI.bas $
'****************************** LICENSE ***********************************
' * Copyright (C) 2001-23 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>
' * Last updated:
' * $Date: 2022-01-01 03:31:00 $
' * $Version: 21.0.0 $
'****************************************************************************
'
' Some tests using the CryptoSys PKI VB6/VBA wrapper interface.
Option Explicit
Option Base 0
Public Const MIN_VERSION As Long = 210000
Public Sub DoAllTests()
Dim n As Long
Dim isok As Boolean
Debug.Print ("INTERROGATE THE CORE DICRPKI DLL...")
n = pkiVersion()
Debug.Print "Version=" & n
If n < MIN_VERSION Then
MsgBox "Require diCrPKI v" & MIN_VERSION & " or higher", vbCritical
Exit Sub
End If
Debug.Print "ModuleName=" & pkiModuleName()
Debug.Print "CWD=" & CurDir
Call test_aead
Call test_asn1TextDumpToString
Call test_asn1Type
Call test_cipherDecryptAEAD
Call test_cipherDecryptBytes
Call test_cipherDecryptHex
Call test_cipherEncryptAEAD
Call test_cipherEncryptBytes
Call test_cipherEncryptHex
Call test_cipherKeyWrap
Call test_cmsGetSigDataDigest
Call test_cmsMakeSigData_pss
Call test_cmsMakeSigDataFromSigValue
Call test_cmsQueryEnvData
Call test_cmsQuerySigData
Call test_cmsReadEnvDataToBytes
Call test_cmsReadSigDataToBytes
Call test_cnvBase58FromBytes
Call test_cnvByteEncoding
Call test_cnvBytesLen
Call test_cnvNumToBytes
Call test_cnvReverseBytes
Call test_cnvUTF8BytesFromLatin1
Call test_comprCompress
Call test_eccDHSharedSecret
Call test_eccReadKey
Call test_eccReadPrivateKey
Call test_eccMakeKeys
Call test_encrypt_empty
Call test_hash_empty
Call test_hash_utf8
Call test_hashHexFromHex
Call test_hmac_empty
Call test_hmacBytes
Call test_ocspMakeRequest
Call test_ocspReadResponse
Call test_padBytesBlock
Call test_padHexBlock
Call test_pbeKdf2
Call test_pbeKdf2Hex
Call test_pkiCompileTime
Call test_pkiLastError
Call test_rngBytes
Call test_rngGuid
Call test_rsaEncodeMsg
Call test_rsaEncrypt
Call test_rsaKeys
Call test_rsaKeyValue
Call test_rsaPublicKeyFromPrivate
Call test_rsaRawPrivate
Call test_rsaReadAnyPrivateKey
Call test_rsaReadAnyPublicKey
Call test_rsaToXMLString
Call test_sigSignData
Call test_sigSignFile
Call test_smimeQuery
Call test_unpadHex
Call test_wipeBytes
Call test_wipeString
Call test_x509QueryCert
Call test_x509ReadStringFromFile
' New in [v20.5]
Call test_hashLength
Call test_kdfBytes
Call test_kdfForCms
Call test_cmsEnvData_ecdh
Call test_x509MakeCert_X25519
Call test_pfxMakeFile_AES256
Call test_cmsMakeSigData_X25519
' New in [v20.6]
Call test_cmsEnvData_adv
' New in [v21.0]
Call test_errFormatErrorMessage
Call test_cipher_GCM
Call test_rsaReadPublicKey_CSR
Call test_x509MakeCert_Ex
Call test_hash_sha3
Call test_hmac_sha3
Call test_prfBytes
Call test_xofBytes
Debug.Print "ALL DONE."
End Sub
Public Sub test_cnvBytesLen()
Dim ab() As Byte
Debug.Print cnvBytesLen(ab) ' Expecting 0
ReDim ab(10) ' NB actually 11 elements (0..10)
Debug.Print cnvBytesLen(ab) ' 11
ab = vbNullString ' Set as empty array
Debug.Print cnvBytesLen(ab) ' 0
End Sub
Public Sub test_pkiLastError()
Dim s As String
' Valid function call, no error
s = hashHexFromHex("616263", PKI_HASH_SHA1)
Debug.Print "SHA1('abc')=" & s
' No error, so expecting empty string
Debug.Print "LastError='" & pkiLastError() & "'"
' Force an error
s = rsaFromXMLString("BADSTRING")
Debug.Print "rsaFromXMLString(ERROR) returns '" & s & "'"
Debug.Print "LastError='" & pkiLastError() & "'"
End Sub
Public Sub test_pkiErrorLookup()
Dim nErrCode As Long
For nErrCode = 1 To 11
Debug.Print nErrCode & " = " & pkiErrorLookup(nErrCode)
Next
End Sub
Public Sub test_aead()
Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim strOK As String
' GCM Test Case #03 (AES-128)
key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308")
iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888")
ct = cnvBytesFromHexStr("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4")
strOK = "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255"
Debug.Print "KY=" & cnvHexStrFromBytes(key)
Debug.Print "IV=" & cnvHexStrFromBytes(iv)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
' Must dimension any optional empty byte array
Dim lpAAD() As Byte
pt = cipherDecryptAEAD(ct, key, iv, lpAAD, PKI_AEAD_AES_128_GCM)
Debug.Print "PT=" & cnvHexStrFromBytes(pt)
End Sub
Public Sub test_cipherEncryptAEAD()
Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim lpDummy() As Byte
' GCM Test Case #03 (AES-128)
key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308")
iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888")
pt = cnvBytesFromHexStr("d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255")
ct = cipherEncryptAEAD(pt, key, iv, lpDummy, PKI_AEAD_AES_128_GCM Or PKI_IV_PREFIX)
Debug.Print "IV|CT=" & cnvHexStrFromBytes(ct)
Debug.Print "OK= " & _
"CAFEBABEFACEDBADDECAF888" & _
"42831EC2217774244B7221B784D0D49CE3AA212F2C02A4E035C17E2329ACA12E21D514B25466931C7D8F6A5AAC84AA051BA30B396A0AAC973D58E091473F59854D5C2AF327CD64A62CF35ABD2BA6FAB4"
End Sub
Public Sub test_x509QueryCert()
Debug.Print x509TextDumpToString("AliceRSASignByCarl.cer")
Debug.Print x509QueryCert("AliceRSASignByCarl.cer", "subjectName")
'Debug.Print asn1TextDumpToString("AliceRSASignByCarl.cer")
' Certificate with non-ASCII Spanish characters
Debug.Print "Default: " & x509QueryCert("alicia.cer", "issuerName")
Debug.Print "LATIN1: " & x509QueryCert("alicia.cer", "issuerName", PKI_X509_LATIN1)
Debug.Print "UTF8: " & x509QueryCert("alicia.cer", "issuerName", PKI_X509_UTF8)
Debug.Print "LDAP: " & x509QueryCert("alicia.cer", "issuerName", PKI_X509_LDAP)
' Certificate with Chinese characters
Debug.Print "Default: " & x509QueryCert("myca-chinadavid.cer", "subjectName")
Debug.Print "LDAP: " & x509QueryCert("myca-chinadavid.cer", "subjectName", PKI_X509_LDAP)
End Sub
Public Sub test_eccReadKey()
Dim curveName As String
Dim alicePrivateKeyHex As String
Dim ourPrivateKey As String
curveName = "X25519"
alicePrivateKeyHex = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"
' The new short way with a wrapper function
ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, curveName, PKI_ECC_PRIVATE_KEY)
Debug.Assert Len(ourPrivateKey) > 0
Debug.Print "Key curve=" & eccQueryKey(ourPrivateKey, "curveName", 0) & " keyBits=" & eccQueryKey(ourPrivateKey, "keyBits", 0)
End Sub
Public Sub test_eccReadPrivateKey()
Dim strIntKey As String
' Read in public key from file
strIntKey = eccReadPublicKey("myeckeyp256.pub")
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
eccQueryKey(strIntKey, "keyBits", 0) & _
" and is a " & _
IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(eccKeyHashCode(strIntKey))
' Read in private key from file
strIntKey = eccReadPrivateKey("myeckeyp256.p8", "password")
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
eccQueryKey(strIntKey, "keyBits", 0) & _
" and is a " & _
IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(eccKeyHashCode(strIntKey))
' Derive public key from private key
strIntKey = eccPublicKeyFromPrivate(strIntKey)
Debug.Assert Len(strIntKey) > 0
Debug.Print "Key curve=" & eccQueryKey(strIntKey, "curveName", 0) & " keyBits=" & _
eccQueryKey(strIntKey, "keyBits", 0) & _
" and is a " & _
IIf(eccQueryKey(strIntKey, "isPrivate") = "1", "Private", "Public") & " key"
Debug.Print eccQueryKey(strIntKey, "publicKey")
Debug.Print "KeyHashCode=0x" & Hex(eccKeyHashCode(strIntKey))
End Sub
Public Sub test_eccMakeKeys()
Dim r As Long
Dim strIntKey As String
' Generate brainpool key pair
r = eccMakeKeys("myeccBP256r1.pub", "myeccBP256r1.p8e", "brainpoolP256r1", "password1", "count=6000;prf=hmacWithSHA256", PKI_PBE_PBKDF2_AES128 Or PKI_KEY_FORMAT_PEM)
Debug.Print " returns " & r & " (expected 0)"
' Read in key to internal string
strIntKey = eccReadPrivateKey("myeccBP256r1.p8e", "password1")
Debug.Print "curveName=" & eccQueryKey(strIntKey, "curveName")
Debug.Print "keyBits=" & eccQueryKey(strIntKey, "keyBits")
End Sub
Public Sub test_eccDHSharedSecret()
Dim strCurveName As String
Dim ourPrivateKey As String
Dim theirPublicKey As String
Dim lpZZ() As Byte
' Ref: RFC7748 Section 6.1
Const alicePrivateKeyHex As String = "77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"
Const alicePublicKeyHex As String = "8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a"
Const bobPrivateKeyHex As String = "5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"
Const bobPublicKeyHex As String = "de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f"
strCurveName = "X25519"
' 1. Alice's private + Bob's public
ourPrivateKey = eccReadKeyByCurve(alicePrivateKeyHex, strCurveName, PKI_ECC_PRIVATE_KEY)
Debug.Print "Our key has " & eccQueryKey(ourPrivateKey, "keyBits") & " bits and is a " & _
IIf(eccQueryKey(ourPrivateKey, "isPrivate") = "1", "Private", "Public") & " key"
theirPublicKey = eccReadKeyByCurve(bobPublicKeyHex, strCurveName, PKI_ECC_PUBLIC_KEY)
Debug.Print "Their key has " & eccQueryKey(theirPublicKey, "keyBits") & " bits and is a " & _
IIf(eccQueryKey(theirPublicKey, "isPrivate") = "1", "Private", "Public") & " key"
' Compute shared secret
lpZZ = eccDHSharedSecret(ourPrivateKey, theirPublicKey)
Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ)
Debug.Print "OK=4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
' 2. Bob's private + Alice's public
ourPrivateKey = eccReadKeyByCurve(bobPrivateKeyHex, strCurveName, PKI_ECC_PRIVATE_KEY)
Debug.Print "Our key has " & eccQueryKey(ourPrivateKey, "keyBits") & " bits and is a " & _
IIf(eccQueryKey(ourPrivateKey, "isPrivate") = "1", "Private", "Public") & " key"
theirPublicKey = eccReadKeyByCurve(alicePublicKeyHex, strCurveName, PKI_ECC_PUBLIC_KEY)
Debug.Print "Their key has " & eccQueryKey(theirPublicKey, "keyBits") & " bits and is a " & _
IIf(eccQueryKey(theirPublicKey, "isPrivate") = "1", "Private", "Public") & " key"
' Compute shared secret
lpZZ = eccDHSharedSecret(ourPrivateKey, theirPublicKey)
Debug.Print "ZZ=" & cnvHexStrFromBytes(lpZZ)
Debug.Print "OK=4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
End Sub
Public Sub test_hashHexFromHex()
Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte
' Hex <-- Hex
strDigest = hashHexFromHex("616263", PKI_HASH_SHA256) ' "abc" in hex
Debug.Print strDigest
lpMessage = StrConv("abc", vbFromUnicode) ' "abc" in a byte array
' Hex <-- Bytes
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print strDigest
' Bytes <-- Bytes
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
' Hex <-- File
strDigest = hashHexFromFile("abc.txt", PKI_HASH_SHA256) ' "abc" in a text file
Debug.Print strDigest
' Bytes <-- File
lpDigest = hashFile("abc.txt", PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
Debug.Print "OK=" & "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"
End Sub
Public Sub test_hash_empty()
Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
lpDigest = hashBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA256)
Debug.Print strDigest
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA512)
Debug.Print strDigest
strDigest = hashHexFromBytes(lpMessage, PKI_HASH_SHA512)
Debug.Print strDigest
End Sub
Public Sub test_hmac_empty()
Dim strDigest As String
Dim lpMessage() As Byte
Dim lpDigest() As Byte
Dim lpKey() As Byte
lpKey = cnvBytesFromHexStr("0102030405060708090a0b0c0d0e0f10111213141516171819")
lpDigest = hmacBytes(lpMessage, lpKey, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
lpDigest = hmacBytes(lpMessage, lpKey, PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpDigest)
strDigest = hmacHexFromBytes(lpMessage, lpKey, PKI_HASH_SHA256)
Debug.Print strDigest
strDigest = hmacHexFromBytes(lpMessage, lpKey, PKI_HASH_SHA512)
Debug.Print strDigest
strDigest = hmacHexFromBytes(lpMessage, lpKey, PKI_HASH_SHA512)
Debug.Print strDigest
End Sub
Public Sub test_encrypt_empty()
Dim lpKey() As Byte
Dim lpIV() As Byte
Dim lpPlain() As Byte
Dim lpCipher() As Byte
' Empty key = NBG
lpCipher = cipherEncryptBytes(lpPlain, lpKey, lpIV, "Aes128/ECB", 0)
Debug.Print "CT=" & cnvHexStrFromBytes(lpCipher)
Debug.Print pkiGetLastError() & ": " & pkiGetLastError()
lpKey = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
lpCipher = cipherEncryptBytes(lpPlain, lpKey, lpIV, "Aes128/ECB", 0)
Debug.Print "CT=" & cnvHexStrFromBytes(lpCipher)
lpCipher = cipherEncryptBytes(lpPlain, lpKey, lpIV, "Aes128/ECB", 0)
Debug.Print "CT=" & cnvHexStrFromBytes(lpCipher)
End Sub
Public Sub test_cipherEncryptHex()
Dim strKeyHex As String
Dim strIvHex As String
Dim strPlainHex As String
Dim strCipherHex As String
strKeyHex = "0123456789ABCDEFF0E1D2C3B4A59687"
strIvHex = "FEDCBA9876543210FEDCBA9876543210"
strPlainHex = "4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F"
' Get encrypted output directly in hex
strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, strIvHex, "Aes128/CBC/OneAndZeroes", 0)
Debug.Print strCipherHex
' Same again with bytes
Dim lpKey() As Byte
Dim lpIV() As Byte
Dim lpPlain() As Byte
Dim lpCipher() As Byte
lpPlain = StrConv("Now is the time for all good men to", vbFromUnicode)
lpKey = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
lpIV = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
' Get encrypted output
lpCipher = cipherEncryptBytes(lpPlain, lpKey, lpIV, "Aes128/CBC/OneAndZeroes", 0)
Debug.Print cnvHexStrFromBytes(lpCipher)
' Same again using ECB mode with default PKCS#5 padding
' To pass an empty byte array for IV, create a dummy zero-length array
Dim lpDummy() As Byte
lpCipher = cipherEncryptBytes(lpPlain, lpKey, lpDummy, "Aes128/ECB", 0)
Debug.Print cnvHexStrFromBytes(lpCipher)
' Same again with hex using ECB mode with default PKCS#5 padding
' To pass a "null" IV in hex, just use the empty string
strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, "", "Aes128/ECB", 0)
Debug.Print strCipherHex
' Or vbNullString
strCipherHex = cipherEncryptHex(strPlainHex, strKeyHex, vbNullString, "Aes128/ECB", 0)
Debug.Print strCipherHex
End Sub
Public Sub test_cipherDecryptHex()
Dim strKeyHex As String
Dim strIvHex As String
Dim strPlainHex As String
Dim strCipherHex As String
strKeyHex = "0123456789ABCDEFF0E1D2C3B4A59687"
strIvHex = "FEDCBA9876543210FEDCBA9876543210"
strCipherHex = "C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B"
strPlainHex = cipherDecryptHex(strCipherHex, strKeyHex, strIvHex, "Aes128/CBC/OneAndZeroes")
Debug.Print "PT=" & strPlainHex
Debug.Print "PT='" & cnvStringFromHexStr(strPlainHex) & "'"
End Sub
Public Sub test_cipherEncryptBytes()
Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim dt() As Byte
Dim algstr As String
' PART 1
algstr = "Aes128/CBC/OneAndZeroes"
Debug.Print algstr
key = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
iv = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
' "Now is the time for all good men to"
pt = cnvBytesFromHexStr("4E6F77206973207468652074696D6520666F7220616C6C20676F6F64206D656E20746F")
ct = cipherEncryptBytes(pt, key, iv, algstr, 0)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
Debug.Print "OK=C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B"
dt = cipherDecryptBytes(ct, key, iv, algstr, 0)
Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'"
' PART 2 - Use CTR mode and prefix the IV in the output
algstr = "Aes128/CTR"
Debug.Print algstr & " + PREFIX"
ct = cipherEncryptBytes(pt, key, iv, algstr, PKI_IV_PREFIX)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
dt = cipherDecryptBytes(ct, key, iv, algstr, PKI_IV_PREFIX)
Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'"
' PART 3 - Use ECB mode and note we use a dummy empty byte array for the IV
Dim dummy() As Byte
algstr = "Aes128/ECB"
Debug.Print algstr
ct = cipherEncryptBytes(pt, key, dummy, algstr, 0)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
dt = cipherDecryptBytes(ct, key, dummy, algstr, 0)
Debug.Print "dt='" & StrConv(dt, vbUnicode) & "'"
End Sub
Public Sub test_cipherDecryptBytes()
Dim key() As Byte
Dim iv() As Byte
Dim ct() As Byte
Dim ok() As Byte
Dim dt() As Byte
key = cnvBytesFromHexStr("0123456789ABCDEFF0E1D2C3B4A59687")
iv = cnvBytesFromHexStr("FEDCBA9876543210FEDCBA9876543210")
ct = cnvBytesFromHexStr("C3153108A8DD340C0BCB1DFE8D25D2320EE0E66BD2BB4A313FB75C5638E9E1771D4CDA34FBFB7E74B321F9A2CF4EA61B")
' Decrypt
dt = cipherDecryptBytes(ct, key, iv, "Aes128/CBC/OneAndZeroes")
Debug.Print ("DT=" & cnvHexStrFromBytes(dt))
Debug.Print ("DT='" & StrConv(dt, vbUnicode) + "'")
End Sub
Public Sub test_padBytesBlock()
Dim lpInput() As Byte
Dim lpBlock() As Byte
Dim lpUnpadded() As Byte
lpInput = cnvBytesFromHexStr("FDFDFDFDFD")
Debug.Print "Input data = 0x" & cnvHexStrFromBytes(lpInput)
lpBlock = padBytesBlock(lpInput, 8, 0)
Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock)
' Unpad
lpUnpadded = padUnpadBytes(lpBlock, 8, 0)
Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded)
' Special corner case - output is the empty string
lpBlock = cnvBytesFromHexStr("0808080808080808")
Debug.Print "Padded data = 0x" & cnvHexStrFromBytes(lpBlock)
lpUnpadded = padUnpadBytes(lpBlock, 8, 0)
Debug.Print "Unpadded data = 0x" & cnvHexStrFromBytes(lpUnpadded)
End Sub
Public Sub test_padHexBlock()
Dim strInputHex As String
Dim strOutputHex As String
strInputHex = "FDFDFD"
Debug.Print "Hex input =" & strInputHex
strOutputHex = padHexBlock(strInputHex, 8, 0)
Debug.Print "Padded data=" & strOutputHex
Debug.Print "Unpadded =" & padUnpadHex(strOutputHex, 8, 0)
strOutputHex = padHexBlock(strInputHex, 8, PKI_PAD_1ZERO)
Debug.Print "Padded data=" & strOutputHex
Debug.Print "Unpadded =" & padUnpadHex(strOutputHex, 8, PKI_PAD_1ZERO)
strOutputHex = padHexBlock(strInputHex, 8, PKI_PAD_AX923)
Debug.Print "Padded data=" & strOutputHex
Debug.Print "Unpadded =" & padUnpadHex(strOutputHex, 8, PKI_PAD_AX923)
End Sub
Public Sub test_unpadHex()
Dim strInputHex As String
Dim strOutputHex As String
strInputHex = "FFFFFFFFFF030303"
Debug.Print "Hex input =" & strInputHex
strOutputHex = padUnpadHex(strInputHex, PKI_BLK_TDEA_BYTES, 0)
Debug.Print "Unpadded =" & strOutputHex
' Output is empty string
strInputHex = "0808080808080808"
Debug.Print "Hex input =" & strInputHex
strOutputHex = padUnpadHex(strInputHex, PKI_BLK_TDEA_BYTES, 0)
Debug.Print "Unpadded =" & strOutputHex
' Bad input data results in the same data being returned
strInputHex = "FFFFFFFFFFFFFFFF"
Debug.Print "Hex input =" & strInputHex
strOutputHex = padUnpadHex(strInputHex, PKI_BLK_TDEA_BYTES, 0)
Debug.Print "Unpadded =" & strOutputHex
If Len(strOutputHex) = Len(strInputHex) Then
Debug.Print "DECRYPTION ERROR"
End If
Debug.Assert Len(strOutputHex) = Len(strInputHex)
End Sub
Public Sub test_rngBytes()
Dim i As Integer
For i = 1 To 10
Debug.Print cnvHexStrFromBytes(rngBytes(32))
Next
End Sub
Public Sub test_rngGuid()
Dim i As Integer
For i = 1 To 5
Debug.Print rngGuid()
Next
End Sub
Public Sub test_asn1TextDumpToString()
Dim strInput As String
Dim strOutput As String
strInput = "MAQwAgUA"
Debug.Print "Input: " & strInput
strOutput = asn1TextDumpToString(strInput)
Debug.Print strOutput
Debug.Print asn1TextDumpToString(strInput, PKI_ASN1_NOCOMMENTS)
End Sub
Public Sub test_asn1Type()
Debug.Print asn1Type("AliceRSASignByCarl.cer", 0)
Debug.Print asn1Type("BobPrivRSAEncrypt.p8e", 0)
Debug.Print asn1Type("bad.file", 0)
End Sub
Public Sub test_cipherDecryptAEAD()
Dim key() As Byte
Dim iv() As Byte
Dim pt() As Byte
Dim ct() As Byte
Dim strOK As String
' GCM Test Case #03 (AES-128)
key = cnvBytesFromHexStr("feffe9928665731c6d6a8f9467308308")
iv = cnvBytesFromHexStr("cafebabefacedbaddecaf888")
ct = cnvBytesFromHexStr("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f59854d5c2af327cd64a62cf35abd2ba6fab4")
strOK = "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255"
Dim lpAAD() As Byte ' Declare empty array for NULL input
pt = cipherDecryptAEAD(ct, key, iv, lpAAD, PKI_AEAD_AES_128_GCM)
Debug.Print "PT=" & cnvHexStrFromBytes(pt)
Debug.Print "OK=" & strOK
End Sub
Public Sub test_smimeQuery()
Dim strFileIn As String
Dim strQuery As String
strFileIn = "cmsalice2bob-smime-env.txt"
Debug.Print "FILE: " & strFileIn
strQuery = "content-type"
Debug.Print strQuery & "=" & smimeQuery(strFileIn, strQuery, 0)
strQuery = "smime-type"
Debug.Print strQuery & "=" & smimeQuery(strFileIn, strQuery, 0)
strQuery = "encoding"
Debug.Print strQuery & "=" & smimeQuery(strFileIn, strQuery, 0)
strQuery = "filename"
Debug.Print strQuery & "=" & smimeQuery(strFileIn, strQuery, 0)
End Sub
Public Sub test_rsaToXMLString()
Dim strPrivateKey As String
strPrivateKey = rsaReadPrivateKey("AlicePrivRSASign.p8e", "password")
Debug.Print rsaToXMLString(strPrivateKey, 0)
Debug.Print rsaToXMLString(strPrivateKey, PKI_XML_EXCLPRIVATE Or PKI_XML_HEXBINARY)
Debug.Print rsaToXMLStringEx(strPrivateKey, "ds", PKI_XML_EXCLPRIVATE)
' Now derive internal private key string from XML
Dim strXML As String
Dim strKey As String
strXML = rsaToXMLString(strPrivateKey)
strKey = rsaFromXMLString(strXML)
Debug.Print "Key length = " & rsaKeyBits(strKey) & " bits"
Debug.Print "Key length in bytes = " & rsaKeyBytes(strKey) & " bytes"
End Sub
Public Sub test_rsaEncrypt()
Dim strPubKeyFile As String
Dim lpMsg() As Byte
Dim lpEnc() As Byte
Dim strPriKeyFile As String
Dim lpDec() As Byte
' Message to be encrypted:
lpMsg = cnvBytesFromHexStr("6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34")
Debug.Print "MSG=" & cnvHexStrFromBytes(lpMsg)
' Use RSA-OEAP with SHA-256
strPubKeyFile = "rsa-oaep-1.pub"
lpEnc = rsaEncrypt(lpMsg, strPubKeyFile, PKI_EME_OAEP + PKI_HASH_SHA256)
' NB different each time...
Debug.Print "ENC=" & cnvHexStrFromBytes(lpEnc)
strPriKeyFile = "rsa-oaep-1.p8"
lpDec = rsaDecrypt(lpEnc, strPriKeyFile, "", PKI_EME_OAEP + PKI_HASH_SHA256)
Debug.Print "DEC=" & cnvHexStrFromBytes(lpDec)
strPubKeyFile = "rsa-oaep-1.pub"
' Set seed to fixed value for debugging....
lpEnc = rsaEncrypt(lpMsg, strPubKeyFile, PKI_EME_OAEP, "seed=18b776ea21069d69776a33e96bad48e1dda0a5ef")
Debug.Print "ENC=" & cnvHexStrFromBytes(lpEnc)
Debug.Print "OK =354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb" _
& "21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535f" _
& "a9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426" _
& "d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a"
' Decrypt
strPriKeyFile = "rsa-oaep-1.p8"
lpDec = rsaDecrypt(lpEnc, strPriKeyFile, "", PKI_EME_OAEP)
Debug.Print "DEC=" & cnvHexStrFromBytes(lpDec)
End Sub
Public Sub test_cnvUTF8BytesFromLatin1()
Dim strData As String
Dim lpDataUTF8() As Byte
strData = "abcóéíáñ"
Debug.Print "Latin-1 string='" & strData & "'"
Debug.Print " (" & Len(strData) & " characters)"
lpDataUTF8 = cnvUTF8BytesFromLatin1(strData)
Debug.Print "UTF-8=(0x)" & cnvHexStrFromBytes(lpDataUTF8)
Debug.Print " (" & cnvBytesLen(lpDataUTF8) & " bytes)"
Debug.Print "cnvCheckUTF8Bytes returns " & cnvCheckUTF8Bytes(lpDataUTF8) & " (expected 2)"
' And back to a string
Dim strLatin1 As String
strLatin1 = cnvLatin1FromUTF8Bytes(lpDataUTF8)
Debug.Print "Back to string='" & strLatin1 & "'"
End Sub
Public Sub test_cmsReadEnvDataToBytes()
Dim strPrivateKey As String
Dim lpData() As Byte
Dim strData As String
' Read in private key to internal key string
strPrivateKey = rsaReadPrivateKey("BobPrivRSAEncrypt.p8e", "password")
Debug.Assert Len(strPrivateKey) > 0
' 1. Decrypted content is UTF-8 encoded
lpData = cmsReadEnvDataToBytes("cmsalice2bob_utf8.p7m", "", strPrivateKey, 0)
Debug.Assert cnvBytesLen(lpData) > 0
Debug.Print "HEX(PT)=" & cnvHexStrFromBytes(lpData)
' Convert from UTF-8-encoded bytes to VB Unicode string
strData = cnvLatin1FromUTF8Bytes(lpData)
Debug.Print "PT=" & strData
' 2. Decrypted content is plain ANSI string
strData = cmsReadEnvDataToString("cms2bobandcarl.p7m", "", strPrivateKey, 0)
Debug.Print "PT=" & strData
' Clean up
strPrivateKey = wipeString(strPrivateKey)
End Sub
Public Sub test_cmsQueryEnvData()
Dim strQuery As String
Dim strOutput As String
Dim strEnvDataFile As String
strEnvDataFile = "5.1.bin"
Debug.Print "FILE: " & strEnvDataFile
strQuery = "keyEncryptionAlgorithm"
strOutput = cmsQueryEnvData(strEnvDataFile, strQuery, 0)
Debug.Print strQuery & " ==> " & strOutput
strQuery = "contentEncryptionAlgorithm"
strOutput = cmsQueryEnvData(strEnvDataFile, strQuery, 0)
Debug.Print strQuery & " ==> " & strOutput
strQuery = "sizeofEncryptedContent"
strOutput = cmsQueryEnvData(strEnvDataFile, strQuery, 0)
Debug.Print strQuery & " ==> " & strOutput
End Sub
Public Sub test_pkiCompileTime()
Debug.Print pkiCompileTime()
Debug.Print pkiModuleInfo()
Debug.Print pkiModuleName()
Debug.Print pkiPlatform()
End Sub
Public Sub test_cipherKeyWrap()
Dim lpWK() As Byte
Dim lpKeyData() As Byte
Dim lpKEK() As Byte
lpKeyData = cnvBytesFromHexStr("00112233 44556677 8899aabb ccddeeff")
lpKEK = cnvBytesFromHexStr("c17a44e8 e28d7d64 81d1ddd5 0a3b8914")
' NB Specific nonzero option required in nOptions
lpWK = cipherKeyWrap(lpKeyData, lpKEK, PKI_BC_AES128)
Debug.Print "WK=" & cnvHexStrFromBytes(lpWK)
Debug.Print "OK=503D75C73630A7B02ECF51B9B29B907749310B77B0B2E054"
' Now unwrap the KEK
Dim lpKeyUnwrapped() As Byte
lpKeyUnwrapped = cipherKeyUnwrap(lpWK, lpKEK, PKI_BC_AES128)
Debug.Print "KY=" & cnvHexStrFromBytes(lpKeyUnwrapped)
Debug.Print "OK=00112233445566778899AABBCCDDEEFF"
End Sub
Public Sub test_comprCompress()
Dim strPlain As String
Dim lpToCompress() As Byte
Dim lpCompressed() As Byte
Dim lpUncompressed() As Byte
strPlain = "hello, hello, hello. This is a 'hello world' message " & _
"for the world, repeat, for the world."
lpToCompress = StrConv(strPlain, vbFromUnicode)
lpCompressed = comprCompress(lpToCompress)
Debug.Print "OK= " & "789CCB48CDC9C9D751C840A2F4144232328B15802851411D2CA2509E5F9493A2AE909B5A5C9C989EAA90965FA45092910A11D651284A2D484D2CD14115D6030086D11F4E"
Debug.Print "COMPRESSED=" & cnvHexStrFromBytes(lpCompressed)
lpUncompressed = comprUncompress(lpCompressed)
Debug.Print "'" & StrConv(lpUncompressed, vbUnicode); "'"
End Sub
Public Sub test_hmacBytes()
Dim lpData() As Byte
Dim lpKey() As Byte
Dim lpDigest() As Byte
Dim strDigest As String
' Test case 4 from RFC 2202 and RFC 4231
lpKey = cnvBytesFromHexStr("0102030405060708090a0b0c0d0e0f10111213141516171819")
' data = 0xcd repeated 50 times
lpData = cnvBytesFromHexStr("cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" & _
"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd")
' Bytes <-- Bytes
lpDigest = hmacBytes(lpData, lpKey, PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & cnvHexStrFromBytes(lpDigest)
Debug.Print "CORRECT =82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b"
' Hex <-- Bytes
strDigest = hmacHexFromBytes(lpData, lpKey, PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & strDigest
' Hex <-- Hex
' Test case 1 from RFC 2202 and RFC 4231
' Data = "Hi There"
strDigest = hmacHexFromHex("4869205468657265", "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", PKI_HASH_SHA256)
Debug.Print "HMAC-SHA-256=" & strDigest
Debug.Print "CORRECT =b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"
End Sub
Public Sub test_hmac_sha3()
Dim lpData() As Byte
Dim lpKey() As Byte
Dim lpDigest() As Byte
Dim strDigest As String
Dim strKeyHex As String
' NIST HMAC_SHA3-256.pdf Sample #1
lpKey = cnvBytesFromHexStr("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")
lpData = StrConv("Sample message for keylen<blocklen", vbFromUnicode)
' Bytes <-- Bytes
lpDigest = hmacBytes(lpData, lpKey, PKI_HASH_SHA3_256)
Debug.Print "HMAC-SHA3-256=" & cnvHexStrFromBytes(lpDigest)
Debug.Print "CORRECT =4fe8e202c4f058e8dddc23d8c34e467343e23555e24fc2f025d598f558f67205"
' Hex <-- Bytes
strDigest = hmacHexFromBytes(lpData, lpKey, PKI_HASH_SHA3_256)
Debug.Print "HMAC-SHA3-256=" & strDigest
' Hex <-- Hex
' NIST HMAC_SHA3-224.pdf Sample #3
' Data = "Sample message for keylen>blocklen"
strKeyHex = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" & _
"202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f" & _
"404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f" & _
"606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f" & _
"808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f" & _
"a0a1a2a3a4a5a6a7a8a9aaab"
strDigest = hmacHexFromHex("53616d706c65206d65737361676520666f72206b65796c656e3e626c6f636b6c656e", strKeyHex, PKI_HASH_SHA3_224)
Debug.Print "HMAC-SHA3-224=" & strDigest
Debug.Print "CORRECT =078695eecc227c636ad31d063a15dd05a7e819a66ec6d8de1e193e59"
End Sub
Public Sub test_cmsGetSigDataDigest()
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) & "]"
End Sub
Public Sub test_cmsMakeSigData_pss()
Dim strPriKey As String
Dim lpData() As Byte
Dim strCmsFile As String
Dim r As Long
Dim strQuery As String
Dim s As String
' Read in private key to internal key string
strPriKey = rsaReadPrivateKey("User_RSA_2048.p8e", "password")
Debug.Assert Len(strPriKey) > 0
Debug.Print "Private key is " & RSA_KeyBits(strPriKey) & " bits"
' Get input data in a byte array
lpData = StrConv("This is some sample content.", vbFromUnicode)
' Make signed-data file
strCmsFile = "SignedData_PSS_384.p7m"
r = cmsMakeSigDataFromBytes(strCmsFile, lpData, "User_RSA_2048.cer", strPriKey, PKI_SIG_RSA_PSS_SHA384 Or PKI_CMS_INCLUDE_ATTRS)
Debug.Print "cmsMakeSigDataFromBytes returns " & r & " (expecting 0)"
Debug.Assert 0 = r
' Query the resulting file
Debug.Print asn1Type(strCmsFile)
strQuery = "signatureAlgorithm"
s = cmsQuerySigData(strCmsFile, strQuery)
Debug.Print strQuery & "='" & s & "'"
strQuery = "digestAlgorithm"
s = cmsQuerySigData(strCmsFile, strQuery)
Debug.Print strQuery & "='" & s & "'"
' Validate it
r = CMS_VerifySigData(strCmsFile, "", "", 0)
Debug.Print "CMS_VerifySigData returns " & r & " (expecting 0)"
Debug.Assert 0 = r
End Sub
Public Sub test_cmsMakeSigDataFromSigValue()
Dim strDataHex As String
Dim strSigHex As String
Dim strCertFile As String
Dim strCmsFile As String
Dim r As Long
' Data to be signed in hex format (punctuation will be removed)
strDataHex = "54:68:69:73:20:69:73:20:73:6f:6d:65:20:73:61:6d" & _
"70:6c:65:20:63:6f:6e:74:65:6e:74:2e"
' The signature (generated by the smart card) is:
strSigHex = "2F:23:82:D2:F3:09:5F:B8:0C:58:EB:4E:9D:BF:89:9A" & _
"81:E5:75:C4:91:3D:D3:D0:D5:7B:B6:D5:FE:94:A1:8A" & _
"AC:E3:C4:84:F5:CD:60:4E:27:95:F6:CF:00:86:76:75" & _
"3F:2B:F0:E7:D4:02:67:A7:F5:C7:8D:16:04:A5:B3:B5" & _
"E7:D9:32:F0:24:EF:E7:20:44:D5:9F:07:C5:53:24:FA" & _
"CE:01:1D:0F:17:13:A7:2A:95:9D:2B:E4:03:95:14:0B" & _
"E9:39:0D:BA:CE:6E:9C:9E:0C:E8:98:E6:55:13:D4:68" & _
"6F:D0:07:D7:A2:B1:62:4C:E3:8F:AF:FD:E0:D5:5D:C7"
strCertFile = "AliceRSASignByCarl.cer"
strCmsFile = "BasicSignByAliceExternal.p7m"
' Create the signed-data file
r = cmsMakeSigDataFromSigValue(strCmsFile, cnvFromHex(strSigHex), cnvFromHex(strDataHex), strCertFile, PKI_SIG_RSA_SHA1)
Debug.Print "cmsMakeSigDataFromSigValue returns " & r & " (expected 0)"
Debug.Print asn1Type(strCmsFile)
End Sub
Public Sub test_cmsQuerySigData()
Dim strCmsFile As String
Dim strQuery As String
Dim strOutput As String
strCmsFile = "4.6.bin"
Debug.Print "FILE: " & strCmsFile
strQuery = "version"
strOutput = cmsQuerySigData(strCmsFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"
strQuery = "digestAlgorithm"
strOutput = cmsQuerySigData(strCmsFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"
strCmsFile = "4.7.bin"
Debug.Print "FILE: " & strCmsFile
strQuery = "version"
strOutput = cmsQuerySigData(strCmsFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"
strQuery = "signatureAlgorithm"
strOutput = cmsQuerySigData(strCmsFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"
strCmsFile = "BasicSignByAlice_attr.bin"
Debug.Print "FILE: " & strCmsFile
strQuery = "signingTime"
strOutput = cmsQuerySigData(strCmsFile, strQuery)
Debug.Print strQuery & " ==> [" & strOutput & "]"
End Sub
Public Sub test_cmsReadSigDataToBytes()
Dim lpData() As Byte
Dim strData As String
' Read UTF-8 encoded data from signed-data CMS object
lpData = cmsReadSigDataToBytes("basicsignedbyalice_utf8.p7m")
Debug.Assert cnvBytesLen(lpData) > 0
Debug.Print "HEX(CONTENT)=" & cnvHexStrFromBytes(lpData)
' Convert from UTF-8-encoded bytes to VB Unicode string
strData = cnvLatin1FromUTF8Bytes(lpData)
Debug.Print "CONTENT='" & strData & "'"
End Sub
Public Sub test_cnvBase58FromBytes()
Dim lpData() As Byte
Dim strBase58 As String
lpData = cnvBytesFromHexStr("00010966776006953D5567439E5E39F86A0D273BEED61967F6")
strBase58 = cnvBase58FromBytes(lpData)
Debug.Print strBase58
' Decode base58 string to byte array
lpData = cnvBase58ToBytes(strBase58)
Debug.Print cnvHexStrFromBytes(lpData)
strBase58 = "DiManagement"
Debug.Print "INPUT: " & strBase58
lpData = cnvBase58ToBytes(strBase58)
Debug.Print cnvHexStrFromBytes(lpData)
End Sub
Public Sub test_cnvByteEncoding()
Dim lpLatin1() As Byte
Dim lpUTF8() As Byte
' Set up a byte array with the following 4 characters encoded in Latin-1
' U+0061 LATIN SMALL LETTER A
' U+00E9 LATIN SMALL LETTER E WITH ACUTE
' U+00F1 LATIN SMALL LETTER N WITH TILDE
' U+0062 LATIN SMALL LETTER B
lpLatin1 = cnvBytesFromHexStr("61E9F162")
Debug.Print "Latin-1=" & cnvHexStrFromBytes(lpLatin1) & " (" & cnvBytesLen(lpLatin1) & " bytes)"
lpUTF8 = cnvByteEncoding(lpLatin1, PKI_CNV_UTF8_FROM_LATIN1)
Debug.Print "UTF-8 =" & cnvHexStrFromBytes(lpUTF8) & " (" & cnvBytesLen(lpUTF8) & " bytes)"
' And back again the other way...
lpLatin1 = cnvByteEncoding(lpUTF8, PKI_CNV_LATIN1_FROM_UTF8)
Debug.Print "Latin-1=" & cnvHexStrFromBytes(lpLatin1) & " (" & cnvBytesLen(lpLatin1) & " bytes)"
End Sub
Public Sub test_cnvNumToBytes()
Dim lpData() As Byte
Dim nBytes As Long
Dim nNumber As Long
nNumber = &HDEADBEEF
Debug.Print "INPUT=0x" & Hex(nNumber) & " (" & nNumber & ")"
' Default big-endian order
lpData = cnvNumToBytes(nNumber)
Debug.Print "cnvNumToBytes(BE)=" & cnvHexStrFromBytes(lpData)
' Little-endian order
lpData = cnvNumToBytes(nNumber, PKI_CNV_LITTLE_ENDIAN)
Debug.Print "cnvNumToBytes(LE)=" & cnvHexStrFromBytes(lpData)
End Sub
Public Sub test_cnvReverseBytes()
Debug.Print cnvToHex(cnvReverseBytes(cnvFromHex("DEADBEEF")))
' EFBEADDE
End Sub
Public Sub test_pbeKdf2()
Dim lpDK() As Byte
Dim strPassword As String
Dim lpSalt() As Byte
Dim nCount As Long
strPassword = "password"
lpSalt = cnvBytesFromHexStr("78 57 8E 5A 5D 63 CB 06")
nCount = 2048
lpDK = pbeKdf2(24, StrConv(strPassword, vbFromUnicode), lpSalt, nCount)
Debug.Print "Derived key = " & cnvHexStrFromBytes(lpDK)
Debug.Print "Correct key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"
lpDK = pbeKdf2(24, StrConv(strPassword, vbFromUnicode), lpSalt, nCount, PKI_HASH_SHA256)
Debug.Print "Derived key {HMAC-SHA-256} = " & cnvHexStrFromBytes(lpDK)
Debug.Print "Correct key {HMAC-SHA-256} = 97B5A91D35AF542324881315C4F849E327C4707D1BC9D322"
End Sub
Public Sub test_pbeKdf2Hex()
Dim strDK As String
Dim strPassword As String
Dim strSaltHex As String
Dim nCount As Long
strPassword = "password"
strSaltHex = "78578E5A5D63CB06"
nCount = 2048
strDK = pbeKdf2Hex(24, strPassword, strSaltHex, nCount)
Debug.Print "Derived key = " & strDK
Debug.Print "Correct key = BFDE6BE94DF7E11DD409BCE20A0255EC327CB936FFE93643"
End Sub
Public Sub test_ocspMakeRequest()
Dim strOcsp As String
strOcsp = ocspMakeRequest("UTNUSERFirst-Object.cer", "dims.cer", PKI_HASH_SHA1)
Debug.Print strOcsp
' Pass serial number instead of filename
strOcsp = ocspMakeRequest("UTNUSERFirst-Object.cer", "#x 00 FB C7 23 22 8C 8C 80 22 D8 85 92 23 DE E7 06 60", PKI_HASH_SHA1)
Debug.Print strOcsp
End Sub
Public Sub test_ocspReadResponse()
Dim strBuf As String
strBuf = ocspReadResponse("ocsp_response_ok_dims.dat", "UTNUSERFirst-Object.cer")
Debug.Print strBuf
End Sub
Public Sub test_rsaKeys()
Dim r As Long
Dim strIntKeyStr As String
Dim strKeyFile As String
Dim nPriHashCode As Long
Dim nPubHashCode As Long
Dim strASN1 As String
' Make a pair of 512-bit keys (just a demo for speed, too short in practice)
Debug.Print "About to create an RSA key pair..."
r = rsaMakeKeys("myrsa512.pub", "myrsa512.p8e", "password", 512)
Debug.Print "rsaMakeKeys returns " & r
Debug.Assert r = 0
' Display the type of ASN.1 files we created
Debug.Print asn1Type("myrsa512.pub")
Debug.Print asn1Type("myrsa512.p8e")
' Read in the private key to an internal key string
strIntKeyStr = rsaReadPrivateKey("myrsa512.p8e", "password")
Debug.Assert Len(strIntKeyStr) > 0
Debug.Print "Private key size=" & RSA_KeyBits(strIntKeyStr) & " bits"
nPriHashCode = RSA_KeyHashCode(strIntKeyStr)
Debug.Print "KeyHashCode=0x" & Hex(nPriHashCode)
' Save with stronger encryption
strKeyFile = "myrsa512ex.p8e"
r = rsaSaveEncKey(strKeyFile, strIntKeyStr, "password1", "count=6666;prf=hmacWithSHA384", PKI_PBE_PBKDF2_AES192)
Debug.Assert r = 0
' Show ASN.1 dump
strASN1 = asn1TextDumpToString(strKeyFile)
Debug.Print strASN1
' Expected to contain certain strings consistent with arguments above
Debug.Assert InStr(strASN1, "hmacWithSHA384")
Debug.Assert InStr(strASN1, "--6666")
Debug.Assert InStr(strASN1, "aes192-CBC")
Debug.Print asn1Type(strKeyFile)
' Save in unencrypted form
strKeyFile = "myrsa512.p8"
r = rsaSaveKey(strKeyFile, strIntKeyStr)
Debug.Assert r = 0
Debug.Print asn1Type(strKeyFile)
' Save in SSL unencrypted form
strKeyFile = "myrsa512.key"
r = rsaSaveKey(strKeyFile, strIntKeyStr, PKI_KEY_FORMAT_SSL)
Debug.Assert r = 0
Debug.Print asn1Type(strKeyFile)
' Read in the public key to an internal key string
strIntKeyStr = rsaReadPublicKey("myrsa512.pub")
Debug.Assert Len(strIntKeyStr) > 0
Debug.Print "Key size=" & RSA_KeyBits(strIntKeyStr) & " bits"
nPubHashCode = RSA_KeyHashCode(strIntKeyStr)
Debug.Print "KeyHashCode=0x" & Hex(nPubHashCode)
' The two hashcodes should be equal
Debug.Assert nPubHashCode = nPriHashCode
' Save in PEM form
strKeyFile = "myrsa512.pem"
r = rsaSaveKey(strKeyFile, strIntKeyStr, PKI_KEY_FORMAT_PEM)
Debug.Assert r = 0
Debug.Print asn1Type(strKeyFile)
' Save in SSL form
strKeyFile = "myrsa512ssl.pem"
r = rsaSaveKey(strKeyFile, strIntKeyStr, PKI_KEY_FORMAT_SSL)
Debug.Assert r = 0
Debug.Print asn1Type(strKeyFile)
End Sub
Public Sub test_rsaKeyValue()
Dim strKeyString As String
Dim strFieldName As String
Dim strValue As String
strKeyString = rsaReadPublicKey("AliceRSASignByCarl.cer")
strFieldName = "Modulus"
strValue = rsaKeyValue(strKeyString, strFieldName)
Debug.Print strFieldName & "=" & strValue
strFieldName = "Exponent"
strValue = rsaKeyValue(strKeyString, strFieldName)
Debug.Print strFieldName & "=" & strValue
End Sub
Public Sub test_rsaPublicKeyFromPrivate()
Dim strPrivateKey As String
Dim strPublicKey As String
' Read in private key to internal string
strPrivateKey = rsaReadPrivateKey("BobPrivRSAEncrypt.p8e", "password")
Debug.Assert Len(strPrivateKey) > 0
Debug.Print "Private key length = " & rsaKeyBits(strPrivateKey) & " bits"
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strPrivateKey))
' Convert to public key string
strPublicKey = rsaPublicKeyFromPrivate(strPrivateKey)
Debug.Print "Public key length = " & rsaKeyBits(strPublicKey) & " bits"
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strPublicKey))
End Sub
Public Sub test_rsaRawPrivate()
Dim strPrivateKey As String
Dim pt() As Byte
Dim ct() As Byte
strPrivateKey = rsaReadPrivateKey("rsa508.p8e", "password")
Debug.Assert Len(strPrivateKey) > 0
pt = cnvBytesFromHexStr("0001ffffffffffffffffffffffffffff" & _
"ffffffffffffffffffffffffff003020" & _
"300c06082a864886f70d020205000410" & _
"dca9ecf1c15c1bd266aff9c8799365cd")
ct = rsaRawPrivate(pt, strPrivateKey)
Debug.Print "CT=" & cnvHexStrFromBytes(ct)
Dim strPublicKey As String
Dim dt() As Byte
strPublicKey = rsaReadPublicKey("Rsa508.pub")
Debug.Assert Len(strPublicKey) > 0
dt = rsaRawPublic(ct, strPublicKey)
Debug.Print "DT=" & cnvHexStrFromBytes(dt)
End Sub
Public Sub test_rsaReadAnyPrivateKey()
Dim strIntKey As String
strIntKey = rsaReadAnyPrivateKey("AlicePrivRSASign.p8e", "password")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
' Unencrypted key
strIntKey = rsaReadAnyPrivateKey("AlicePrivRSASign.pri", "")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
' Key in XML form
strIntKey = rsaReadAnyPrivateKey("alice-pri.xml", "")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
End Sub
Public Sub test_rsaReadAnyPublicKey()
Dim strIntKey As String
strIntKey = rsaReadAnyPublicKey("AlicePubRSA.pub")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
' X.509 certificate
strIntKey = rsaReadAnyPublicKey("AliceRSASignByCarl.cer")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
' Key in XML form
strIntKey = rsaReadAnyPublicKey("alice-pub.xml")
Debug.Print strIntKey
Debug.Print "KeyHashCode=0x" & Hex(RSA_KeyHashCode(strIntKey))
End Sub
Public Sub test_x509ReadStringFromFile()
Dim strCertString As String
strCertString = x509ReadStringFromFile("AliceRSASignByCarl.cer")
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
strCertString = x509ReadCertStringFromP7Chain("alice_bob_carl_certs.p7c", 3)
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
Debug.Print "HashIssuerAndSN=" & x509HashIssuerAndSN(strCertString, PKI_HASH_SHA256)
'Invalid index
strCertString = x509ReadCertStringFromP7Chain("alice_bob_carl_certs.p7c", 0)
Debug.Print "[" & strCertString & "]"
strCertString = x509ReadCertStringFromPFX("alice.p12", "password")
Debug.Print strCertString
Debug.Print "CertThumb=" & x509CertThumb(strCertString)
Debug.Print "HashIssuerAndSN=" & x509HashIssuerAndSN(strCertString)
Dim strP7File As String
Dim nIndex As Long
Dim nCerts As Long
strP7File = "alice_bob_carl_certs.p7c"
' Call core fn with zero index to find count
nCerts = X509_ReadCertStringFromP7Chain("", 0, strP7File, 0, 0)
Debug.Print "nCerts=" & nCerts
For nIndex = 1 To nCerts
strCertString = x509ReadCertStringFromP7Chain(strP7File, nIndex)
Debug.Print "subjectName: " & x509QueryCert(strCertString, "subjectName")
Next
End Sub
Public Sub test_rsaEncodeMsg()
Dim lpData() As Byte
Dim lpBlock() As Byte
Dim lpDecoded() As Byte
Dim nBlockLen As Long
nBlockLen = 512 \ 8
lpData = cnvBytesFromHexStr("DEADBEEF")
lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EME_PKCSV1_5)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EME_PKCSV1_5)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)
lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EME_OAEP)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EME_OAEP)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)
lpBlock = rsaEncodeMsg(nBlockLen, lpData, PKI_EMSIG_PKCSV1_5 Or PKI_HASH_SHA256)
Debug.Print cnvHexStrFromBytes(lpBlock)
lpDecoded = rsaDecodeMsg(lpBlock, PKI_EMSIG_PKCSV1_5)
Debug.Print "DECODED=" & cnvHexStrFromBytes(lpDecoded)
Debug.Print "DIGEST =" & hashHexFromBytes(lpData, PKI_HASH_SHA256)
End Sub
Public Sub test_sigSignData()
Dim lpData() As Byte
Dim strSig As String
lpData = StrConv("abc", vbFromUnicode)
strSig = sigSignData(lpData, "AlicePrivRSASign.p8e", "password", "sha1WithRSAEncryption")
Debug.Print "SIG=" & strSig
Debug.Print "OK =" & "YK1aePtKQDDsVCyJdM0V9VOE6DZVTO3Z ... AmHH6QIsDZ8R8="
' Now verify the signature using Alice's certificate
Dim r As Long
r = sigVerifyData(strSig, lpData, "AliceRSASignByCarl.cer", "sha1WithRSAEncryption")
Debug.Print "sigVerifyData returns " & r & " (expected 0)"
End Sub
Public Sub test_sigSignFile()
Dim strSig As String
strSig = sigSignFile("abc.txt", "AlicePrivRSASign.p8e", "password", "", PKI_SIG_SHA256RSA)
Debug.Print "SIG=" & strSig
Debug.Print "OK =" & "tLy6hJadL4w9JI/A/qLCG0V...peD1VHSzgu/qirjOaA="
End Sub
Public Sub test_hash_utf8()
Dim strData As String
Dim strDigest As String
' Our original string data
strData = "Estándares de Electrónica de México para mañana"
' Compute SHA-1 hash over UTF-8 encoded byte array
strDigest = hashHexFromBytes(cnvUTF8BytesFromLatin1(strData), PKI_HASH_SHA1)
Debug.Print "Digest=" & strDigest
Debug.Print "OK = " & "3eeb1871c14cd03af6d586850e3058fa80cbbe51"
End Sub
Public Sub test_wipeString()
Dim strData As String
strData = "my deepest secrets"
strData = wipeString(strData)
Debug.Print "AFTER: '" & strData & "'"
End Sub
Public Sub test_wipeBytes()
Dim lpData() As Byte
lpData = cnvFromHex("DEADBEEF")
Debug.Print "BEFORE: 0x(" & cnvToHex(lpData) & ")" ' BEFORE: 0x(DEADBEEF)
Call wipeBytes(lpData)
Debug.Print "AFTER: 0x(" & cnvToHex(lpData) & ")" ' AFTER: 0x()
End Sub
Public Sub test_hashLength()
Debug.Print hashLength(PKI_HASH_SHA512) ' 64
Debug.Print hashLength(PKI_HASH_BTC160) ' 20
End Sub
Public Sub test_kdfBytes()
Dim lpKEK() As Byte
Dim lpZZ() As Byte
Dim lpInfo() As Byte
' ansx963_2001.rsp CAVS 12.0 'ANS X9.63-2001' information for sample
lpZZ = cnvFromHex("96c05619d56c328ab95fe84b18264b08725b85e33fd34f08")
lpKEK = kdfBytes(128 \ 8, lpZZ, lpInfo, PKI_HASH_SHA256)
Debug.Print "KEK = " & cnvToHex(lpKEK)
Debug.Print "OK = 443024c3dae66b95e6f5670601558f71"
' [RFC 5869] A.1. Test Case 1 Basic test case with SHA-256
lpZZ = cnvFromHex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b")
lpInfo = cnvFromHex("f0f1f2f3f4f5f6f7f8f9")
lpKEK = kdfBytes(42, lpZZ, lpInfo, PKI_KDF_HKDF Or PKI_HASH_SHA256, "salt=000102030405060708090a0b0c")
Debug.Print "KEK = " & cnvToHex(lpKEK)
Debug.Print "OK = 3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865"
End Sub
Public Sub test_kdfForCms()
Dim lpKEK() As Byte
Dim lpZZ() As Byte
Dim lpUkm() As Byte
lpZZ = cnvFromHex("160E3F5588C6FB4E9CEE8BC3C1C5000AB86396468C3D1CAEC0CB6E21536B5513")
lpKEK = kdfForCms(lpZZ, lpUkm, PKI_KWRAP_AES128 Or PKI_KDF_X963 Or PKI_HASH_SHA1)
Debug.Print "KEK = " & cnvToHex(lpKEK)
Debug.Print "OK = 04D616C654CDF62BB186A5A088B60FB5"
lpUkm = cnvFromHex("616263") ' "abc"
lpKEK = kdfForCms(lpZZ, lpUkm, PKI_KWRAP_AES256 Or PKI_KDF_HKDF Or PKI_HASH_SHA256)
Debug.Print "KEK = " & cnvToHex(lpKEK)
Debug.Print "OK = 1D06D6FD5C1EBFB33CAD875E6B99781D3D750875F573C9093CECBFBA6937ACC5"
End Sub
Public Sub test_cmsEnvData_ecdh()
' Create an enveloped CMS object to Dana (using ecdh) and Alice (using RSA)
Dim strMsg As String
Dim strCertList As String
Dim strCmsFile As String
Dim nRet As Long
Dim strQuery As String
Dim strPriKeyAlice As String
Dim strPriKeyDana As String
Dim strOut As String
Dim strCertFile As String
Dim abMsg() As Byte
strCertList = "lamps-dana.encrypt.crt;lamps-alice.encrypt.crt"
strMsg = "This is some sample content."
' Create an enveloped CMS object to Dana (using ecdh) and Alice (using RSA)
strCmsFile = "dana_alice_all_defaults.p7m"
nRet = cmsMakeEnvDataFromString(strCmsFile, strMsg, strCertList)
Debug.Print "cmsMakeEnvDataFromString returns " & nRet & " (expecting 2)"
Debug.Print "FILE: " & strCmsFile
strQuery = "contentEncryptionAlgorithm"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "recipientInfoType"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "keyEncryptionAlgorithm"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "recipientInfoType/2"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "keyEncryptionAlgorithm/2"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
' Read in Alice's RSA and Dana's ECC private key (unencrypted)
strPriKeyAlice = rsaReadPrivateKey("lamps-alice.decrypt.p8.pem", "")
Debug.Assert Len(strPriKeyAlice) > 0
strPriKeyDana = eccReadPrivateKey("lamps-dana.decrypt.p8.pem", "")
Debug.Assert Len(strPriKeyDana) > 0
' Read CMS enveloped-data using Alice's RSA key
strCertFile = "lamps-alice.encrypt.crt"
strOut = cmsReadEnvDataToString(strCmsFile, strCertFile, strPriKeyAlice)
Debug.Assert (Len(strOut) > 0)
Debug.Print "MSG=" & strOut
' Read CMS enveloped-data using Dana's ECC key
strCertFile = "lamps-dana.encrypt.crt"
strOut = cmsReadEnvDataToString(strCmsFile, strCertFile, strPriKeyDana)
Debug.Assert (Len(strOut) > 0)
Debug.Print "MSG=" & strOut
' Create enveloped CMS object using RSA-OAEP but defaults for ECDH
strCmsFile = "dana_alice_oaep_ecc_defaults.p7m"
nRet = cmsMakeEnvDataFromString(strCmsFile, strMsg, strCertList, "", PKI_BC_AES128 Or PKI_KT_RSAES_OAEP Or PKI_MGF_MGF1SHA1 Or PKI_HASH_SHA256)
Debug.Print "cmsMakeEnvDataFromString returns " & nRet & " (expecting 2)"
Debug.Print "FILE: " & strCmsFile
strQuery = "contentEncryptionAlgorithm"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "recipientInfoType"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "keyEncryptionAlgorithm"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "recipientInfoType/2"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "keyEncryptionAlgorithm/2"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
' Read CMS enveloped-data using Alice's RSA key
strCertFile = "lamps-alice.encrypt.crt"
strOut = cmsReadEnvDataToString(strCmsFile, strCertFile, strPriKeyAlice)
Debug.Assert (Len(strOut) > 0)
Debug.Print "MSG=" & strOut
' Read CMS enveloped-data using Dana's ECC key
strCertFile = "lamps-dana.encrypt.crt"
strOut = cmsReadEnvDataToString(strCmsFile, strCertFile, strPriKeyDana)
Debug.Assert (Len(strOut) > 0)
Debug.Print "MSG=" & strOut
' Use specific ECDH parameters
strCmsFile = "dana_alice_hkdf.p7m"
strCertList = "lamps-dana.encrypt.crt"
abMsg = StrConv(strMsg, vbFromUnicode)
nRet = cmsMakeEnvDataFromBytes(strCmsFile, abMsg, strCertList, "", PKI_BC_AES256 Or PKI_HASH_SHA256 Or PKI_KDF_HKDF Or PKI_KWRAP_AES256)
Debug.Print "cmsMakeEnvDataFromString returns " & nRet & " (expecting 1)"
Debug.Print "FILE: " & strCmsFile
strQuery = "keyEncryptionAlgorithm"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
strQuery = "keyWrapAlgorithm"
Debug.Print "QueryEnvData('" & strQuery & "')=" & cmsQueryEnvData(strCmsFile, strQuery)
' Read CMS enveloped-data using Dana's ECC key
strCertFile = "lamps-dana.encrypt.crt"
strOut = cmsReadEnvDataToString(strCmsFile, strCertFile, strPriKeyDana)
Debug.Assert (Len(strOut) > 0)
Debug.Print "MSG=" & strOut
End Sub
Public Sub test_x509MakeCert_X25519()
Dim strCertName As String
Dim strIssuercert As String
Dim strPriKeyFile As String
Dim strPubKeyFile As String
Dim strPriKeyStr As String
Dim strPubKeyStr As String
Dim strDn As String
Dim strExtns As String
Dim r As Long
strCertName = "new-lamps-dana.encrypt.cer"
strIssuercert = "lamps-ca.ed25519.crt"
strPriKeyFile = "lamps-ca.ed25519.p8" ' No password
strPubKeyFile = "lamps-dana.encrypt.crt" ' We get the public key from the cert we are trying to reproduce!
strDn = "O=IETF;OU=LAMPS WG;CN=Dana Hopper"
strExtns = "serialNumber=#x0E4B0A36A9EFBA9C9A3B68248E521DC0DEF3A7;notBefore=2020-12-15T21:35:44;notAfter=2052-12-15T21:35:44;extKeyUsage=emailProtection;" & _
"keyUsage=keyAgreement;sMIMECapabilities=301A060B2A864886F70D0109100313300B0609608648016503040105;" & _
"certificatePolicies=2.16.840.1.101.3.2.1.48.1;rfc822Name=dana@smime.example;subjectKeyIdentifier=9ddf4dd405ef9aec6086bc276d04e9ce5adc8fa4"
' Read in private and public keys to internal key strings
strPriKeyStr = eccReadPrivateKey(strPriKeyFile, "")
Debug.Assert Len(strPriKeyStr) > 0
Debug.Print "curveName=" & eccQueryKey(strPriKeyStr, "curvename")
strPubKeyStr = eccReadPublicKey(strPubKeyFile)
Debug.Assert Len(strPubKeyStr) > 0
Debug.Print "curveName=" & eccQueryKey(strPubKeyStr, "curvename")
' Create the new certificate using internal keystrings for public and private keys
r = X509_MakeCert(strCertName, strIssuercert, strPubKeyStr, strPriKeyStr, 0, 0, strDn, strExtns, 0, "", PKI_SIG_ED25519 Or PKI_X509_AUTHKEYID)
Debug.Print "X509_MakeCert returns " & r & " (expecting 0)"
Debug.Assert r = 0
' Dump details of new cert
Debug.Print "FILE: " & strCertName
Debug.Print (x509TextDumpToString(strCertName))
' For comparison, dump details of original lamps cert
Debug.Print "FILE: " & strPubKeyFile
Debug.Print (x509TextDumpToString(strPubKeyFile))
' NOTE: the *content* of the original certificate is the same as the newly created one
' _BUT_ the *order* of extension fields is different, so the thumbprints and signatures will not match.
' AFAWK there is no accepted order for extensions in an X.509 certificate.
End Sub
Public Sub test_pfxMakeFile_AES256()
Dim strPfxFile As String
Dim strPlainKeyFile As String
Dim strKeyFile As String
Dim strCertFile As String
Dim strPassword As String
Dim strKeyStr As String
Dim strCertStr As String
Dim strThumb As String
Dim r As Long
strPfxFile = "bob-aes256.pfx"
strPlainKeyFile = "lamps-bob.p8.pem"
strKeyFile = "lamps-bob.p8e"
strCertFile = "lamps-bob.crt"
strPassword = "password"
' Read in unencrypted key file then save as encrypted
' (We need an encrypted key file to make the PFX)
strKeyStr = rsaReadPrivateKey(strPlainKeyFile, "")
Debug.Assert Len(strKeyStr) > 0
r = rsaSaveEncKey(strKeyFile, strKeyStr, strPassword, "", PKI_PBE_PBKDF2_AES128)
Debug.Print "rsaSaveEncKey returns " & r & " (expecting 0)"
Debug.Assert 0 = r
' Make a PFX file using AES256-SHA256
r = PFX_MakeFile(strPfxFile, strCertFile, strKeyFile, strPassword, "Bob's friendly AES256 ID", PKI_PFX_AES256_SHA256)
Debug.Print "PFX_MakeFile returns " & r & " (expecting 0)"
Debug.Assert 0 = r
Debug.Print "Created file: " & strPfxFile
' Verify the PFX file's signature
r = PFX_VerifySig(strPfxFile, strPassword, 0)
Debug.Print "PFX_VerifySig returns " & r & " (expecting 0)"
Debug.Assert 0 = r
' Extract the certifcate from the PFX file we just made
strCertStr = x509ReadCertStringFromPFX(strPfxFile, strPassword)
Debug.Print "CERT=" & strCertStr
' Show the subject name
Debug.Print "subjectName='" & x509QueryCert(strCertStr, "subjectName") & "'"
' Check thumbprint
strThumb = x509CertThumb(strCertStr)
Debug.Print "SHA1(CER)=" & strThumb
Debug.Assert strThumb = "119cf5ff83dca26642cf3f2bb556241ccade75ec"
End Sub
Public Sub test_cmsMakeSigData_X25519()
Dim strSigDataFile As String
Dim strCertFile As String
Dim lpData() As Byte
Dim strPrivateKey As String
Dim strQuery As String
Dim r As Long
' Input contains two non-ASCII characters:
' U+00CD Latin capital letter I with acute, encodes as (0x) C3 8D
' U+00F1 Latin small letter N with tilde, encodes as (0x) C3 B1
' Convert Unicode string to UTF-8-encoded byte array to be signed
lpData = cnvUTF8BytesFromLatin1("<doc><name c='es'>Íñigo</name></doc>")
Debug.Print "HEX(data to be signed)=" & cnvToHex(lpData)
' Read in Dana's ED25519 private key
strPrivateKey = eccReadPrivateKey("lamps-dana.p8.pem", "")
strCertFile = "lamps-dana.crt"
' Create a CMS signed-data object
strSigDataFile = "signeddata-utf8-dana.p7m"
r = cmsMakeSigDataFromBytes(strSigDataFile, lpData, strCertFile, strPrivateKey, PKI_SIG_ED25519 Or PKI_CMS_INCLUDE_ATTRS Or PKI_CMS_ADD_SIGNINGCERT)
Debug.Print "cmsMakeSigDataFromBytes returns " & r & " (expected 0)"
Debug.Assert 0 = r
Debug.Print "FILE: " & strSigDataFile
' Query the signed-data object
strQuery = "signatureAlgorithm"
Debug.Print "QuerySigData('" & strQuery & "')=" & cmsQuerySigData(strSigDataFile, strQuery)
strQuery = "signingCertHash"
Debug.Print "QuerySigData('" & strQuery & "')=" & cmsQuerySigData(strSigDataFile, strQuery)
' Check thumbprint of cert, this should match the signingCertHash
Debug.Print "CertThumb=" & x509CertThumb(strCertFile)
' Read back the signed data
lpData = cmsReadSigDataToBytes(strSigDataFile)
Debug.Print "HEX(recovered content)=" & cnvToHex(lpData)
End Sub
Public Sub test_cmsEnvData_adv()
Dim n As Long
' Create an enveloped CMS object (ktri type) to Bob using Bob's RSA key...
n = cmsMakeEnvData("cms2bob_aes128.p7m", "excontent.txt", "BobRSASignByCarl.cer", "", PKI_BC_AES128 Or PKI_KT_RSAES_OAEP)
Debug.Print "cmsMakeEnvData returns " & n & " (expecting 1)"
Debug.Assert 1 = n
' Same but using authenticated encryption and creating an authEnvelopedData object...
n = cmsMakeEnvData("cms2bob_aes128auth.p7m", "excontent.txt", "BobRSASignByCarl.cer", "", PKI_AEAD_AES_128_GCM Or PKI_KT_RSAES_OAEP)
Debug.Print "cmsMakeEnvData returns " & n & " (expecting 1)"
Debug.Assert 1 = n
' Create an enveloped CMS object (kari type) to Dana using Dana's ECC key...
n = cmsMakeEnvData("cms2dana_hkdf.p7m", "excontent.txt", "lamps-dana.encrypt.crt", "", PKI_BC_AES256 Or PKI_HASH_SHA256 Or PKI_KDF_HKDF Or PKI_KWRAP_AES256)
Debug.Print "cmsMakeEnvData returns " & n & " (expecting 1)"
Debug.Assert 1 = n
' Create an enveloped CMS object (kekri type) using a previously distributed symmetric key-encryption key (KEK)...
n = cmsMakeEnvData("cms_envdata_kekri.p7m", "excontent.txt", "type=@kekri,keyid=ourcommonkey", "#x0123456789ABCDEFF0E1D2C3B4A59687", PKI_BC_AES256 Or PKI_HASH_SHA256 Or PKI_KWRAP_AES128)
Debug.Print "cmsMakeEnvData returns " & n & " (expecting 1)"
Debug.Assert 1 = n
' Create an enveloped CMS object (pwri type) using password-based key management...
n = cmsMakeEnvData("cms_envdata_pwri.p7m", "excontent.txt", "type=@pwri", "password12345", PKI_BC_AES192)
Debug.Print "cmsMakeEnvData returns " & n & " (expecting 1)"
Debug.Assert 1 = n
End Sub
Public Sub test_errFormatErrorMessage()
Dim s As String
Dim r As Long
' Clear any existing errors
Call pkiVersion
Debug.Print errFormatErrorMessage(11)
Debug.Print errFormatErrorMessage(11, "User message!")
' Try and read missing file
s = asn1Type("missing.file")
Debug.Print errFormatErrorMessage()
r = cmsMakeEnvData("not-to-be-made.p7m", "missing.file", "")
Debug.Print errFormatErrorMessage(r)
' Try to create a signed-data object but passing a missing cert file
Dim privkey As String
privkey = rsaReadPrivateKey("AlicePrivRSASign.p8e", "password")
r = CMS_MakeSigData("not-to-be-made.p7m", "excontent.txt", "missing.cer", privkey, 0)
Debug.Print errFormatErrorMessage(r, "User/expected error")
End Sub
Public Sub test_cipher_GCM()
Debug.Print "Testing cipher GCM..."
Dim fileIn As String
Dim fileEnc As String
Dim fileChk As String
Dim r As Long
Dim key() As Byte
Dim iv() As Byte
key = cnvFromHex("2B7E151628AED2A6ABF7158809CF4F3C")
' NB Require exact 12-byte IV for GCM
iv = cnvFromHex("000102030405060708090A0B")
Debug.Print "Encrypt a file using AES-GCM..."
fileIn = "excontent.txt"
fileEnc = "excontent-gcm-enc.dat"
fileChk = "abc-gcm-chk.dat"
' Encrypt the file
Debug.Print "About to encrypt file '" & fileIn & "' of length " & FileLen(fileIn)
r = cipherFileEncrypt(fileEnc, fileIn, key, iv, "aes128-gcm", PKI_IV_PREFIX)
Debug.Print "cipherFileEncrypt(GCM) returns " & r & " (expecting 0)"
Debug.Assert r = 0
Debug.Print "Created file '" & fileEnc & "' of length " & FileLen(fileEnc) _
& " (expected " & FileLen(fileIn) & "+12+16=" & FileLen(fileIn) + 12 + 16 & ")"
' Decrypt the file - IV is already at start of file so pass null iv argument
iv = vbNullString ' Set IV to be an empty byte array
Debug.Print "About to decrypt file '" & fileEnc
r = cipherFileDecrypt(fileChk, fileEnc, key, iv, "aes128-gcm", PKI_IV_PREFIX)
Debug.Print "cipherFileDecrypt(GCM) returns " & r & " (expecting 0)"
Debug.Assert r = 0
Debug.Print "Created file '" & fileChk & "' of length " & FileLen(fileChk)
' Check decrypted file is the same as original
Debug.Assert hashHexFromFile(fileIn, PKI_HASH_SHA1) = hashHexFromFile(fileChk, PKI_HASH_SHA1)
Debug.Print "Encrypt using AES-GCM with hex-encoded parameters..."
' Same as EncryptAEAD except without AAD and with hex-encoded arguments
Dim pthex As String
Dim cthex As String
Dim dthex As String
Dim keyHex As String
Dim ivhex As String
keyHex = "2B7E151628AED2A6ABF7158809CF4F3C"
ivhex = "000102030405060708090A0B"
pthex = cnvHexStrFromString("This is some sample content.")
Debug.Print "PT=" & pthex
cthex = cipherEncryptHex(pthex, keyHex, ivhex, "aes128-gcm")
Debug.Print "CT=" & cthex
' CT=0FA752259801FD6293B779E382FAD5FA7B5664D62EB63AA66064E189024C709ED4D580FB5E04E001C2D8DF97
dthex = cipherDecryptHex(cthex, keyHex, ivhex, "aes128-gcm")
Debug.Print "DT=" & dthex
Debug.Assert Len(dthex) > 0
Debug.Print "DT='" & cnvStringFromHexStr(dthex) & "'"
' Check decrypted hex is equal to original
Debug.Assert UCase(dthex) = UCase(pthex)
End Sub
Public Sub test_rsaReadPublicKey_CSR()
Dim csrfile As String
Dim keyfile As String
Dim dn As String
Dim extns As String
Dim keystr As String
Dim r As Long
' Create a new CSR for LAMPS WG alice
csrfile = "lamps-alice-csr.pem"
keyfile = "lamps-alice.p8" ' No password
dn = "O=IETF;OU=LAMPS WG;CN=Alice Lovelace;"
extns = "keyUsage=digitalSignature,nonRepudiation;extKeyUsage=emailProtection"
r = X509_CertRequest(csrfile, keyfile, dn, extns, "", PKI_SIG_SHA256RSA)
Debug.Print "X509_CertRequest returns " & r & " (expecting 0)"
' Dump details of CSR we just made...
Debug.Print x509TextDumpToString(csrfile, PKI_X509_LDAP)
' Read in public key from this CSR file to an internal key string
' (New in [v20.7])
keystr = rsaReadPublicKey(csrfile)
Debug.Print "Keysize=" & rsaKeyBits(keystr) & " bits, HashCode=0x" & Hex(RSA_KeyHashCode(keystr))
' EXPECTED: Keysize=2048 bits, HashCode=0xCA0B84DA
End Sub
Public Sub test_x509MakeCert_Ex()
Dim r As Long
Dim certname As String
Dim keyfile As String
Dim dn As String
Dim extns As String
Dim serialNum As Long
Dim s As String
certname = "myca-newattributes2022.cer"
keyfile = "lamps-ca.rsa.p8" ' No password
dn = "C=DE;dnQualifier='distinguisher';initials='E.M.';pseudonym='Super Muster';generationQualifier='3rd.';CN=Erika Mustermann"
extns = "keyUsage=digitalSignature,nonRepudiation;extKeyUsage=emailProtection;rfc822Name=erika@example.com;cRLDistributionPoints=http://dodgycert.example.com/evca.crl;"
serialNum = &H88C
r = X509_MakeCertSelf(certname, keyfile, serialNum, 10, dn, extns, 0, "", PKI_SIG_SHA256RSA)
Debug.Print "X509_MakeCertSelf returns " & r & " (expecting 0)"
Debug.Assert r = 0
' Dump details of cert we just made...
Debug.Print x509TextDumpToString(certname, PKI_X509_LDAP)
' Query the certificate
s = x509QueryCert(certname, "cRLDistributionPointsURI")
Debug.Print "cRLDistributionPointsURI='" & s & "'"
End Sub
Public Sub test_prfBytes()
Dim lpPrf() As Byte
Dim lpMsg() As Byte
Dim lpKey() As Byte
lpKey = cnvFromHex("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")
lpMsg = cnvFromHex("00010203")
' "Standard" KMAC output length KMAC128 => 256 bits, no custom string
lpPrf = prfBytes(256 \ 8, lpMsg, lpKey, PKI_KMAC_128)
Debug.Print "KMAC=" & cnvToHex(lpPrf)
Debug.Print "OK =E5780B0D3EA6F7D3A429C5706AA43A00FADBD7D49628839E3187243F456EE14E"
' Same with custom string
' NB order of parameters (szCustom <=> nOptions).
lpPrf = prfBytes(256 \ 8, lpMsg, lpKey, PKI_KMAC_128, "My Tagged Application")
Debug.Print "KMAC=" & cnvToHex(lpPrf)
Debug.Print "OK =3B1FBA963CD8B0B59E8C1A6D71888B7143651AF8BA0A7070C0979E2811324AA5"
' Use KMAC256 with 1600-bit message and "standard" 512-bit output
lpKey = cnvFromHex("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")
Dim strMsg As String
strMsg = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F3031" _
& "32333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60616263" _
& "6465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495" _
& "969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7"
lpMsg = cnvFromHex(strMsg)
lpPrf = prfBytes(512 \ 8, lpMsg, lpKey, PKI_KMAC_256)
Debug.Print "KMAC=" & cnvToHex(lpPrf)
Debug.Print "OK =75358CF39E41494E949707927CEE0AF20A3FF553904C86B08F21CC414BCFD691589D27CF5E15369CBBFF8B9A4C2EB17800855D0235FF635DA82533EC6B759B69"
End Sub
Public Sub test_xofBytes()
Dim lpMessage() As Byte
Dim lpOut() As Byte
lpMessage = cnvFromHex("6ae23f058f0f2264a18cd609acc26dd4dbc00f5c3ee9e13ecaea2bb5a2f0bb6b")
' Output 2000 bits
lpOut = xofBytes(2000 \ 8, lpMessage, PKI_XOF_SHAKE256)
Debug.Print "OUT=" & cnvToHex(lpOut)
Debug.Print "OK =" & "b9b92544fb25cf...f1d35bdff79a"
' MGF1-SHA-256
lpMessage = cnvFromHex("3b5c056af3ebba70d4c805380420585562b32410a778f558ff951252407647e3")
Debug.Print cnvToHex(lpMessage)
lpOut = xofBytes(34, lpMessage, PKI_XOF_MGF1_SHA256)
Debug.Print "OUT=" & cnvToHex(lpOut)
Debug.Print "OK =" & "5b7eb772aecf04c74af07d9d9c1c1f8d3a90dcda00d5bab1dc28daecdc86eb87611e"
End Sub
Public Sub test_hash_sha3()
Dim lpMessage() As Byte
lpMessage = StrConv("abc", vbFromUnicode)
Debug.Print "lpMessage=" & cnvHexStrFromBytes(lpMessage)
Debug.Print "OK:" & vbCrLf & "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"
Debug.Print hashHexFromBytes(lpMessage, PKI_HASH_SHA3_256)
Debug.Print hashHexFromHex("616263", PKI_HASH_SHA3_256)
Debug.Print hashHexFromFile("abc.txt", PKI_HASH_SHA3_256)
Debug.Print cnvHexStrFromBytes(hashBytes(lpMessage, PKI_HASH_SHA3_256))
Debug.Print cnvHexStrFromBytes(hashFile("abc.txt", PKI_HASH_SHA3_256))
' Test other algs
Debug.Print hashHexFromBytes(lpMessage, PKI_HASH_SHA3_224)
Debug.Print hashHexFromHex("616263", PKI_HASH_SHA3_256)
Debug.Print hashHexFromFile("abc.txt", PKI_HASH_SHA3_384)
Debug.Print cnvHexStrFromBytes(hashBytes(lpMessage, PKI_HASH_SHA3_512))
End Sub