using System; using System.Diagnostics; using System.IO; using 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.cs $ * Last updated: * $Date: 2011-12-29 08:28:00 $ * $Version: 5.0.0 $ ************************* END OF COPYRIGHT NOTICE ************************ */ namespace TestFirmaSATcsharp { /// <summary> /// Test examples for FirmaSAT .NET interface /// </summary> class TestFirmaSATcsharp { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main(string[] args) { int n; string s, s1; string fname; char ch; string attributeName, elementName; string newname, keyfile, password, certfile, certStr; // Required test files (see `FirmaSATtestfiles.zip`) string[] arrFileNames = 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()); string missingFile = "STOPPED: Required file is missing in current working directory"; foreach (string fn in arrFileNames) { if (FileIsNotPresent(fn, missingFile)) return; } Console.WriteLine("\nFORM THE PIPESTRING FROM AN XML FILE:"); fname = "Muestra_v2_signed2011.xml"; s = Sat.MakePipeStringFromXml(fname); Console.WriteLine("Sat.MakePipeStringFromXml('{0}')=\n{1}", fname, s); Debug.Assert(s.Length > 0, "Sat.MakePipeStringFromXml failed"); Console.WriteLine("\nSIGN 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("\nVERIFY 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("\nFORM THE DIGEST OF THE PIPESTRING IN AN XML FILE:"); fname = "Muestra_v2_signed2011.xml"; s = Sat.MakeDigestFromXml(fname); Console.WriteLine("Sat.MakeDigestFromXml('{0}')=\n{1}", fname, s); Debug.Assert(s.Length > 0, "Sat.MakeDigestFromXml failed"); Console.WriteLine("\nEXTRACT THE DIGEST FROM THE SIGNATURE IN AN XML FILE:"); fname = "Muestra_v2_signed2011.xml"; s = Sat.ExtractDigestFromSignature(fname); Console.WriteLine("Sat.ExtractDigestFromSignature('{0}')=\n{1}", fname, s); Debug.Assert(s.Length > 0, "Sat.ExtractDigestFromSignature failed"); Console.WriteLine("\nTRY 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("\nEXTRACT 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})=\n{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})=\n{1}", fname, s, attributeName, elementName); Debug.Assert(s.Length > 0, "Sat.GetXmlAttribute failed"); Console.WriteLine("\nGET 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("\nGET CERTIFICATE AS A BASE64 STRING:"); fname = "aaa010101aaa_CSD_01.cer"; s = Sat.GetCertAsString(fname); Console.WriteLine("Sat.GetCertAsString('{0}')=\n{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("\nMAKE 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}')=\n{1}", fname, s); Debug.Assert(s.Length > 0, "Sat.MakeSignatureFromXml failed"); Console.WriteLine("\nSIGN 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("\nEXTRACT 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("\nEXTRACT 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("\nSIGN 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("\nVERIFY 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("\nEXTRACT THE DIGEST FROM THE SIGNATURE IN AN XML FILE:"); fname = "ejemplo_v3-new_signed.xml"; s = Sat.ExtractDigestFromSignature(fname); Console.WriteLine("Sat.ExtractDigestFromSignature('{0}')=\n{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)=\n{1}", fname, s); Debug.Assert(s.Length > 0, "Sat.ExtractDigestFromSignature failed"); Console.WriteLine("\nFORM 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}')=\n{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("\nGET 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}')=\t{1}", fname, s); Debug.Assert(s.Length > 0, "Sat.GetCertExpiry failed"); s = Sat.GetCertStart(fname); Console.WriteLine("Sat.GetCertStart('{0}') =\t{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}')=\t{1}", fname, s); Debug.Assert(s.Length > 0, "Sat.GetCertExpiry failed"); s = Sat.GetCertStart(fname); Console.WriteLine("Sat.GetCertStart('{0}') =\t{1}", fname, s); Debug.Assert(s.Length > 0, "Sat.GetCertStart failed"); Console.WriteLine("\nCHECK 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("\nFIND 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("\nCREATE 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}') =\n{1}", fname, s); Console.WriteLine("\nFORM DIGEST OF PIPESTRING FOR TFD:"); s = Tfd.MakeDigestFromXml(fname); Console.WriteLine("Tfd.MakeDigestFromXml('{0}')=\n{1}", fname, s); Console.WriteLine("\nEXTRACT DIGEST FROM TFD SELLOSAT:"); // NB certFile is required for Tfd s1 = Tfd.ExtractDigestFromSignature(fname, certfile); Console.WriteLine("Tfd.ExtractDigestFromSignature('{0}')=\n{1}", fname, s1); // Check the two digests match Debug.Assert(String.Compare(s, s1, true) == 0, "Digests do not match"); Console.WriteLine("\nPRETEND 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}')=\n{1}", fname, s); s1 = Sat.GetXmlAttribute(fname, "selloSAT", "TimbreFiscalDigital"); Console.WriteLine("Correct=\n{0}", s1); Debug.Assert(String.Compare(s, s1, true) == 0, "selloSAT values do not match"); Console.WriteLine("\nVERIFY 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("\nADD 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("\nEXTRACT ATTRIBUTES FROM CONSECUTIVE ELEMENTS:"); fname = "ejemplo_v3_base2011.xml"; attributeName = "descripcion"; elementName = "cfdi:Concepto"; Console.WriteLine("For file '{0}'", fname); int i = 0; string eName = null; for (i = 1; i <= 100; i++) { 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)) { break; } Console.WriteLine("{0}", s); } Console.WriteLine(); Console.WriteLine("\nDETECT 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("\nVALIDATE 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("\nUsing 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("\nGET PRIVATE KEY AS BASE64:"); fname = "aaa010101aaa_CSD_01.key"; password = "a0123456789"; s = Sat.GetKeyAsString(fname, password); Console.WriteLine("Sat.GetKeyAsString({0})=\n{1}\n", 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("\nFirmaSAT 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); } ---*/ } // LOCAL UTILITIES... static bool FileIsNotPresent(string filePath, string message) { FileInfo fi = new FileInfo(filePath); if (!fi.Exists) { Console.WriteLine("\n{0}: {1}", message, filePath); return true; } return false; } } }