#Include "cryptlib.bi"

#Macro check(expression)
status = expression
If status = CRYPT_ENVELOPE_RESOURCE Then
	Print "Warning on line " & __LINE__ & ". Envelope needs a resource to proceed."
	Sleep 800
ElseIf cryptStatusError(status) Then
	Print "Error on line " & __LINE__ & ". Status code: " & status
	Sleep
	cryptEnd()
	End
EndIf
#EndMacro
#Macro display(colour, buffer, length)
Scope
Color 7
Dim As UByte Ptr temp_buffer = buffer
Dim As Integer   temp_length = length
Print
Print "Buffer: " & #buffer
Print "Length: " & temp_length
Print "Pointer: " & temp_buffer
Print "Data:";
Color colour
For i As Integer = 0 To (temp_length - 1)
	Print " "; Hex(temp_buffer[i], 2);
	Sleep 10
	If InKey <> "" Then
		cryptEnd()
		End
	EndIf
Next
Print
Color 7
End Scope
#EndMacro

' Define variables
Dim As CRYPT_ENVELOPE cryptEnvelope
Dim As CRYPT_CONTEXT  cryptContext
Dim As CRYPT_USER     cryptUser = CRYPT_UNUSED
Dim As Integer        bytesCopied
Dim As Integer        status
Dim As String         cryptKey = "0123456789ABCDEF"

' Message data
Const As String  messagesource = "Hello world."
Const As Integer messagemax = 128
Dim As Integer   messagelen
Dim As UByte     messagebuffer(1 To messagemax)
Dim As UByte Ptr message = @messagebuffer(1)
*Cast(ZString Ptr, message) = messagesource
messagelen = Len(messagesource)

' Enveloped data
Const As Integer envelopedmax = 512
Dim As Integer   envelopedlen
Dim As UByte     envelopedbuffer(1 To envelopedmax)
Dim As UByte Ptr enveloped = @envelopedbuffer(1)


' Start cryptlib
check( cryptInit())

' ---------------------------------------
' ------- Envelope/Pack some data -------
' ---------------------------------------

' Create envelope
check( cryptCreateEnvelope(@cryptEnvelope, cryptUser, CRYPT_FORMAT_CRYPTLIB))

' Add the password
check( cryptSetAttributeString(cryptEnvelope, CRYPT_ENVINFO_PASSWORD, StrPtr(cryptKey), Len(cryptKey)))

' State the message size and push the message into the envelope
check( cryptSetAttribute(cryptEnvelope, CRYPT_ENVINFO_DATASIZE, messagelen))
check( cryptPushData(cryptEnvelope, message, messagelen, @bytesCopied))

' Pop out the enveloped message
check( cryptFlushData(cryptEnvelope))
check( cryptPopData(cryptEnvelope, enveloped, envelopedmax, @envelopedlen))

' Delete envelope
check( cryptDestroyEnvelope(cryptEnvelope))

' ---------------------------------------

' Display data (for checking and debugging)
display(2, message, messagelen)
display(4, enveloped, envelopedlen)


' ---------------------------------------
' ---- De-envelope/Unpack some data -----
' ---------------------------------------

' Create envelope
check( cryptCreateEnvelope(@cryptEnvelope, cryptUser, CRYPT_FORMAT_AUTO))

' Push in enveloped data
check( cryptPushData(cryptEnvelope, enveloped, envelopedlen, @bytesCopied))

' Add the password
check( cryptSetAttributeString(cryptEnvelope, CRYPT_ENVINFO_PASSWORD, StrPtr(cryptKey), Len(cryptKey)))

' Pop out the recovered message
check( cryptFlushData(cryptEnvelope))
check( cryptPopData(cryptEnvelope, message, messagemax, @envelopedlen))

' Delete envelope
check( cryptDestroyEnvelope(cryptEnvelope))

' ---------------------------------------

' Display data (for checking and debugging)
display(2, message, messagelen)


' Shutdown cryptlib
check( cryptEnd())


' Finish
Print "Done"
Sleep
End
