/* $Id: TestFirmaSAT.java $ */ /* $Date: 2015-01-13 20:19:00 $ */ /* $Version: 7.0.j0 $ */ /* * Copyright (C) 2014-15 DI Management Services Pty Limited. * All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net> */ import net.cryptosys.firmasat.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.FileNotFoundException; import java.io.UnsupportedEncodingException; /** The TestFirmaSAT class carries out a series of tests using the methods in the `net.cryptosys.firmasat` package. * <p>There is at least one test for each method in the package, including some obscure edge cases that you may not * need. All the methods in `net.cryptosys.firmasat` are static, intended to be called directly in a one-off manner. * </p> */ public final class TestFirmaSAT { private TestFirmaSAT() {} // Hide constructor. private static final int REQUIRE_MIN_VER = 70000; // Required test files (see `FirmaSATtestfiles.zip`) private static final String[] arrFileNames = new String[] { "ejemplo_v32-base2012.xml", "ejemplo_v32-tfd2012.xml", "ejemplo_v32-noprefix2012.xml", "ejemplo_v32-base-latin1.xml", "V3_2-base2012.xml", "V3_2_BadCurp.xml", "V2_2-base2012.xml", "Muestra_v22-base2012.xml", "Muestra_v22-signed2012.xml", "Muestra_v22-bad-nover.xml", "detallista_base2012.xml", "Muestra_v2_signed2011.xml", "ejemplo_v3_signed2011.xml", "Muestra_nomina.xml", "Muestra_nomina_tfd.xml", "Prueba2Notario_iedu.xml", "emisor.cer", "emisor.key", "pac.key", "pac.cer", "Ejemplo_Retenciones-base.xml", "Ejemplo_Retenciones-signed-tfd.xml", "AAA010101AAA201501CT-base.xml", "AAA010101AAA201501BN-base.xml", "contab-SelloDigitalContElec-signed.xml", "ConVolE12345-base.xml", "CSD_E12345CV_ACP020530MP5.key", "CSD_E12345CV_ACP020530MP5.cer", }; public static void main(String[] args) { int n; String s; char ch; String fname, newname; String certfile, keyfile, password, newpassword; String elementName, attributeName; String certStr, s1; boolean hasBOM; byte[] xmlArr; String xmlStr; String digest; byte[] b; // Print some system properties to get started... System.out.println("\nPRINT SOME SYSTEM PROPERTIES..."); System.out.println("java.version=" + System.getProperty("java.version")); System.out.println("os.arch=" + System.getProperty("os.arch")); System.out.println("os.name=" + System.getProperty("os.name")); System.out.println("os.version=" + System.getProperty("os.version")); System.out.println("file.encoding=" + System.getProperty("file.encoding")); System.out.println("\nTEST THE GENERAL CLASS..."); n = General.version(); System.out.println("General.version()=" + n); assert n >= REQUIRE_MIN_VER : "Require FirmaSAT v5.4.0 or higher"; s = General.moduleName(); System.out.println("General.moduleName()=" + s); //displayChars(s); s = General.platform(); System.out.println("General.platform()=" + s); s = General.compileTime(); System.out.println("General.compileTime()=" + s); //displayChars(s); ch = General.licenceType(); System.out.println("General.licenceType()=" + ch); s = General.lastError(); System.out.println("General.lastError()='" + s + "' (expecting empty)"); // CHECK FOR REQUIRED FILES IN CURRENT WORKING DIRECTORY System.out.println("Current working directory is "+System.getProperty("user.dir") ); String missingFile = "STOPPED: Required file is missing in current working directory"; for (String fn : arrFileNames) { if (fileIsNotPresent(fn, missingFile)) return; } System.out.println("\nLOOKUP MESSAGES FOR SOME ERROR CODES..."); n = 1; s = General.errorLookup(n); System.out.println("General.errorLookup("+n+")=" + s); n = 17; s = General.errorLookup(n); System.out.println("General.errorLookup("+n+")=" + s); n = 9999; s = General.errorLookup(n); System.out.println("General.errorLookup("+n+")=" + s); // TEST THE METHODS IN THE SAT CLASS... System.out.println("\nFORM THE PIPESTRING FROM AN XML FILE:"); fname = "ejemplo_v32-signed2012.xml"; s = Sat.makePipeStringFromXml(fname); System.out.println("Sat.makePipeStringFromXml('"+fname+"')=\n" + s); assert s.length() > 0 : "Sat.makePipeStringFromXml failed"; //displayChars(s); System.out.println("\nSIGN AN XML FILE:"); fname = "ejemplo_v32-base2012.xml"; newname = "ejemplo_v32-new_signed.xml"; keyfile = "emisor.key"; password = "12345678a"; /* CAUTION: DO NOT HARD-CODE REAL PASSWORDS! */ certfile = "emisor.cer"; n = Sat.signXml(newname, fname, keyfile, password, certfile); System.out.println("Sat.signXml('"+fname+"'-->'"+newname+"') returns "+n); assert n == 0 : "Sat.signXml failed"; // Did we make a valid XML file? n = Sat.validateXml(newname); System.out.println("Sat.validateXml('"+newname+"') returns "+n); assert n == 0 : "Sat.validateXml failed"; System.out.println("\nVERIFY A SIGNATURE IN AN XML FILE:"); System.out.println("1. One we know is good:"); fname = "ejemplo_v32-signed2012.xml"; n = Sat.verifySignature(fname); System.out.println("Sat.verifySignature('"+fname+"') returns "+n); assert n == 0 : "Sat.verifySignature failed"; System.out.println("2. One we just made, so it should be good:"); fname = newname; n = Sat.verifySignature(fname); System.out.println("Sat.verifySignature('"+fname+"') returns "+n); assert n == 0 : "Sat.verifySignature failed"; System.out.println("\nFORM THE DIGEST OF THE PIPESTRING IN AN XML FILE:"); fname = "ejemplo_v32-signed2012.xml"; s = Sat.makeDigestFromXml(fname); System.out.println("Sat.makeDigestFromXml('"+ fname+"')=\n"+ s); assert s.length() > 0 : "Sat.makeDigestFromXml failed"; System.out.println("\nEXTRACT THE DIGEST FROM THE SIGNATURE IN AN XML FILE:"); fname = "ejemplo_v32-signed2012.xml"; s = Sat.extractDigestFromSignature(fname); System.out.println("Sat.extractDigestFromSignature('"+ fname+"')=\n"+ s); assert s.length() > 0 : "Sat.extractDigestFromSignature failed"; System.out.println("\nTRY VALIDATING XML FILES:"); System.out.println("1. A valid one:"); fname = "Muestra_v22-signed2012.xml"; n = Sat.validateXml(fname); System.out.println("Sat.validateXml('"+ fname+"') returns "+ n); assert n == 0 : "Sat.validateXml failed"; System.out.println("2. An invalid one (missing version):"); fname = "Muestra_v22-bad-nover.xml"; n = Sat.validateXml(fname); System.out.println("Sat.validateXml('"+ fname+"') returns "+ n); s = General.lastError(); System.out.println("ErrorLookup("+ n+")="+ General.errorLookup(n)); System.out.println("LastError="+ s); assert n != 0 : "Sat.validateXml should have failed"; System.out.println("3. An invalid one (empty noCertificado):"); fname = "Muestra_v22-base2012-nocert.xml"; n = Sat.validateXml(fname); System.out.println("Sat.validateXml('"+ fname+"') returns "+ n); s = General.lastError(); System.out.println("ErrorLookup("+ n+")="+ General.errorLookup(n)); System.out.println("LastError="+ s); assert n != 0 : "Sat.validateXml should have failed"; System.out.println("\nEXTRACT AN ATTRIBUTE FROM AN XML FILE:"); fname = "ejemplo_v32-signed2012.xml"; elementName = "Comprobante"; attributeName = "sello"; s = Sat.getXmlAttribute(fname, attributeName, elementName); System.out.println("Sat.getXmlAttribute('"+ fname +"',"+ attributeName +","+ elementName +")=\n"+ s ); assert s.length() > 0 : "Sat.getXmlAttribute failed"; elementName = "Comprobante"; attributeName = "formaDePago"; s = Sat.getXmlAttribute(fname, attributeName, elementName); System.out.println("Sat.getXmlAttribute('"+ fname +"',"+ attributeName +","+ elementName +")=\n"+ s ); assert s.length() > 0 : "Sat.getXmlAttribute failed"; System.out.println("\nGET DETAILS OF X.509 CERTIFICATE:"); System.out.println("1. From embedded `certificado` in XML"); fname = "ejemplo_v32-signed2012.xml"; s = Sat.getCertNumber(fname); System.out.println("Sat.getCertNumber('"+ fname +"')="+ s ); assert s.length() > 0 : "Sat.getCertNumber failed"; s = Sat.getCertExpiry(fname); System.out.println("Sat.getCertExpiry('"+ fname +"')="+ s ); assert s.length() > 0 : "Sat.getCertExpiry failed"; System.out.println("2. From X.509 file"); fname = "emisor.cer"; s = Sat.getCertNumber(fname); System.out.println("Sat.getCertNumber('"+ fname +"')="+ s ); assert s.length() > 0 : "Sat.getCertNumber failed"; s = Sat.getCertExpiry(fname); System.out.println("Sat.getCertExpiry('"+ fname +"')="+ s ); assert s.length() > 0 : "Sat.getCertExpiry failed"; System.out.println("\nGET CERTIFICATE AS A BASE64 STRING:"); fname = "emisor.cer"; s = Sat.getCertAsString(fname); System.out.println("Sat.getCertAsString('"+ fname +"')=\n"+ s ); assert s.length() > 0 : "Sat.getCertAsString failed"; System.out.println("Sat.getCertAsString('"+ fname +"').length()="+ s.length() ); // Compare against String from XML file fname = "Muestra_v22-signed2012.xml"; s1 = Sat.getCertAsString(fname); System.out.println("Sat.getCertAsString('"+ fname +"').length()="+ s1.length() ); assert s1.length() > 0 : "Sat.getCertAsString failed"; assert s.equalsIgnoreCase(s1): "Sat.getCertAsString failed"; // Keep this String for later certStr = s1; System.out.println("\nMAKE A SIGNATURE FROM A BASE XML FILE:"); fname = "ejemplo_v32-base2012.xml"; keyfile = "emisor.key"; password = "12345678a"; /* CAUTION: DO NOT HARD-CODE REAL PASSWORDS! */ s = Sat.makeSignatureFromXml(fname, keyfile, password); System.out.println("Sat.makeSignatureFromXml('"+ fname +"')=\n"+ s ); assert s.length() > 0 : "Sat.makeSignatureFromXml failed"; System.out.println("\nSIGN A DETALLISTA XML FILE:"); fname = "detallista_base2012.xml"; newname = "detallista-new_signed.xml"; keyfile = "emisor.key"; password = "12345678a"; /* CAUTION: DO NOT HARD-CODE REAL PASSWORDS! */ certfile = "emisor.cer"; n = Sat.signXml(newname, fname, keyfile, password, certfile); System.out.println("Sat.signXml('"+ fname +"'-->'"+ newname +"') returns "+ n ); assert n == 0 : "Sat.signXml failed"; // Did we make a valid XML file? n = Sat.validateXml(newname); System.out.println("Sat.validateXml('"+ newname +"') returns "+ n ); assert n == 0 : "Sat.validateXml failed"; n = Sat.verifySignature(newname); System.out.println("Sat.verifySignature('"+ newname +"') returns "+ n ); assert n == 0 : "Sat.verifySignature failed"; System.out.println("\nEXTRACT AN ATTRIBUTE FROM A DETALLISTA XML FILE:"); fname = "detallista-new_signed.xml"; elementName = "detallista:detallista"; attributeName = "documentStructureVersion"; s = Sat.getXmlAttribute(fname, attributeName, elementName); System.out.println("Sat.getXmlAttribute('"+ fname +"',"+ attributeName +","+ elementName +")="+ s ); assert s.length() > 0 : "Sat.getXmlAttribute failed"; assert s.equalsIgnoreCase("AMC8.1") : "Invalid detallista.documentStructureVersion"; System.out.println("\nEXTRACT AN ATTRIBUTE WITH ACCENTED CHARACTERS:"); fname = "Muestra_v22-signed2012.xml"; elementName = "Domicilio"; attributeName = "pais"; s = Sat.getXmlAttribute(fname, attributeName, elementName); System.out.println("Sat.getXmlAttribute('"+ fname +"',"+ attributeName +","+ elementName +")="+ s ); assert s.length() > 0 : "Sat.getXmlAttribute failed"; assert s.equalsIgnoreCase("México") : "Invalid Domicilio/@pais attribute"; // SIGN CFDI Version="3.2" XML System.out.println("\nSIGN CFDi VERSION 3.2 XML FILE:"); fname = "ejemplo_v32-base2012.xml"; newname = "ejemplo_v32-new_signed.xml"; keyfile = "emisor.key"; password = "12345678a"; /* CAUTION: DO NOT HARD-CODE REAL PASSWORDS! */ certfile = "emisor.cer"; n = Sat.signXml(newname, fname, keyfile, password, certfile); System.out.println("Sat.signXml('"+ fname +"'-->'"+ newname +"') returns "+ n ); assert n == 0 : "Sat.signXml failed"; // Did we make a valid XML file? n = Sat.validateXml(newname); System.out.println("Sat.validateXml('"+ newname +"') returns "+ n ); assert n == 0 : "Sat.validateXml failed"; System.out.println("\nVERIFY A SHA-1 SIGNATURE IN AN XML FILE:"); fname = newname; n = Sat.verifySignature(fname); System.out.println("Sat.verifySignature('"+ fname +"') returns "+ n ); assert n == 0 : "Sat.verifySignature failed"; System.out.println("\nEXTRACT THE DIGEST FROM THE SIGNATURE IN AN XML FILE:"); fname = "ejemplo_v32-new_signed.xml"; s = Sat.extractDigestFromSignature(fname); System.out.println("Sat.extractDigestFromSignature('"+ fname +"')=\n"+ s ); assert s.length() > 0 : "Sat.extractDigestFromSignature failed"; System.out.println("Using a separate certificate file:"); fname = "ejemplo_v32-new_signed.xml"; certfile = "emisor.cer"; s = Sat.extractDigestFromSignature(fname, certfile); System.out.println("Sat.extractDigestFromSignature('"+ fname +"', certfile)=\n"+ s ); assert s.length() > 0 : "Sat.extractDigestFromSignature failed"; // Use certStr we extracted from emisor.cer above System.out.println("Using a separate certificate stored as a String:"); fname = "ejemplo_v32-new_signed.xml"; s = Sat.extractDigestFromSignature(fname, certStr); System.out.println("Sat.extractDigestFromSignature('"+ fname +"', certStr)=\n"+ s ); assert s.length() > 0 : "Sat.extractDigestFromSignature failed"; System.out.println("\nFORM THE SHA-1 DIGEST OF THE PIPESTRING IN AN XML FILE:"); fname = "ejemplo_v32-new_signed.xml"; s1 = Sat.makeDigestFromXml(fname, Sat.HashAlgorithm.Sha1); System.out.println("Sat.makeDigestFromXml('"+ fname +"')=\n"+ s1 ); assert s1.length() > 0 : "Sat.makeDigestFromXml failed"; // Check the two digests match assert s.equalsIgnoreCase(s1) : "Digests do not match"; System.out.println("\nGET VALIDITY DETAILS OF X.509 CERTIFICATE:"); System.out.println("1. From embedded `certificado` in XML"); fname = "ejemplo_v32-signed2012.xml"; s = Sat.getCertExpiry(fname); System.out.println("Sat.getCertExpiry('"+ fname +"')=\t"+ s ); assert s.length() > 0 : "Sat.getCertExpiry failed"; s = Sat.getCertStart(fname); System.out.println("Sat.getCertStart('"+ fname +"') =\t"+ s ); assert s.length() > 0 : "Sat.getCertStart failed"; System.out.println("2. From X.509 file"); fname = "emisor.cer"; s = Sat.getCertExpiry(fname); System.out.println("Sat.getCertExpiry('"+ fname +"')=\t"+ s ); assert s.length() > 0 : "Sat.getCertExpiry failed"; s = Sat.getCertStart(fname); System.out.println("Sat.getCertStart('"+ fname +"') =\t"+ s ); assert s.length() > 0 : "Sat.getCertStart failed"; System.out.println("\nCHECK PRIVATE KEY MATCHES PUBLIC KEY IN CERTIFICATE:"); certfile = "emisor.cer"; keyfile = "emisor.key"; password = "12345678a"; /* CAUTION: DO NOT HARD-CODE REAL PASSWORDS! */ n = Sat.checkKeyAndCert(keyfile, password, certfile); System.out.println("Sat.checkKeyAndCert("+ keyfile +","+ certfile +") = "+ n ); assert n == 0 : "Sat.checkKeyAndCert failed"; certfile = "pac.cer"; keyfile = "pac.key"; password = "12345678a"; n = Sat.checkKeyAndCert(keyfile, password, certfile); System.out.println("Sat.checkKeyAndCert("+ keyfile +","+ certfile +") = "+ n ); assert n == 0 : "Sat.checkKeyAndCert failed"; // Get embedded certificate from XML doc certfile = "ejemplo_v32-signed2012.xml"; keyfile = "emisor.key"; password = "12345678a"; n = Sat.checkKeyAndCert(keyfile, password, certfile); System.out.println("Sat.checkKeyAndCert("+ keyfile +","+ certfile +") = "+ n ); 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. // These strings are from `emisor-pem.cer` and `emisor-pem.key`, respectively certfile = "-----BEGIN CERTIFICATE-----" + "MIIEdDCCA1ygAwIBAgIUMjAwMDEwMDAwMDAxMDAwMDU4NjcwDQYJKoZIhvcNAQEF" + "BQAwggFvMRgwFgYDVQQDDA9BLkMuIGRlIHBydWViYXMxLzAtBgNVBAoMJlNlcnZp" + "Y2lvIGRlIEFkbWluaXN0cmFjacOzbiBUcmlidXRhcmlhMTgwNgYDVQQLDC9BZG1p" + "bmlzdHJhY2nDs24gZGUgU2VndXJpZGFkIGRlIGxhIEluZm9ybWFjacOzbjEpMCcG" + "CSqGSIb3DQEJARYaYXNpc25ldEBwcnVlYmFzLnNhdC5nb2IubXgxJjAkBgNVBAkM" + "HUF2LiBIaWRhbGdvIDc3LCBDb2wuIEd1ZXJyZXJvMQ4wDAYDVQQRDAUwNjMwMDEL" + "MAkGA1UEBhMCTVgxGTAXBgNVBAgMEERpc3RyaXRvIEZlZGVyYWwxEjAQBgNVBAcM" + "CUNveW9hY8OhbjEVMBMGA1UELRMMU0FUOTcwNzAxTk4zMTIwMAYJKoZIhvcNAQkC" + "DCNSZXNwb25zYWJsZTogSMOpY3RvciBPcm5lbGFzIEFyY2lnYTAeFw0xMjA3Mjcx" + "NzAyMDBaFw0xNjA3MjcxNzAyMDBaMIHbMSkwJwYDVQQDEyBBQ0NFTSBTRVJWSUNJ" + "T1MgRU1QUkVTQVJJQUxFUyBTQzEpMCcGA1UEKRMgQUNDRU0gU0VSVklDSU9TIEVN" + "UFJFU0FSSUFMRVMgU0MxKTAnBgNVBAoTIEFDQ0VNIFNFUlZJQ0lPUyBFTVBSRVNB" + "UklBTEVTIFNDMSUwIwYDVQQtExxBQUEwMTAxMDFBQUEgLyBIRUdUNzYxMDAzNFMy" + "MR4wHAYDVQQFExUgLyBIRUdUNzYxMDAzTURGUk5OMDkxETAPBgNVBAsTCFVuaWRh" + "ZCAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2TTQSPONBOVxpXv9wLYo8" + "jezBrb34i/tLx8jGdtyy27BcesOav2c1NS/Gdv10u9SkWtwdy34uRAVe7H0a3VMR" + "LHAkvp2qMCHaZc4T8k47Jtb9wrOEh/XFS8LgT4y5OQYo6civfXXdlvxWU/gdM/e6" + "I2lg6FGorP8H4GPAJ/qCNwIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQE" + "AwIGwDANBgkqhkiG9w0BAQUFAAOCAQEATxMecTpMbdhSHo6KVUg4QVF4Op2IBhiM" + "aOrtrXBdJgzGotUFcJgdBCMjtTZXSlq1S4DG1jr8p4NzQlzxsdTxaB8nSKJ4KEMg" + "IT7E62xRUj15jI49qFz7f2uMttZLNThipunsN/NF1XtvESMTDwQFvas/Ugig6qwE" + "fSZc0MDxMpKLEkEePmQwtZD+zXFSMVa6hmOu4M+FzGiRXbj4YJXn9Myjd8xbL/c+" + "9UIcrYoZskxDvMxc6/6M3rNNDY3OFhBK+V/sPMzWWGt8S1yjmtPfXgFs1t65AZ2h" + "cTwTAuHrKwDatJ1ZPfa482ZBROAAX1waz7WwXp0gso7sDCm2/yUVww==" + "-----END CERTIFICATE-----"; keyfile = "-----BEGIN ENCRYPTED PRIVATE KEY-----" + "MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI3V0iJrMlAI0CAggA" + "MBQGCCqGSIb3DQMHBAgmAnxnceS9FgSCAoBeM47Z7bIErpBCcTTUqChTzglQ2Om+" + "Nw4Nv0YZZkw8T0iLknP5J+p0EJHDQzATqHC1VZmG8+S23yJWSpYKzikQ0EdQCg3y" + "pl6QP55wdZ6DmkJQPo4cE+Z9elLT4QDRH//bJbZlnUtwKlu0ldMFNlBdAz/vYM4C" + "mad/cYIaR2tEJrJQvOiT4Z+c5Thf/3kLr5ohtVi7IDCFrIuSk0y0994rW4yGXQT7" + "/licNrOSDnBIWYP1poYa5YBFw6KMqA+uC7xwu6XGpdMJ3pyaogZUlw0MwL0mnWNI" + "DUkKm0lBrM0bEXZJgVbMzBokUupOMq6RAIOb6NXRREAw6mpyiekMNUE2ajXB2Xlj" + "1O12LqBEPMfdjeeQ1oakUuAfrTKiFIREcSW8472Xcmzu40u+zTCJVefpgNb6FF6V" + "L3QH3LZ+F2+A92rXn1gZETlHn9MjMfZyh7NUUbZ+BCpq0U2lyARbTZ2T+LvHP1gk" + "2oEDB/X+otXuK0cMxj8yG4tc5g7w7xo8GCMAu8zmKQa4pNd5+vND4JgwIaSWC5yW" + "EB0/E5qszMij2l1Ibni3Uj9HB8baf0ZU9hMahP4hjF1hFb4HfRxcmYOGyfldMCnr" + "1zQ0IZXCS5ki/xdrvxgkj6CEl9dXutPBrbg/mIPJLIkJPGQ2T78tlwvFl5C5i9U9" + "sOha2UmVXtDwg0zwWqLgS/6oQNYouQQlFbeH3jEYgHGENqunsIb0Nt4HBSQq6NgH" + "XGK7WRaLeDPIDr7j85cBdycuKXPH4Vtb8qx9dH4veKKz6ymbiHtXY63+3J4Geh6t" + "IzLduuX0CBiLob0R+gorwUK28i6bS373/d/GQoWOdBmSSws2BaHEGBmU" + "-----END ENCRYPTED PRIVATE KEY-----"; password = "12345678a"; n = Sat.checkKeyAndCert(keyfile, password, certfile); System.out.println("Sat.checkKeyAndCert(STRINGS) = "+ n ); assert n == 0 : "Sat.checkKeyAndCert failed"; System.out.println("\nFIND THE COMPROBANTE VERSION OF AN XML FILE:"); fname = "Muestra_v22-base2012.xml"; n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion('"+ fname +"') = "+ n ); assert n == 22 : "Sat.xmlReceiptVersion failed"; fname = "ejemplo_v32-base2012.xml"; n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion('"+ fname +"') = "+ n ); assert n == 32 : "Sat.xmlReceiptVersion failed"; // Older versions still work... fname = "Muestra_v2_signed2011.xml"; n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion('"+ fname +"') = "+ n ); assert n == 2 : "Sat.xmlReceiptVersion failed"; fname = "ejemplo_v3_signed2011.xml"; n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion('"+ fname +"') = "+ n ); assert n == 3 : "Sat.xmlReceiptVersion failed"; // Show we can cope with CFDi XML with no prefixes fname = "ejemplo_v32-noprefix2012.xml"; n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion('"+ fname +"') = "+ n ); assert n == 32 : "Sat.xmlReceiptVersion failed"; System.out.println("\nCREATE CADENA ORIGINAL DEL TIMBRE FISCAL DIGITAL (PIPESTRING FOR TFD):"); fname = "ejemplo_v32-tfd2012.xml"; s = Tfd.makePipeStringFromXml(fname); System.out.println("Tfd.makePipeStringFromXml('"+fname+"')=\n" + s); assert s.length() > 0 : "Tfd.makePipeStringFromXml failed"; System.out.println("\nFORM DIGEST OF PIPESTRING FOR TFD:"); s = Tfd.makeDigestFromXml(fname); System.out.println("Tfd.makeDigestFromXml('"+ fname +"')=\n"+ s ); assert s.length() > 0 : "Tfd.makeDigestFromXml failed"; System.out.println("\nEXTRACT DIGEST FROM TFD SELLOSAT:"); // NB certFile is required for Tfd certfile = "pac.cer"; s1 = Tfd.extractDigestFromSignature(fname, certfile); System.out.println("Tfd.extractDigestFromSignature('"+ fname +"')=\n"+ s1 ); // Check the two digests match assert s.equalsIgnoreCase(s1) : "Digests do not match"; System.out.println("\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 // so create a TFD signature String we could paste into the `selloSAT' node fname = "ejemplo_v32-tfd2012.xml"; certfile = "pac.cer"; keyfile = "pac.key"; password = "12345678a"; s = Tfd.makeSignatureFromXml(fname, keyfile, password); System.out.println("Tfd.makeSignatureFromXml('"+ fname +"')=\n"+ s ); s1 = Sat.getXmlAttribute(fname, "selloSAT", "TimbreFiscalDigital"); System.out.println("Correct=\n"+ s1 ); assert s.equalsIgnoreCase(s1) : "selloSAT values do not match"; System.out.println("\nVERIFY SIGNATURE IN TFD SELLOSAT:"); n = Tfd.verifySignature(fname, certfile); System.out.println("Tfd.verifySignature("+ fname +","+ certfile +")="+ n +" (expected 0)"); assert n == 0 : "Tfd.verifySignature failed"; System.out.println("\nADD UTF-8 BOM TO EXISTING FILE:"); fname = "Muestra_v22-signed2012.xml"; newname = "Muestra_v22-with_BOM.xml"; n = Sat.fixBom(newname, fname); System.out.println("Sat.fixBom("+ fname +"->"+ newname +")="+ n +" (expected 0)"); assert n == 0 : "Sat.fixBom failed"; System.out.println("\nEXTRACT ATTRIBUTES FROM CONSECUTIVE ELEMENTS:"); fname = "ejemplo_v32-base2012.xml"; attributeName = "descripcion"; elementName = "cfdi:Concepto"; System.out.println("For file '"+ fname +"'"); String eName = null; for (int i = 1; i <= 100; i++) { // Loop until we get an empty string returned... eName = elementName + String.format("[%d]", i); System.out.print("Sat.getXmlAttribute("+attributeName+","+eName+")="); s = Sat.getXmlAttribute(fname, attributeName, eName); if ((s.length() == 0)) { break; } System.out.println(s); } System.out.println(); System.out.println("\nVALIDATE XML WITH STRICT AND LOOSE OPTIONS:"); System.out.println("Default strict behaviour (Bad attribute..@CURP..is too long):"); fname = "V3_2_BadCurp.xml"; n = Sat.validateXml(fname); System.out.println("Sat.validateXml('"+ fname +"') returns "+ n ); s = General.lastError(); System.out.println("ErrorLookup("+ n +")="+ General.errorLookup(n) ); System.out.println("LastError="+ s ); assert n != 0 : "Sat.validateXml failed to fail"; System.out.println("\nUsing XmlOption.Loose:"); n = Sat.validateXml(fname, Sat.XmlOption.Loose); System.out.println("Sat.validateXml('"+ fname +"', Loose) returns "+ n ); assert n == 0 : "Sat.validateXml failed"; System.out.println("\nGET PRIVATE KEY AS BASE64:"); fname = "emisor.key"; password = "12345678a"; s = Sat.getKeyAsString(fname, password); System.out.println("Sat.getKeyAsString("+ fname +")=\n"+ s +"\n"); System.out.println("Sat.getKeyAsString('"+ fname +"').length()="+ s.length() ); assert s.length() > 0 : "Sat.getKeyAsString failed"; System.out.println("\nWRITE PFX FROM PRIVATE KEY AND CERT:"); certfile = "emisor.cer"; keyfile = "emisor.key"; password = "12345678a"; fname = "archivo_pfx.pem"; newpassword = "clavedesalida"; n = Sat.writePfxFile(fname, newpassword, keyfile, password, certfile); System.out.println("Sat.writePfxFile()->"+ fname +" returns "+ n ); assert n == 0 : "Sat.writePfxFile failed"; System.out.println("New PFX file is "+ fileLength(fname) +" bytes long."); System.out.println("\nGET RFC AND ORG NAME FROM CERT:"); fname = "emisor.cer"; System.out.println("FILE: "+ fname ); s = Sat.queryCert(fname, Sat.Query.rfc); System.out.println("Sat.queryCert(rfc)="+ s ); assert s.length() > 0 : "Sat.queryCert(rfc) failed"; s = Sat.queryCert(fname, Sat.Query.organizationName); System.out.println("Sat.queryCert(organizationName)='"+ s +"'"); assert s.length() > 0 : "Sat.queryCert(organizationName) failed"; fname = "ejemplo_v32-signed2012.xml"; System.out.println("FILE: "+ fname ); s = Sat.queryCert(fname, Sat.Query.rfc); System.out.println("Sat.queryCert(rfc)="+ s ); assert s.length() > 0 : "Sat.queryCert(rfc) failed"; s = Sat.queryCert(fname, Sat.Query.organizationName); System.out.println("Sat.queryCert(organizationName)='"+ s +"'"); assert s.length() > 0 : "Sat.queryCert(organizationName) failed"; System.out.println("\nTEST OTHER QUERIES FOR CERT:"); fname = "emisor.cer"; System.out.println("FILE: "+ fname ); s = Sat.queryCert(fname, Sat.Query.notBefore); System.out.println("Sat.queryCert(notBefore)="+ s ); assert s.length() > 0 : "Sat.queryCert(notBefore) failed"; s = Sat.queryCert(fname, Sat.Query.notAfter); System.out.println("Sat.queryCert(notAfter)="+ s ); assert s.length() > 0 : "Sat.queryCert(notAfter) failed"; s = Sat.queryCert(fname, Sat.Query.serialNumber); System.out.println("Sat.queryCert(serialNumber)="+ s ); assert s.length() > 0 : "Sat.queryCert(serialNumber) failed"; System.out.println("\nTEST NOMINA FEATURE:"); fname = "Muestra_nomina.xml"; System.out.println("FILE: "+ fname ); s = Sat.makePipeStringFromXml(fname); System.out.println("Sat.makePipeStringFromXml=\n"+ s ); assert s.length() > 0 : "Sat.makePipeStringFromXml failed"; newname = "Muestra_nomina2014-signed.xml"; certfile = "emisor.cer"; keyfile = "emisor.key"; password = "12345678a"; n = Sat.signXml(newname, fname, keyfile, password, certfile); System.out.println("Sat.signXml('"+ fname +"'-->'"+ newname +"') returns "+ n ); assert n == 0 : "Sat.signXml failed"; // Did we make a valid XML file? n = Sat.validateXml(newname); System.out.println("Sat.validateXml('"+ newname +"') returns "+ n +" ==> "+ (n==0 ? "OK" : "FAILED") ); assert n == 0 : "Sat.validateXml failed"; // Check file has a BOM hasBOM = FileHasBom(newname); System.out.println("File '"+ newname +"' "+ (hasBOM ? "has a BOM" : "does NOT have a BOM") ); assert hasBOM : "Expecting to find a BOM"; System.out.println("\nSIGN FILE WITHOUT BOM:"); newname = "Muestra_nomina2014-signed-no-bom.xml"; n = Sat.signXml(newname, fname, keyfile, password, certfile, Sat.SIGN_NO_BOM); System.out.println("Sat.signXml('"+ fname +"'-->'"+ newname +"') returns "+ n ); assert n == 0 : "Sat.signXml failed"; // Did we make a valid XML file? n = Sat.validateXml(newname); System.out.println("Sat.validateXml('"+ newname +"') returns "+ n +" ==> "+ (n == 0 ? "OK" : "FAILED") ); assert n == 0 : "Sat.validateXml failed"; // Check file does not have a BOM hasBOM = FileHasBom(newname); System.out.println("File '"+ newname +"' "+ (hasBOM ? "has a BOM" : "does NOT have a BOM") ); assert !hasBOM : "Not expecting to find a BOM"; System.out.println("\nSIGN FILE WITHOUT BOM AND EMPTY ELEMENTS:"); newname = "Muestra_nomina2014-signed-no-bom-empty-elems.xml"; n = Sat.signXml(newname, fname, keyfile, password, certfile, Sat.SIGN_NO_BOM + Sat.SIGN_USE_EMPTY_ELEMENTS); System.out.println("Sat.signXml('"+ fname +"'-->'"+ newname +"') returns "+ n ); assert n == 0 : "Sat.signXml failed"; // Did we make a valid XML file? n = Sat.validateXml(newname); System.out.println("Sat.validateXml('"+ newname +"') returns "+ n +" ==> "+ (n == 0 ? "OK" : "FAILED") ); assert n == 0 : "Sat.validateXml failed"; // Check file does not have a BOM hasBOM = FileHasBom(newname); System.out.println("File '"+ newname +"' "+ (hasBOM ? "has a BOM" : "does NOT have a BOM") ); assert !hasBOM : "Not expecting to find a BOM"; System.out.println("\nSIGN A `NOTARIOSPUBLICUS` XML FILE:"); fname = "Prueba2Notario_iedu.xml"; newname = "Prueba2Notario_iedu-signed.xml"; certfile = "emisor.cer"; keyfile = "emisor.key"; password = "12345678a"; n = Sat.signXml(newname, fname, keyfile, password, certfile); System.out.println("Sat.signXml('"+ fname +"'-->'"+ newname +"') returns "+ n ); assert n == 0 : "Sat.signXml failed"; // Did we make a valid XML file? n = Sat.validateXml(newname); System.out.println("Sat.validateXml('"+ newname +"') returns "+ n +" ==> "+ (n == 0 ? "OK" : "FAILED") ); assert n == 0 : "Sat.validateXml failed"; System.out.println("\nTEST TFD IN NOMINA XML:"); // One we made earlier using pac.key/pac.cer fname = "Muestra_nomina_tfd.xml"; certfile = "pac.cer"; s = Tfd.makePipeStringFromXml(fname); System.out.println("FILE: "+ fname ); System.out.println("Tfd.makePipeStringFromXml(TFD)=\n"+ s ); assert s.length() > 0 : "Tfd.makePipeStringFromXml(TFD) failed"; n = Tfd.verifySignature(fname, certfile); System.out.println("Tfd.verifySignature('"+ fname +"') returns "+ n +" ==> "+ (n == 0 ? "OK" : "FAILED") ); assert n == 0 : "Tfd.verifySignature failed"; System.out.println("\nADD A TFD ELEMENT TO A SIGNED CFDI DOCUMENT USING PAC KEY:"); fname = "Prueba2Notario_iedu-signed.xml"; newname = "Prueba2Notario_iedu-tfd.xml"; certfile = "pac.cer"; keyfile = "pac.key"; password = "12345678a"; n = Tfd.addSignedTfd(newname, fname, keyfile, password, certfile); System.out.println("Tfd.addSignedTfd('"+ fname +"'-->'"+ newname +"') returns "+ n ); assert n == 0 : "Tfd.addSignedTfd failed"; // Did we make a valid XML file? n = Sat.validateXml(newname); System.out.println("Sat.validateXml('"+ newname +"') returns "+ n +" ==> "+ (n == 0 ? "OK" : "FAILED") ); assert n == 0 : "Sat.validateXml failed"; // Does it have a valid selloSAT in the TFD? n = Tfd.verifySignature(newname, certfile); System.out.println("Tfd.verifySignature('"+ newname +"') returns "+ n +" ==> "+ (n == 0 ? "OK" : "FAILED") ); // Extract digests from the two signatures: `sello` and `selloSAT` digest = Sat.extractDigestFromSignature(newname); assert digest.length() > 0; System.out.println("DIGEST(sello, '"+ newname +"')=\n"+ digest ); // Note that the TFD selloSAT will be different each time it is created digest = Tfd.extractDigestFromSignature(newname, certfile); assert digest.length() > 0; System.out.println("DIGEST(selloSAT, '"+ newname +"')=\n"+ digest ); System.out.println("\nSIGN XML FROM BYTES TO STRING:"); // These strings are from `emisor-pem.cer` and `emisor-pem.key`, respectively certfile = "-----BEGIN CERTIFICATE-----" + "MIIEdDCCA1ygAwIBAgIUMjAwMDEwMDAwMDAxMDAwMDU4NjcwDQYJKoZIhvcNAQEF" + "BQAwggFvMRgwFgYDVQQDDA9BLkMuIGRlIHBydWViYXMxLzAtBgNVBAoMJlNlcnZp" + "Y2lvIGRlIEFkbWluaXN0cmFjacOzbiBUcmlidXRhcmlhMTgwNgYDVQQLDC9BZG1p" + "bmlzdHJhY2nDs24gZGUgU2VndXJpZGFkIGRlIGxhIEluZm9ybWFjacOzbjEpMCcG" + "CSqGSIb3DQEJARYaYXNpc25ldEBwcnVlYmFzLnNhdC5nb2IubXgxJjAkBgNVBAkM" + "HUF2LiBIaWRhbGdvIDc3LCBDb2wuIEd1ZXJyZXJvMQ4wDAYDVQQRDAUwNjMwMDEL" + "MAkGA1UEBhMCTVgxGTAXBgNVBAgMEERpc3RyaXRvIEZlZGVyYWwxEjAQBgNVBAcM" + "CUNveW9hY8OhbjEVMBMGA1UELRMMU0FUOTcwNzAxTk4zMTIwMAYJKoZIhvcNAQkC" + "DCNSZXNwb25zYWJsZTogSMOpY3RvciBPcm5lbGFzIEFyY2lnYTAeFw0xMjA3Mjcx" + "NzAyMDBaFw0xNjA3MjcxNzAyMDBaMIHbMSkwJwYDVQQDEyBBQ0NFTSBTRVJWSUNJ" + "T1MgRU1QUkVTQVJJQUxFUyBTQzEpMCcGA1UEKRMgQUNDRU0gU0VSVklDSU9TIEVN" + "UFJFU0FSSUFMRVMgU0MxKTAnBgNVBAoTIEFDQ0VNIFNFUlZJQ0lPUyBFTVBSRVNB" + "UklBTEVTIFNDMSUwIwYDVQQtExxBQUEwMTAxMDFBQUEgLyBIRUdUNzYxMDAzNFMy" + "MR4wHAYDVQQFExUgLyBIRUdUNzYxMDAzTURGUk5OMDkxETAPBgNVBAsTCFVuaWRh" + "ZCAxMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2TTQSPONBOVxpXv9wLYo8" + "jezBrb34i/tLx8jGdtyy27BcesOav2c1NS/Gdv10u9SkWtwdy34uRAVe7H0a3VMR" + "LHAkvp2qMCHaZc4T8k47Jtb9wrOEh/XFS8LgT4y5OQYo6civfXXdlvxWU/gdM/e6" + "I2lg6FGorP8H4GPAJ/qCNwIDAQABox0wGzAMBgNVHRMBAf8EAjAAMAsGA1UdDwQE" + "AwIGwDANBgkqhkiG9w0BAQUFAAOCAQEATxMecTpMbdhSHo6KVUg4QVF4Op2IBhiM" + "aOrtrXBdJgzGotUFcJgdBCMjtTZXSlq1S4DG1jr8p4NzQlzxsdTxaB8nSKJ4KEMg" + "IT7E62xRUj15jI49qFz7f2uMttZLNThipunsN/NF1XtvESMTDwQFvas/Ugig6qwE" + "fSZc0MDxMpKLEkEePmQwtZD+zXFSMVa6hmOu4M+FzGiRXbj4YJXn9Myjd8xbL/c+" + "9UIcrYoZskxDvMxc6/6M3rNNDY3OFhBK+V/sPMzWWGt8S1yjmtPfXgFs1t65AZ2h" + "cTwTAuHrKwDatJ1ZPfa482ZBROAAX1waz7WwXp0gso7sDCm2/yUVww==" + "-----END CERTIFICATE-----"; keyfile = "-----BEGIN ENCRYPTED PRIVATE KEY-----" + "MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI3V0iJrMlAI0CAggA" + "MBQGCCqGSIb3DQMHBAgmAnxnceS9FgSCAoBeM47Z7bIErpBCcTTUqChTzglQ2Om+" + "Nw4Nv0YZZkw8T0iLknP5J+p0EJHDQzATqHC1VZmG8+S23yJWSpYKzikQ0EdQCg3y" + "pl6QP55wdZ6DmkJQPo4cE+Z9elLT4QDRH//bJbZlnUtwKlu0ldMFNlBdAz/vYM4C" + "mad/cYIaR2tEJrJQvOiT4Z+c5Thf/3kLr5ohtVi7IDCFrIuSk0y0994rW4yGXQT7" + "/licNrOSDnBIWYP1poYa5YBFw6KMqA+uC7xwu6XGpdMJ3pyaogZUlw0MwL0mnWNI" + "DUkKm0lBrM0bEXZJgVbMzBokUupOMq6RAIOb6NXRREAw6mpyiekMNUE2ajXB2Xlj" + "1O12LqBEPMfdjeeQ1oakUuAfrTKiFIREcSW8472Xcmzu40u+zTCJVefpgNb6FF6V" + "L3QH3LZ+F2+A92rXn1gZETlHn9MjMfZyh7NUUbZ+BCpq0U2lyARbTZ2T+LvHP1gk" + "2oEDB/X+otXuK0cMxj8yG4tc5g7w7xo8GCMAu8zmKQa4pNd5+vND4JgwIaSWC5yW" + "EB0/E5qszMij2l1Ibni3Uj9HB8baf0ZU9hMahP4hjF1hFb4HfRxcmYOGyfldMCnr" + "1zQ0IZXCS5ki/xdrvxgkj6CEl9dXutPBrbg/mIPJLIkJPGQ2T78tlwvFl5C5i9U9" + "sOha2UmVXtDwg0zwWqLgS/6oQNYouQQlFbeH3jEYgHGENqunsIb0Nt4HBSQq6NgH" + "XGK7WRaLeDPIDr7j85cBdycuKXPH4Vtb8qx9dH4veKKz6ymbiHtXY63+3J4Geh6t" + "IzLduuX0CBiLob0R+gorwUK28i6bS373/d/GQoWOdBmSSws2BaHEGBmU" + "-----END ENCRYPTED PRIVATE KEY-----"; password = "12345678a"; // Read in a UTF-8-encoded XML file into a byte array fname = "ejemplo_v32-base2012.xml"; xmlArr = readABinaryFile(fname); System.out.println("File '"+ fname +"'-->"+ xmlArr.length +" UTF-8 bytes"); // Sign it and receive result back as a byte array... b = Sat.signXmlBytesToBytes(xmlArr, keyfile, password, certfile, 0); if (b.length == 0) { System.out.println("ERROR="+ General.lastError() ); } else { // Put in a String and print it... try { s = new String(b, "UTF-8"); } catch (UnsupportedEncodingException ex) { throw new AssertionError(ex); } System.out.println("XML-OUT=\n---\n"+ s +"\n---\n"); } assert b.length > 0 : "Sat.signXmlBytesToString failed"; System.out.println("\nSIGN XML FROM BYTES TO STRING USING EMPTY-ELEMENT TAGS:"); // Sign it and receive result back as a String... b = Sat.signXmlBytesToBytes(xmlArr, keyfile, password, certfile, Sat.SIGN_USE_EMPTY_ELEMENTS); if (b.length == 0) { System.out.println("ERROR="+ General.lastError() ); } else { // Put in a String and print it... try { s = new String(b, "UTF-8"); } catch (UnsupportedEncodingException ex) { throw new AssertionError(ex); } System.out.println("XML-OUT(UseEmptyElements)=\n---\n"+ s +"\n---\n"); } assert b.length > 0 : "Sat.signXmlBytesToString(UseEmptyElements) failed"; System.out.println("\nGENERATE 3 FRESH UUIDs:"); s = Sat.uuid(); System.out.println("Sat.uuid()=" + s); assert s.length() > 0 : "Sat.uuid failed"; System.out.println("Sat.uuid()=" + Sat.uuid()); System.out.println("Sat.uuid()=" + Sat.uuid()); System.out.println("\nPASS XML DATA AS A STRING:"); // Most methods will accept the XML data in a String instead of a filename, *but* ... System.out.println("Non-US-ASCII characters in String *must* be written as XML entities when XML encoding is UTF-8"); // This test XML is not a valid CFDi document. It's just a short string showing how to pass XML data // that happens to work with getXmlAttribute() and xmlReceiptVersion(). xmlStr = "<?xml version='1.0' encoding='UTF-8'?><Comprobante version='3.2' pais='MÉXICO' />"; System.out.println("Dummy test XML string=["+ xmlStr +"]"); n = Sat.xmlReceiptVersion(xmlStr); if (n == 0) System.out.println("ERROR="+ General.lastError() ); else System.out.println("xmlReceiptVersion()="+ n ); assert n == 32 : "Sat.xmlReceiptVersion(xmlStr) failed"; s = Sat.getXmlAttribute(xmlStr, "pais", "Comprobante"); if (s.length() == 0) System.out.println("ERROR="+ General.lastError() ); else System.out.println("getXmlAttribute(Combrobante/@pais)="+ s ); assert s.length() > 0 : "Sat.getXmlAttribute(xmlStr) failed"; // New in [v6.0] System.out.println("\nWORK WITH A `RETENCIONES` DOCUMENT:"); fname = "Ejemplo_Retenciones-base.xml"; System.out.println("FILE="+ fname ); n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion() returns "+ n +" (expecting 1010)"); assert 1010 == n : "Sat.xmlReceiptVersion failed"; s = Sat.makeDigestFromXml(fname); System.out.println("Sat.makeDigestFromXml() -> "+ s ); assert s.length() > 0 : "Sat.makeDigestFromXml failed"; // Use new [v6.0] option to find name of root element s = Sat.getXmlAttribute(fname, "", ""); System.out.println("File root element is '"+ s +"'"); assert s.length() > 0 : "Sat.getXmlAttribute('','') failed"; // New in [v7.0] System.out.println("\nWORK WITH `CONTABILIDAD` DOCUMENTS:"); fname = "AAA010101AAA201501CT-base.xml"; System.out.println("CATALOGOCUENTAS FILE="+ fname ); n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion() returns ID="+ n +" (expecting 2011)"); assert 2011 == n : "Sat.xmlReceiptVersion failed"; System.out.println("SIGN A CATALOGOCUENTAS DOCUMENT..."); newname = "AAA010101AAA201501CT.xml"; keyfile = "emisor.key"; certfile = "emisor.cer"; password = "12345678a"; n = Sat.signXml(newname, fname, keyfile, password, certfile); System.out.println("Sat.signXml() returns "+ n +" (expecting 0)"); assert 0 == n : "Sat.signXml failed"; n = Sat.verifySignature(newname); System.out.println("Sat.verifySignature() returns "+ n +" (expecting 0)"); assert 0 == n : "Sat.verifySignature failed"; fname = "AAA010101AAA201501BN-base.xml"; System.out.println("BALANZA FILE="+ fname ); n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion() returns ID="+ n +" (expecting 2111)"); assert 2111 == n : "Sat.xmlReceiptVersion failed"; System.out.println("MAKE THE SIGNATURE STRING FOR BALANZA..."); s = Sat.makeSignatureFromXml(fname, keyfile, password); System.out.println("Sat.makeSignatureFromXml() ->\n"+ s ); assert s.length() > 0 : "Sat.makeSignatureFromXml() failed"; fname = "contab-SelloDigitalContElec-signed.xml"; System.out.println("SELLODIGITALCONTELEC FILE="+ fname ); n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion() returns ID="+ n +" (expecting 2511)"); assert 2511 == n : "Sat.xmlReceiptVersion failed"; System.out.println("VERIFY SIGNATURE FOR SELLODIGITALCONTELEC USING PAC CERTIFICATE..."); n = Sat.verifySignature(fname, "pac.cer"); System.out.println("Sat.verifySignature() returns "+ n +" (expecting 0)"); assert 0 == n : "Sat.verifySignature failed"; System.out.println("\nWORK WITH `CONTROLESVOLUMETRICOS` DOCUMENT:"); fname = "ConVolE12345-base.xml"; System.out.println("FILE="+ fname ); n = Sat.xmlReceiptVersion(fname); System.out.println("Sat.xmlReceiptVersion() returns ID="+ n +" (expecting 4011)"); assert 4011 == n : "Sat.xmlReceiptVersion failed"; System.out.println("SIGN A CONVOL DOCUMENT WITH BIGFILE FLAG..."); newname = "ConVolE12345-signed.xml"; // Use key and cert provided for ConVol tests keyfile = "CSD_E12345CV_ACP020530MP5.key"; certfile = "CSD_E12345CV_ACP020530MP5.cer"; password = "12345678a"; n = Sat.signXml(newname, fname, keyfile, password, certfile, Sat.SIGN_BIGFILE); System.out.println("Sat.signXmlEx(BigFile) returns "+ n +" (expecting 0)"); assert 0 == n : "Sat.signXmlEx(BigFile) failed"; n = Sat.verifySignature(newname); System.out.println("Sat.verifySignature() returns "+ n +" (expecting 0)"); assert 0 == n : "Sat.verifySignature failed"; // ****************************************** // FINALLY, SHOW CURRENT VERSION FOR CORE DLL System.out.println("\nFirmaSAT DLL Version="+ General.version() +" ["+ General.compileTime() +"]"); } //********************************** // INTERNAL METHODS USED LOCALLY... //********************************** /** Return TRUE if the file is present else print message and return FALSE */ private static boolean fileIsNotPresent(String filePath, String message) { File f = new File(filePath); if (!f.exists()) { System.out.println("\n"+ message +": "+ filePath ); return true; } return false; } /** Returns the length of a file in bytes or -1 if not found */ private static long fileLength(String filePath) { File f = new File(filePath); if (!f.exists()) { return -1; } return f.length(); } /** Reads a binary file into a byte array */ private static byte[] readABinaryFile(String fileName) { byte[] b = new byte[0]; File file = new File(fileName); if (file.exists()) { b = new byte[(int) file.length()]; try { FileInputStream f = new FileInputStream(file); f.read(b); f.close(); } catch (FileNotFoundException ex) { System.out.println("Cannot find file '" + fileName + "'"); ex.printStackTrace(); } catch (IOException ex) { System.out.println("Error reading from file '" + fileName + "'"); ex.printStackTrace(); } } return b; } /** Returns TRUE if file has a UTF-8 Byte Order Mark */ private static boolean FileHasBom(String fileName) { final int kNBYTES = 3; byte[] buf = new byte[kNBYTES]; File file = new File(fileName); try { FileInputStream f = new FileInputStream(file); f.read(buf); f.close(); } catch (FileNotFoundException ex) { System.out.println("Cannot find file '" + fileName + "'"); ex.printStackTrace(); } catch (IOException ex) { System.out.println("Error reading from file '" + fileName + "'"); ex.printStackTrace(); } /* BOM consists of three bytes (0xEF, 0xBB, 0xBF) [NB (byte) cast here!] */ return (buf[0] == (byte)0xEF && buf[1] == (byte)0xBB && buf[2] == (byte)0xBF); } // /** Display all the chars in a string in hex format */ // private static void displayChars(String s) { // char[] chArr = s.toCharArray(); // for (int i = 0; i < chArr.length; i++) { // System.out.printf("%02x ", (byte)chArr[i]); // } // System.out.println(""); // } }