Attribute VB_Name = "basTestChileSign"
' $Id: basTestChileSign $
' $Date: 2013-09-04 13:23 $
' $Author: dai $

' This module uses functions from the CryptoSys (tm) PKI Toolkit available from
' <https://cryptosys.net/pki/>.
' Include the module `basCrPKI' in your project.

' *************************** COPYRIGHT NOTICE ******************************
' This code was originally written by David Ireland and is copyright
' (C) 2013 DI Management Services Pty Ltd <https://di-mgt.com.au>.
' Provided "as is". No warranties. Use at your own risk. You must make your
' own assessment of its accuracy and suitability for your own purposes.
' It is not to be altered or distributed, except as part of an application.
' You are free to use it in any application, provided this copyright notice
' is left unchanged.
' ************************ END OF COPYRIGHT NOTICE **************************

Option Explicit

' To create a signature

' 1.    Compute the message digest value of the canonicalized data-to-be-signed.
' 2.    Compose a <SignedInfo> XML fragment, in canonicalized form, which contains the message digest value from step 1.
' 3.    Compute the message digest of the canonicalized <SignedInfo> element.
' 4.    Sign this message digest using your private key to produce a signature value.

' For steps 1 to 3, use MakeDigestValueOfSignedInfo
' <http://cryptosys.net/pki/basTestChile.html#MakeDigestValueOfSignedInfo>

' For step 4, use SignSignedInfo below

Public Function Test_SignSignedInfo()
    Dim strDigestHex As String
    Dim strPrikeyFile As String
    Dim strPassword As String
    Dim strSigValue64 As String
    
    ' OUR TEST INPUT DATA:
    ' The digest value we made earlier...
    strDigestHex = "353CABFE369AAD9BEA21F5FA06CB367960FFB7D4"
    ' We do not have the signing key used in the SII example. We use a test private key...
    strPrikeyFile = "AlicePrivRSASign.key"
    ' CAUTION: do not hardcode password in production code...
    strPassword = "password"
    
    Debug.Print "SHA-1 message digest of <SignedInfo> = " & strDigestHex
    strSigValue64 = SignSignedInfo(strDigestHex, strPrikeyFile, strPassword)
    Debug.Print "SignatureValue=" & strSigValue64
    
    ' Clean up password
    strPassword = WIPE_String(strPassword, Len(strPassword))
    
End Function

Public Function SignSignedInfo(strDigestHex As String, strPrikeyFile As String, strPassword As String) As String
' INPUT:  SHA-1 digest of canonicalized <SignedInfo> element in HEX format
'         Signer's encrypted private key file
'         Password for private key file
' OUTPUT: Signature value in base64 form

    Dim abDigest() As Byte
    Dim strPrivateKey As String
    Dim abBlock() As Byte
    Dim nkLen As Long
    Dim ndLen As Long
    Dim nRet As Long
    Dim strSigVal64 As String
    
    ' Read in private key from key file
    strPrivateKey = rsaReadPrivateKey(strPrikeyFile, strPassword)
    If Len(strPrivateKey) = 0 Then
        MsgBox "Error: Cannot read RSA key file '" & strPrikeyFile & "'", vbCritical
        Exit Function
    End If
    ' Get length of key in bytes (expecting 128)
    nkLen = RSA_KeyBytes(strPrivateKey)
    Debug.Print "  " & "Key is " & nkLen & " bytes long"

    ' Convert digest value from Hex form to Byte array
    ' -- expecting exactly 20 bytes
    ndLen = PKI_SHA1_BYTES
    If (Len(strDigestHex) <> ndLen * 2) Then
        MsgBox "Error: expecting exactly 40 hex chars in strDigestHex", vbCritical
        Exit Function
    End If
    ReDim abDigest(ndLen - 1)
    nRet = CNV_BytesFromHexStr(abDigest(0), ndLen, strDigestHex)
    Debug.Print "  " & "Digest=" & cnvHexStrFromBytes(abDigest)
    
    ' Encode digest value for signature
    ReDim abBlock(nkLen - 1)
    nRet = RSA_EncodeMsg(abBlock(0), nkLen, abDigest(0), ndLen, PKI_EMSIG_PKCSV1_5 + PKI_EMSIG_DIGESTONLY)
    Debug.Print "  " & "RSA_EncodeMsg returns " & nRet & " (expected 0)"
    Debug.Print "  " & "EM: " & cnvHexStrFromBytes(abBlock)
    
    ' Sign using RSA private key
    nRet = RSA_RawPrivate(abBlock(0), nkLen, strPrivateKey, 0)
    Debug.Print "  " & "SG: " & cnvHexStrFromBytes(abBlock)
    
    ' Convert the byte array to base64 encoding
    strSigVal64 = cnvB64StrFromBytes(abBlock)
    
    ' Return base64-encoded signature value
    SignSignedInfo = strSigVal64
    

End Function