Imports System
Imports System.Diagnostics
Imports System.IO
Imports FirmaSAT

' Some tests using the FirmaSAT .NET interface.
' Requires certain files to exist in the current working directory.

' 
' **************************** COPYRIGHT NOTICE ****************************
' * Copyright (C) 2010-11 DI Management Services Pty Limited. 
' * All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net>
' *   $Id: TestFirmaSat.vb $
' *   Last updated:
' *   $Date: 2011-12-29 08:28:00 $
' *   $Version: 5.0.0 $
' ************************* END OF COPYRIGHT NOTICE ************************
' 
' A ported version of TestFirmaSat.cs from C# to VB.NET
' using icsharpcode.net's SharpDevelop v3.0.


Namespace TestFirmaSATcsharp
  ''' <summary>
  ''' Test examples for FirmaSAT .NET interface
  ''' </summary>
  Class TestFirmaSATcsharp
    ''' <summary>
    ''' The main entry point for the application.
    ''' </summary>
        <STAThread()> _
        Public Shared Sub Main(ByVal args As String())
            Dim n As Integer
            Dim s As String, s1 As String
            Dim fname As String
            Dim ch As Char
            Dim attributeName As String, elementName As String
            Dim newname As String, keyfile As String, password As String, certfile As String, certStr As String
            ' Required test files (see `FirmaSATtestfiles.zip`)
            Dim arrFileNames As String() = New String() {"Muestra_v2_base2011.xml", "Muestra_v2_signed2011.xml", 
            "Muestra_v2_bad.xml", "detallista_base2011.xml", "ejemplo_v3_base2011.xml", "ejemplo_v3_tfd.xml", _
             "ejemplo_v3_noprefix.xml", "V2_2-base.xml", "V3_2-base.xml", "V3_2_BadCurp.xml", "Muestra_v22-base.xml", 
             "ejemplo_v32-base.xml"}

            Console.WriteLine("INTERROGATE THE CORE DIFIRMASAT DLL:")
            n = FirmaSAT.General.Version()
            Console.WriteLine("Version={0}", n)
            Debug.Assert(n >= 500, "Require FirmaSAT v5.0 or higher")
            s = General.CompileTime()
            Console.WriteLine("CompileTime={0}", s)
            s = General.ModuleName()
            Console.WriteLine("ModuleName={0}", s)
            ch = General.LicenceType()
            Console.WriteLine("LicenceType={0}", ch)

            '...
            '            Console.WriteLine("\nInterrogate the underlying CryptoSys PKI DLL:");
            '            n = FirmaSAT.General.PKIVersion();
            '            Console.WriteLine("PKIVersion={0}", n);
            '            s = General.PKICompileTime();
            '            Console.WriteLine("PKICompileTime={0}", s);
            '            s = General.PKIModuleName();
            '            Console.WriteLine("PKIModuleName={0}", s);
            '             ...


            ' CHECK FOR REQUIRED FILES IN CURRENT WORKING DIRECTORY
            Console.WriteLine("Current working directory is {0}", Directory.GetCurrentDirectory())
            Dim missingFile As String = "STOPPED: Required file is missing in current working directory"
            For Each fn As String In arrFileNames
                If FileIsNotPresent(fn, missingFile) Then
                    Return
                End If
            Next

            Console.WriteLine(vbLf & "FORM THE PIPESTRING FROM AN XML FILE:")
            fname = "Muestra_v2_signed2011.xml"
            s = Sat.MakePipeStringFromXml(fname)
            Console.WriteLine("Sat.MakePipeStringFromXml('{0}')=" & vbLf & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.MakePipeStringFromXml failed")

            Console.WriteLine(vbLf & "SIGN AN XML FILE:")
            fname = "Muestra_v2_base2011.xml"
            newname = "Muestra_v2-new_signed2011.xml"
            keyfile = "aaa010101aaa_CSD_01.key"
            password = "a0123456789"
            ' CAUTION: DO NOT HARD-CODE REAL PASSWORDS! 
            certfile = "aaa010101aaa_CSD_01.cer"
            n = Sat.SignXml(newname, fname, keyfile, password, certfile)
            Console.WriteLine("Sat.SignXml('{0}'-->'{1}') returns {2}", fname, newname, n)
            Debug.Assert(n = 0, "Sat.SignXml failed")
            ' Did we make a valid XML file?
            n = Sat.ValidateXml(newname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", newname, n)
            Debug.Assert(n = 0, "Sat.ValidateXml failed")

            Console.WriteLine(vbLf & "VERIFY A SIGNATURE IN AN XML FILE:")
            Console.WriteLine("1. One we know is good:")
            fname = "Muestra_v2_signed2011.xml"
            n = Sat.VerifySignature(fname)
            Console.WriteLine("Sat.VerifySignature('{0}') returns {1}", fname, n)
            Debug.Assert(n = 0, "Sat.VerifySignature failed")

            Console.WriteLine("2. One we just made, so it should be good:")
            fname = newname
            n = Sat.VerifySignature(fname)
            Console.WriteLine("Sat.VerifySignature('{0}') returns {1}", fname, n)
            Debug.Assert(n = 0, "Sat.VerifySignature failed")

            Console.WriteLine(vbLf & "FORM THE DIGEST OF THE PIPESTRING IN AN XML FILE:")
            fname = "Muestra_v2_signed2011.xml"
            s = Sat.MakeDigestFromXml(fname)
            Console.WriteLine("Sat.MakeDigestFromXml('{0}')=" & vbLf & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.MakeDigestFromXml failed")

            Console.WriteLine(vbLf & "EXTRACT THE DIGEST FROM THE SIGNATURE IN AN XML FILE:")
            fname = "Muestra_v2_signed2011.xml"
            s = Sat.ExtractDigestFromSignature(fname)
            Console.WriteLine("Sat.ExtractDigestFromSignature('{0}')=" & vbLf & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.ExtractDigestFromSignature failed")

            Console.WriteLine(vbLf & "TRY VALIDATING XML FILES:")
            Console.WriteLine("1. A valid one:")
            fname = "Muestra_v2_signed2011.xml"
            n = Sat.ValidateXml(fname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", fname, n)
            Debug.Assert(n = 0, "Sat.ValidateXml failed")

            Console.WriteLine("2. An invalid one (missing version):")
            fname = "Muestra_v2_bad.xml"
            n = Sat.ValidateXml(fname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", fname, n)
            s = Sat.LastError()
            Console.WriteLine("ErrorLookup({0})={1}", n, General.ErrorLookup(n))
            Console.WriteLine("LastError={0}", s)

            Console.WriteLine("3. An invalid one (empty noCertificado):")
            fname = "ejemplo_v32-base.xml"
            n = Sat.ValidateXml(fname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", fname, n)
            s = Sat.LastError()
            Console.WriteLine("ErrorLookup({0})={1}", n, General.ErrorLookup(n))
            Console.WriteLine("LastError={0}", s)

            Console.WriteLine(vbLf & "EXTRACT AN ATTRIBUTE FROM AN XML FILE:")
            fname = "Muestra_v2_signed2011.xml"
            elementName = "Comprobante"
            attributeName = "sello"
            s = Sat.GetXmlAttribute(fname, attributeName, elementName)
            Console.WriteLine("Sat.GetXmlAttribute('{0}',{2},{3})=" & vbLf & "{1}", fname, s, attributeName, elementName)
            Debug.Assert(s.Length > 0, "Sat.GetXmlAttribute failed")

            elementName = "Comprobante"
            attributeName = "formaDePago"
            s = Sat.GetXmlAttribute(fname, attributeName, elementName)
            Console.WriteLine("Sat.GetXmlAttribute('{0}',{2},{3})=" & vbLf & "{1}", fname, s, attributeName, elementName)
            Debug.Assert(s.Length > 0, "Sat.GetXmlAttribute failed")

            Console.WriteLine(vbLf & "GET DETAILS OF X.509 CERTIFICATE:")
            Console.WriteLine("1. From embedded `certificado` in XML")
            fname = "Muestra_v2_signed2011.xml"
            s = Sat.GetCertNumber(fname)
            Console.WriteLine("Sat.GetCertNumber('{0}')={1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.GetCertNumber failed")
            s = Sat.GetCertExpiry(fname)
            Console.WriteLine("Sat.GetCertExpiry('{0}')={1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.GetCertExpiry failed")

            Console.WriteLine("2. From X.509 file")
            fname = "aaa010101aaa_CSD_01.cer"
            s = Sat.GetCertNumber(fname)
            Console.WriteLine("Sat.GetCertNumber('{0}')={1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.GetCertNumber failed")
            s = Sat.GetCertExpiry(fname)
            Console.WriteLine("Sat.GetCertExpiry('{0}')={1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.GetCertExpiry failed")

            Console.WriteLine(vbLf & "GET CERTIFICATE AS A BASE64 STRING:")
            fname = "aaa010101aaa_CSD_01.cer"
            s = Sat.GetCertAsString(fname)
            Console.WriteLine("Sat.GetCertAsString('{0}')=" & vbLf & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.GetCertAsString failed")
            Console.WriteLine("Sat.GetCertAsString('{0}').Length={1}", fname, s.Length)
            ' Compare against string from XML file
            fname = "Muestra_v2_signed2011.xml"
            s1 = Sat.GetCertAsString(fname)
            Console.WriteLine("Sat.GetCertAsString('{0}').Length={1}", fname, s1.Length)
            Debug.Assert(s1.Length > 0, "Sat.GetCertAsString failed")
            Debug.Assert([String].Compare(s, s1, True) = 0, "Sat.GetCertAsString failed")

            Console.WriteLine(vbLf & "MAKE A SIGNATURE FROM A BASE XML FILE:")
            fname = "Muestra_v2_base2011.xml"
            keyfile = "aaa010101aaa_CSD_01.key"
            password = "a0123456789"
            ' CAUTION: DO NOT HARD-CODE REAL PASSWORDS! 
            s = Sat.MakeSignatureFromXml(fname, keyfile, password)
            Console.WriteLine("Sat.MakeSignatureFromXml('{0}')=" & vbLf & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.MakeSignatureFromXml failed")

            Console.WriteLine(vbLf & "SIGN A DETALLISTA XML FILE:")
            fname = "detallista_base2011.xml"
            newname = "detallista-new_signed.xml"
            keyfile = "aaa010101aaa_CSD_01.key"
            password = "a0123456789"
            ' CAUTION: DO NOT HARD-CODE REAL PASSWORDS! 
            certfile = "aaa010101aaa_CSD_01.cer"
            n = Sat.SignXml(newname, fname, keyfile, password, certfile)
            Console.WriteLine("Sat.SignXml('{0}'-->'{1}') returns {2}", fname, newname, n)
            Debug.Assert(n = 0, "Sat.SignXml failed")
            ' Did we make a valid XML file?
            n = Sat.ValidateXml(newname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", newname, n)
            Debug.Assert(n = 0, "Sat.ValidateXml failed")
            n = Sat.VerifySignature(newname)
            Console.WriteLine("Sat.VerifySignature('{0}') returns {1}", newname, n)
            Debug.Assert(n = 0, "Sat.VerifySignature failed")

            Console.WriteLine(vbLf & "EXTRACT AN ATTRIBUTE FROM A DETALLISTA XML FILE:")
            fname = "detallista-new_signed.xml"
            elementName = "detallista:detallista"
            attributeName = "documentStructureVersion"
            s = Sat.GetXmlAttribute(fname, attributeName, elementName)
            Console.WriteLine("Sat.GetXmlAttribute('{0}',{2},{3})={1}", fname, s, attributeName, elementName)
            Debug.Assert(s.Length > 0, "Sat.GetXmlAttribute failed")
            Debug.Assert([String].Compare(s, "AMC8.1") = 0, "Invalid detallista.documentStructureVersion")

            Console.WriteLine(vbLf & "EXTRACT AN ATTRIBUTE WITH ACCENTED CHARACTERS:")
            fname = "Muestra_v2_signed2011.xml"
            elementName = "DomicilioFiscal"
            attributeName = "referencia"
            s = Sat.GetXmlAttribute(fname, attributeName, elementName)
            Console.WriteLine("Sat.GetXmlAttribute('{0}',{2},{3})={1}", fname, s, attributeName, elementName)
            Debug.Assert(s.Length > 0, "Sat.GetXmlAttribute failed")
            Debug.Assert([String].Compare(s, "ÁÉÍÓÚÑ áéíóñ") = 0, "Invalid detallista.
            documentStructureVersion")

            ' [NEW IN VERSION 3.0] WILL NOW SIGN CFDI Version="3.0" XML
            Console.WriteLine(vbLf & "SIGN CFDi VERSION 3.0 XML FILE:")
            fname = "ejemplo_v3_base2011.xml"
            newname = "ejemplo_v3-new_signed.xml"
            keyfile = "aaa010101aaa_CSD_01.key"
            password = "a0123456789"
            ' CAUTION: DO NOT HARD-CODE REAL PASSWORDS! 
            certfile = "aaa010101aaa_CSD_01.cer"
            n = Sat.SignXml(newname, fname, keyfile, password, certfile, 0)
            Console.WriteLine("Sat.SignXml('{0}'-->'{1}') returns {2}", fname, newname, n)
            Debug.Assert(n = 0, "Sat.SignXml failed")
            ' Did we make a valid XML file?
            n = Sat.ValidateXml(newname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", newname, n)
            Debug.Assert(n = 0, "Sat.ValidateXml failed")

            Console.WriteLine(vbLf & "VERIFY A SHA-1 SIGNATURE IN AN XML FILE:")
            fname = newname
            n = Sat.VerifySignature(fname)
            Console.WriteLine("Sat.VerifySignature('{0}') returns {1}", fname, n)
            Debug.Assert(n = 0, "Sat.VerifySignature failed")

            Console.WriteLine(vbLf & "EXTRACT THE DIGEST FROM THE SIGNATURE IN AN XML FILE:")
            fname = "ejemplo_v3-new_signed.xml"
            s = Sat.ExtractDigestFromSignature(fname)
            Console.WriteLine("Sat.ExtractDigestFromSignature('{0}')=" & vbLf & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.ExtractDigestFromSignature failed")

            Console.WriteLine("Using a separate certificate:")
            fname = "ejemplo_v3-new_signed.xml"
            certStr = "MIIE/TCCA+
            WgAwIBAgIUMzAwMDEwMDAwMDAxMDAwMDA4MDAwDQYJKoZIhvcNAQEFBQAwggFvMRgwFgYDVQQDDA9BLkMuIGRlIHBydWViYXMxLzAtBgNVBAo
            MJlNlcnZpY2lvIGRlIEFkbWluaXN0cmFjacOzbiBUcmlidXRhcmlhMTgwNgYDVQQLDC9BZG1pbmlzdHJhY2nDs24gZGUgU2VndXJpZGFkIGRl
            IGxhIEluZm9ybWFjacOzbjEpMCcGCSqGSIb3DQEJARYaYXNpc25ldEBwcnVlYmFzLnNhdC5nb2IubXgxJjAkBgNVBAkMHUF2LiBIaWRhbGdvI
            Dc3LCBDb2wuIEd1ZXJyZXJvMQ4wDAYDVQQRDAUwNjMwMDELMAkGA1UEBhMCTVgxGTAXBgNVBAgMEERpc3RyaXRvIEZlZGVyYWwxEjAQBgNVBA
            cMCUNveW9hY8OhbjEVMBMGA1UELRMMU0FUOTcwNzAxTk4zMTIwMAYJKoZIhvcNAQkCDCNSZXNwb25zYWJsZTogSMOpY3RvciBPcm5lbGFzIEF
            yY2lnYTAeFw0xMDA3MzAxNjU4NDBaFw0xMjA3MjkxNjU4NDBaMIGWMRIwEAYDVQQDDAlNYXRyaXogU0ExEjAQBgNVBCkMCU1hdHJpeiBTQTES
            MBAGA1UECgwJTWF0cml6IFNBMSUwIwYDVQQtExxBQUEwMTAxMDFBQUEgLyBBQUFBMDEwMTAxQUFBMR4wHAYDVQQFExUgLyBBQUFBMDEwMTAxS
            ERGUlhYMDExETAPBgNVBAsMCFVuaWRhZCAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD0ltQNthUNUfzq0t1GpIyapjzOn1W5fGM5G
            /pQyMluCzP9YlVAgBjGgzwYp9Z0J9gadg3y2ZrYDwvv8b72goyRnhnv3bkjVRKlus6LDc00K7Jl23UYzNGlXn5+
            i0HxxuWonc2GYKFGsN4rFWKVy3Fnpv8Z2D7dNqsVyT5HapEqwIDAQABo4HqMIHnMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgbAMB0GA1UdDg
            QWBBSYodSwRczzj5H7mcO3+mAyXz+
            y0DAuBgNVHR8EJzAlMCOgIaAfhh1odHRwOi8vcGtpLnNhdC5nb2IubXgvc2F0LmNybDAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0
            dHA6Ly9vY3NwLnNhdC5nb2IubXgvMB8GA1UdIwQYMBaAFOtZfQQimlONnnEaoFiWKfU54KDFMBAGA1UdIAQJMAcwBQYDKgMEMBMGA1UdJQQMM
            AoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQArHQEorApwqumSn5EqDOAjbezi8fLco1cYES/PD+
            LQRM1Vb1g7VLE3hR4S5NNBv0bMwwWAr0WfL9lRRj0PMKLorO8y4TJjRU8MiYXfzSuKYL5Z16kW8zlVHw7CtmjhfjoIMwjQo3prifWxFv7VpfI
            BstKKShU0qB6KzUUNwg2Ola4t4gg2JJcBmyIAIInHSGoeinR2V1tQ10aRqJdXkGin4WZ75yMbQH4L0NfotqY6bpF2CqIY3aogQyJGhUJji4gY
            nS2DvHcyoICwgawshjSaX8Y0Xlwnuh6EusqhqlhTgwPNAPrKIXCmOWtqjlDhho/lhkHJMzuTn8AoVapbBUnj"
            s = Sat.ExtractDigestFromSignature(fname, certStr)
            Console.WriteLine("Sat.ExtractDigestFromSignature('{0}', certStr)=" & vbLf & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.ExtractDigestFromSignature failed")

            Console.WriteLine(vbLf & "FORM THE SHA-1 DIGEST OF THE PIPESTRING IN AN XML FILE:")
            fname = "ejemplo_v3-new_signed.xml"
            s1 = Sat.MakeDigestFromXml(fname, HashAlgorithm.Sha1)
            Console.WriteLine("Sat.MakeDigestFromXml('{0}')=" & vbLf & "{1}", fname, s1)
            Debug.Assert(s1.Length > 0, "Sat.MakeDigestFromXml failed")
            ' Check the two digests match
            Debug.Assert([String].Compare(s, s1, True) = 0, "Digests do not match")

            ' [v3.0] NEW FUNCTIONS ADDED...

            Console.WriteLine(vbLf & "GET VALIDITY DETAILS OF X.509 CERTIFICATE:")
            Console.WriteLine("1. From embedded `certificado` in XML")
            fname = "Muestra_v2_signed2011.xml"
            s = Sat.GetCertExpiry(fname)
            Console.WriteLine("Sat.GetCertExpiry('{0}')=" & vbTab & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.GetCertExpiry failed")
            s = Sat.GetCertStart(fname)
            Console.WriteLine("Sat.GetCertStart('{0}') =" & vbTab & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.GetCertStart failed")

            Console.WriteLine("2. From X.509 file")
            fname = "aaa010101aaa_CSD_01.cer"
            s = Sat.GetCertExpiry(fname)
            Console.WriteLine("Sat.GetCertExpiry('{0}')=" & vbTab & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.GetCertExpiry failed")
            s = Sat.GetCertStart(fname)
            Console.WriteLine("Sat.GetCertStart('{0}') =" & vbTab & "{1}", fname, s)
            Debug.Assert(s.Length > 0, "Sat.GetCertStart failed")

            Console.WriteLine(vbLf & "CHECK PRIVATE KEY MATCHES PUBLIC KEY IN CERTIFICATE:")
            certfile = "aaa010101aaa_CSD_01.cer"
            keyfile = "aaa010101aaa_CSD_01.key"
            password = "a0123456789"
            ' CAUTION: DO NOT HARD-CODE REAL PASSWORDS! 
            n = Sat.CheckKeyAndCert(keyfile, password, certfile)
            Console.WriteLine("Sat.CheckKeyAndCert({0},{1}) = {2}", keyfile, certfile, n)
            Debug.Assert(n = 0, "Sat.CheckKeyAndCert failed")

            certfile = "aaa010101aaa_CSD_02.cer"
            keyfile = "aaa010101aaa_CSD_02.key"
            password = "a0123456789"
            n = Sat.CheckKeyAndCert(keyfile, password, certfile)
            Console.WriteLine("Sat.CheckKeyAndCert({0},{1}) = {2}", keyfile, certfile, n)
            Debug.Assert(n = 0, "Sat.CheckKeyAndCert failed")

            ' Get embedded certificate from XML doc
            certfile = "Muestra_v2_signed2011.xml"
            keyfile = "aaa010101aaa_CSD_01.key"
            password = "a0123456789"
            n = Sat.CheckKeyAndCert(keyfile, password, certfile)
            Console.WriteLine("Sat.CheckKeyAndCert({0},{1}) = {2}", keyfile, certfile, n)
            Debug.Assert(n = 0, "Sat.CheckKeyAndCert failed")

            ' We can pass key file and certificate as "PEM" strings.
            ' The "BEGIN/END" encapsulation is optional for a certificate,
            ' but is required for the encrypted private key.
            certfile = "-----BEGIN CERTIFICATE-----" & "MIIE/TCCA+
            WgAwIBAgIUMzAwMDEwMDAwMDAxMDAwMDA4MDAwDQYJKoZIhvcNAQEF" & 
            "BQAwggFvMRgwFgYDVQQDDA9BLkMuIGRlIHBydWViYXMxLzAtBgNVBAoMJlNlcnZp" & 
            "Y2lvIGRlIEFkbWluaXN0cmFjacOzbiBUcmlidXRhcmlhMTgwNgYDVQQLDC9BZG1p" & 
            "bmlzdHJhY2nDs24gZGUgU2VndXJpZGFkIGRlIGxhIEluZm9ybWFjacOzbjEpMCcG" & 
            "CSqGSIb3DQEJARYaYXNpc25ldEBwcnVlYmFzLnNhdC5nb2IubXgxJjAkBgNVBAkM" & 
            "HUF2LiBIaWRhbGdvIDc3LCBDb2wuIEd1ZXJyZXJvMQ4wDAYDVQQRDAUwNjMwMDEL" & 
            "MAkGA1UEBhMCTVgxGTAXBgNVBAgMEERpc3RyaXRvIEZlZGVyYWwxEjAQBgNVBAcM" & 
            "CUNveW9hY8OhbjEVMBMGA1UELRMMU0FUOTcwNzAxTk4zMTIwMAYJKoZIhvcNAQkC" & 
            "DCNSZXNwb25zYWJsZTogSMOpY3RvciBPcm5lbGFzIEFyY2lnYTAeFw0xMDA3MzAx" & 
            "NjU4NDBaFw0xMjA3MjkxNjU4NDBaMIGWMRIwEAYDVQQDDAlNYXRyaXogU0ExEjAQ" & 
            "BgNVBCkMCU1hdHJpeiBTQTESMBAGA1UECgwJTWF0cml6IFNBMSUwIwYDVQQtExxB" & 
            "QUEwMTAxMDFBQUEgLyBBQUFBMDEwMTAxQUFBMR4wHAYDVQQFExUgLyBBQUFBMDEw" & 
            "MTAxSERGUlhYMDExETAPBgNVBAsMCFVuaWRhZCAxMIGfMA0GCSqGSIb3DQEBAQUA" & 
            "A4GNADCBiQKBgQDD0ltQNthUNUfzq0t1GpIyapjzOn1W5fGM5G/pQyMluCzP9YlV" & 
            "AgBjGgzwYp9Z0J9gadg3y2ZrYDwvv8b72goyRnhnv3bkjVRKlus6LDc00K7Jl23U" & "YzNGlXn5+
            i0HxxuWonc2GYKFGsN4rFWKVy3Fnpv8Z2D7dNqsVyT5HapEqwIDAQAB" & 
            "o4HqMIHnMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgbAMB0GA1UdDgQWBBSYodSw" & "Rczzj5H7mcO3+mAyXz+
            y0DAuBgNVHR8EJzAlMCOgIaAfhh1odHRwOi8vcGtpLnNh" & 
            "dC5nb2IubXgvc2F0LmNybDAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0" & 
            "dHA6Ly9vY3NwLnNhdC5nb2IubXgvMB8GA1UdIwQYMBaAFOtZfQQimlONnnEaoFiW" & 
            "KfU54KDFMBAGA1UdIAQJMAcwBQYDKgMEMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0G" & 
            "CSqGSIb3DQEBBQUAA4IBAQArHQEorApwqumSn5EqDOAjbezi8fLco1cYES/PD+LQ" & 
            "RM1Vb1g7VLE3hR4S5NNBv0bMwwWAr0WfL9lRRj0PMKLorO8y4TJjRU8MiYXfzSuK" & 
            "YL5Z16kW8zlVHw7CtmjhfjoIMwjQo3prifWxFv7VpfIBstKKShU0qB6KzUUNwg2O" & 
            "la4t4gg2JJcBmyIAIInHSGoeinR2V1tQ10aRqJdXkGin4WZ75yMbQH4L0NfotqY6" & 
            "bpF2CqIY3aogQyJGhUJji4gYnS2DvHcyoICwgawshjSaX8Y0Xlwnuh6EusqhqlhT" & 
            "gwPNAPrKIXCmOWtqjlDhho/lhkHJMzuTn8AoVapbBUnj" & "-----END CERTIFICATE-----"
            keyfile = "-----BEGIN ENCRYPTED PRIVATE KEY-----" & 
            "MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQInuASOYqnkMoCAggA" & 
            "MBQGCCqGSIb3DQMHBAhXp9z9DSW2PgSCAoAQVlA5ii7OMeprchNs4wwgE2ReNZrw" & "yVvFISJpnCN4Y906w/MYvpoc5J8q5eIZi9R5Y+
            FPBaCkprN0w54ypMYQX9oPuSlk" & "KW5C7LCq5d1mx4ZeGDmqCNXesehi/kY/0Mt/m8CB90x8dwKVE3bLJVwi+IgbgLf5" & 
            "zStnIXs/LTiA3a9B0Yo8Oe6J4q+Kt0Dlg0+JfSekP76BmImpScc6lUClOX54pCCr" & 
            "gOOZpdJK7G9u/UpxfVdAQeL2GaLE3tfxlEHuFtHmkXMy51OuSv7er+9FuNMxCYGa" & "rLiUybDuFlvcV7++
            9aVql/Qao5gGgKZ1oeCJNb1DZ4xdKJedtx0Kzrp3JmTeSNmG" & 
            "yzkbczFEM1m2GhPQGD6uadqMCguIwlHHm46s/jWBdEjhuQaedbwcQUiOn20dsfh5" & 
            "F1Ld3aMDqAXaJdqhqsXrehMXDdHoTV8c6x66cDXAqiJGng6jySDe/sNMtlX1fHiw" & 
            "6mjq12Wu5E8bmlzHXy8BO4zJS9qgYec34UK30sFk3ZhBXM8ALq2cn1JkGxDDkqjv" & "dOOocARME+
            dxNHxw6rw0UESi0i5GtwYRL8eLHuPPJN7zcQG8FytGI8CsTMYSe72L" & 
            "v0EFacZv7UOQde0vLww8A4EieDLxMu25mZAZ9DebFQwSHtiS4NK5PHFTk4Tm2vEr" & 
            "X/HZfMQmDQbqG8v/cNNKGX/OGcIVu9eLY7T55OG1n1O2bofVkjZ0gzgAo7ZCWMqX" & 
            "f/17dljEIQ/b9iHESwri/Lw5g9cQBBAx23pNPP2SteGhvQg50ZyrxGA5/an1ti2Z" & "u5nQ+
            7YpPyrKxjERRjk8B8i2qLxDrJuaDHfAOWTvdVoGX9/s7M2p68B6" & "-----END ENCRYPTED PRIVATE KEY-----"
            password = "a0123456789"
            n = Sat.CheckKeyAndCert(keyfile, password, certfile)
            Console.WriteLine("Sat.CheckKeyAndCert(STRINGS) = {0}", n)
            Debug.Assert(n = 0, "Sat.CheckKeyAndCert failed")

            Console.WriteLine(vbLf & "FIND THE COMPROBANTE VERSION OF AN XML FILE:")
            fname = "Muestra_v2_base2011.xml"
            n = Sat.XmlReceiptVersion(fname)
            Console.WriteLine("Sat.XmlReceiptVersion('{0}') = {1}", fname, n)
            Debug.Assert(n = 2, "Sat.XmlReceiptVersion failed")
            fname = "ejemplo_v3_base2011.xml"
            n = Sat.XmlReceiptVersion(fname)
            Console.WriteLine("Sat.XmlReceiptVersion('{0}') = {1}", fname, n)
            Debug.Assert(n = 3, "Sat.XmlReceiptVersion failed")
            ' New in [v5.0]...
            fname = "Muestra_v22-base.xml"
            n = Sat.XmlReceiptVersion(fname)
            Console.WriteLine("Sat.XmlReceiptVersion('{0}') = {1}", fname, n)
            Debug.Assert(n = 22, "Sat.XmlReceiptVersion failed")
            fname = "ejemplo_v32-base.xml"
            n = Sat.XmlReceiptVersion(fname)
            Console.WriteLine("Sat.XmlReceiptVersion('{0}') = {1}", fname, n)
            Debug.Assert(n = 32, "Sat.XmlReceiptVersion failed")

            ' NEW IN [v4.0] ...

            fname = "ejemplo_v3_noprefix.xml"
            n = Sat.XmlReceiptVersion(fname)
            Console.WriteLine("Sat.XmlReceiptVersion('{0}') = {1}", fname, n)
            Debug.Assert(n = 3, "Sat.XmlReceiptVersion failed")

            Console.WriteLine(vbLf & "CREATE CADENA ORIGINAL DEL TIMBRE FISCAL DIGITAL (PIPESTRING FOR TFD):")
            fname = "ejemplo_v3_tfd.xml"
            certfile = "aaa010101aaa_CSD_02.cer"
            s = Tfd.MakePipeStringFromXml(fname)
            Console.WriteLine("Tfd.MakePipeStringFromXml('{0}') =" & vbLf & "{1}", fname, s)

            Console.WriteLine(vbLf & "FORM DIGEST OF PIPESTRING FOR TFD:")
            s = Tfd.MakeDigestFromXml(fname)
            Console.WriteLine("Tfd.MakeDigestFromXml('{0}')=" & vbLf & "{1}", fname, s)

            Console.WriteLine(vbLf & "EXTRACT DIGEST FROM TFD SELLOSAT:")
            ' NB certFile is required for Tfd
            s1 = Tfd.ExtractDigestFromSignature(fname, certfile)
            Console.WriteLine("Tfd.ExtractDigestFromSignature('{0}')=" & vbLf & "{1}", fname, s1)

            ' Check the two digests match
            Debug.Assert([String].Compare(s, s1, True) = 0, "Digests do not match")

            Console.WriteLine(vbLf & "PRETEND WE ARE A PAC WITH A KEY ALLOWED TO SIGN THE TFD:")
            ' Pretend we are a PAC with a key allowed to sign the TFD
            fname = "ejemplo_v3_tfd.xml"
            certfile = "aaa010101aaa_CSD_02.cer"
            keyfile = "aaa010101aaa_CSD_02.key"
            password = "a0123456789"
            s = Tfd.MakeSignatureFromXml(fname, keyfile, password)
            Console.WriteLine("Tfd.MakeSignatureFromXml('{0}')=" & vbLf & "{1}", fname, s)
            s1 = Sat.GetXmlAttribute(fname, "selloSAT", "TimbreFiscalDigital")
            Console.WriteLine("Correct=" & vbLf & "{0}", s1)
            Debug.Assert([String].Compare(s, s1, True) = 0, "selloSAT values do not match")

            Console.WriteLine(vbLf & "VERIFY SIGNATURE IN TFD SELLOSAT:")
            n = Tfd.VerifySignature(fname, certfile)
            Console.WriteLine("Tfd.VerifySignature({0},{1})={2} (expected 0)", fname, certfile, n)
            Debug.Assert(n = 0, "Tfd.VerifySignature failed")

            Console.WriteLine(vbLf & "ADD UTF-8 BOM TO EXISTING FILE:")
            fname = "Muestra_v2_signed2011.xml"
            newname = "Muestra_v2_with_BOM.xml"
            n = Sat.FixBom(newname, fname)
            Console.WriteLine("Sat.FixBom({0}->{1})={2} (expected 0)", fname, newname, n)
            Debug.Assert(n = 0, "Sat.FixBom failed")

            ' NEW IN [v5.0]... 

            Console.WriteLine(vbLf & "EXTRACT ATTRIBUTES FROM CONSECUTIVE ELEMENTS:")
            fname = "ejemplo_v3_base2011.xml"
            attributeName = "descripcion"
            elementName = "cfdi:Concepto"
            Console.WriteLine("For file '{0}'", fname)
            Dim i As Integer = 0
            Dim eName As String = Nothing
            For i = 1 To 100
                eName = elementName & String.Format("[{0:d}]", i)
                Console.Write("Sat.GetXmlAttribute({0},{1})=", attributeName, eName)
                s = Sat.GetXmlAttribute(fname, attributeName, eName)
                If (s.Length = 0) Then
                    Exit For
                End If
                Console.WriteLine("{0}", s)
            Next
            Console.WriteLine()

            Console.WriteLine(vbLf & "DETECT VERSION 2.2 OR 3.2 AUTOMATICALLY AND SIGN:")
            certfile = "aaa010101aaa_CSD_01.cer"
            keyfile = "aaa010101aaa_CSD_01.key"
            password = "a0123456789"

            fname = "Muestra_v22-base.xml"
            newname = "Muestra_v22-new_signed.xml"
            n = Sat.SignXml(newname, fname, keyfile, password, certfile)
            Console.WriteLine("Sat.SignXml('{0}'-->'{1}') returns {2}", fname, newname, n)
            Debug.Assert(n = 0, "Sat.SignXml failed")
            ' Did we make a valid XML file?
            n = Sat.ValidateXml(newname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", newname, n)
            Debug.Assert(n = 0, "Sat.ValidateXml failed")

            fname = "V2_2-base.xml"
            newname = "V2_2-new_signed.xml"
            n = Sat.SignXml(newname, fname, keyfile, password, certfile)
            Console.WriteLine("Sat.SignXml('{0}'-->'{1}') returns {2}", fname, newname, n)
            Debug.Assert(n = 0, "Sat.SignXml failed")
            ' Did we make a valid XML file?
            n = Sat.ValidateXml(newname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", newname, n)
            Debug.Assert(n = 0, "Sat.ValidateXml failed")

            fname = "ejemplo_v32-base.xml"
            newname = "ejemplo_v32-new_signed.xml"
            n = Sat.SignXml(newname, fname, keyfile, password, certfile)
            Console.WriteLine("Sat.SignXml('{0}'-->'{1}') returns {2}", fname, newname, n)
            Debug.Assert(n = 0, "Sat.SignXml failed")
            ' Did we make a valid XML file?
            n = Sat.ValidateXml(newname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", newname, n)
            Debug.Assert(n = 0, "Sat.ValidateXml failed")

            fname = "V3_2-base.xml"
            newname = "V3_2-new_signed.xml"
            n = Sat.SignXml(newname, fname, keyfile, password, certfile)
            Console.WriteLine("Sat.SignXml('{0}'-->'{1}') returns {2}", fname, newname, n)
            Debug.Assert(n = 0, "Sat.SignXml failed")
            ' Did we make a valid XML file?
            n = Sat.ValidateXml(newname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", newname, n)
            Debug.Assert(n = 0, "Sat.ValidateXml failed")

            Console.WriteLine(vbLf & "VALIDATE XML WITH STRICT AND LOOSE OPTIONS:")
            Console.WriteLine("Default strict behaviour (badly formed CURP attribute):")
            fname = "V3_2_BadCurp.xml"
            n = Sat.ValidateXml(fname)
            Console.WriteLine("Sat.ValidateXml('{0}') returns {1}", fname, n)
            s = Sat.LastError()
            Console.WriteLine("ErrorLookup({0})={1}", n, General.ErrorLookup(n))
            Console.WriteLine("LastError={0}", s)
            Debug.Assert(n <> 0, "Sat.ValidateXml failed to fail")

            Console.WriteLine(vbLf & "Using XmlOption.Loose:")
            n = Sat.ValidateXml(fname, XmlOption.Loose)
            Console.WriteLine("Sat.ValidateXml('{0}', Loose) returns {1}", fname, n)
            Debug.Assert(n = 0, "Sat.ValidateXml failed")

            Console.WriteLine(vbLf & "GET PRIVATE KEY AS BASE64:")
            fname = "aaa010101aaa_CSD_01.key"
            password = "a0123456789"
            s = Sat.GetKeyAsString(fname, password)
            Console.WriteLine("Sat.GetKeyAsString({0})=" & vbLf & "{1}" & vbLf, fname, s)
            Console.WriteLine("Sat.GetKeyAsString('{0}').Length={1}", fname, s.Length)
            Debug.Assert(s.Length > 0, "Sat.GetKeyAsString failed")

            ' Finally, show current version for core DLL
            Console.WriteLine(vbLf & "FirmaSAT Version={0} [{1}]", General.Version(), General.CompileTime())

            '---
            '              Console.WriteLine("\nDISPLAY ALL POSSIBLE ERROR MESSAGES:");
            '              for (i = 0; i < 10000; i++)
            '              {
            '                  s = General.ErrorLookup(i);
            '                  if (s.Length > 0)
            '                      Console.WriteLine("{0}={1}", i, s);
            '              }
            '             ---


        End Sub

        ' LOCAL UTILITIES...

        Private Shared Function FileIsNotPresent(ByVal filePath As String, ByVal message As String) As Boolean
            Dim fi As New FileInfo(filePath)
            If Not fi.Exists Then
                Console.WriteLine(vbLf & "{0}: {1}", message, filePath)
                Return True
            End If
            Return False
        End Function
    End Class
End Namespace