FirmaSAT


Introduction

FirmaSAT is a add-on utility for users of the CryptoSys PKI Toolkit which enables you to create and read digital receipts (Comprobantes Fiscal Digital) as specified by the Servicio de Administración Tributaria* (SAT) in Mexico. FirmaSAT is a command-line program that works with Version 2.0 SAT XML files [REF1]. You can run it from the command-line, or call it from another program (e.g. from ColdFusion). There is a .NET class library for VB.NET and C# programmers, and an API which can be accessed by C++ programs.

For other related information, see SAT Mexico (last updated 2009-09-04) and the CryptoSys PKI Toolkit.

Contents

Introduction | Contents | Features | New in the Latest Version | Download | Buy Now | How to get started | Syntax | Input XML Files | Remarks | Detallista | Examples | API Interface | .NET Interface | FAQ | Troubleshooting | Legal Bits | Technical Details | XML Validation | Acknowledgments | References | Contact us | Revision History |

Features

FirmaSAT enables the user to:

New in the Latest Version

Version 2.0 of FirmaSAT:

Download

Download a free Trial Edition of FirmaSAT now. Use either

Unzip the zip file and run the setup.exe program inside it, or download the exe program directly and run it.

The Trial Edition is fully-functional. You need administrator privileges to install the program. Please read the licence conditions for the Trial Edition. The latest version 2.0.0 was released on 13 January 2010. The trial period is 60 days from the date first installed on your system. Requires the CryptoSys PKI Toolkit.

You can purchase a licensed version here. Existing licence holders can download the latest Developer Edition here.

How to get started

  1. Make sure that the CryptoSys PKI Toolkit is installed on your system. If you are a licensed user, you should already have it installed. If not, you can download and install a free, fully-functional, trial version from here.
  2. Download and install FirmaSAT.
  3. Open a command-line window in the FirmaSAT directory by using the menu options Start > Programs > FirmaSAT > FirmaSAT-open.

    (Alternatively, open a command-line window (MS-DOS window) and change directory by typing CD %APPDATA%\FirmaSAT.)

  4. Type FirmaSAT LIBINFO. If correctly installed, the output should be similar to:
    >FirmaSAT LIBINFO
    FirmaSat Version 2.0.0 last updated Jan 13 2010 13:29:08.
    diFirmaSat DLL:
      Version:  200
      Module:   C:\WINDOWS\system32\diFirmaSAT2.dll
      Compiled: Jan 13 2010 13:28:03
      Licence:  D
    CryptoSys PKI DLL:
      Version:  340
      Module:   C:\WINDOWS\system32\diCrPKI.dll
      Compiled: Dec 19 2009 21:54:59
    
    If you get an error message that says
    the application has failed to start because diCrPKI.dll/diFirmaSat2.dll was not found
    
    then the installation is not correct.
  5. If you get an error message
    'FirmaSAT' is not recognized as an internal or external command, operable program or batch file.
    
    then you need to set the path to the program which is in the %ProgramFiles%\FirmaSAT directory (or %ProgramFiles(x86)%\FirmaSAT in 64-bit Windows).
    SET PATH=%ProgramFiles%\FirmaSAT;%PATH%
    
    See the batch file SetupForFirmaSAT.bat provided.

Syntax

Usage: FirmaSat ACTION [OPTIONS] [-i] infile [[-o] outfile]
ACTION (one of):
 ATTRIBUTE     = extract a given Attribute from XML file.
 CERTSTRING    = get the Certificate data as a base64 string.
 DATENOTAFTER  = get the expiry Date of the certificate.
 EXTRACTDIGEST = Extract the digest from the signature.
 FORMDIGEST    = Form the digest of the pipestring.
 HELP          = display this Help.
 LIBINFO       = display DLL Library details.
 MAKESIG       = Make signature from XML file.
 NUMBERCERT    = get the certificate serial Number.
 PIPESTRING    = make Pipestring (cadena) from XML file.
 SIGNXML       = create the Signature and set `sello' field in XML file.
 VERIFYSIG     = Verify the signature in XML file.
 XMLOK         = validate XML file.
OPTIONS:
 -k <keyfile>        (required for SIGNXML)
 -p <password>       (required for SIGNXML)
 -c <certfile>       (optional X.509 certificate file for VERIFYSIG/SIGNXML)
 -a <attribute-name> (required for ATTRIBUTE action)
 -e <element-name>   (ditto)
 -s <statusfile>     (default=none; for stdout use ``-s @'')
 -t <tracking-info>  (optional info for the status file)
 -w display help/errors in Windows console font (default=Latin-1)
 -d show debug info; -dd show more
For help type ``FirmaSat HELP'' (en espanol, ``FirmaSat AYUDA -w'')
FirmaSat Version 2.0.0 last updated Jan 13 2010 13:29:08.

All action names and options are case-insensitive. To see the latest syntax, type ``FirmaSAT HELP''. En español, type ``FirmaSAT AYUDA -w''. The -w option causes the accented characters (e.g. ñ, é) to appear properly in the Windows console (at least for the help messages - UTF-8 characters in XML output will still appear "funny").

As an option, you can specify the name of a tracking file (using the -s option) which will contain the results of the operation. This can be used for tracking automated procedures.

Input XML file

All actions (except HELP and LIBINFO) require an input file to be specified. The input file must be a valid XML file encoded in UTF-8. Only SAT version 2.0 format is supported.

To create the piped-string using PIPESTRING or to make the signature using the MAKESIG action, only the fields required for the piped string need be present in the XML file.

To validate the XML file using XMLOK, all required fields must exist.

To verify the signature using VERIFYSIG, the `sello' field must exist and either the 'certificado' field exists in the XML file or the X.509 certificate file is specified in the command line using the -c option. As of Version 2, the certificate specified with the -c option will take priority over any `certificado' field.

To sign the XML file using the SIGNXML action, then `sello' must exist as an empty field (i.e. sello=""). The output XML file will have the `sello' field completed. A new output XML file is created by this action. The input file is not touched. The input and output files can be the same. If an X.509 certificate is specified using the -c option, then the `certificado' and `noCertificado' fields will be completed provided empty fields are specified in the input XML file. For example, your XML file for input should include the following:

<?xml version="1.0" encoding="utf-8"?>
<Comprobante ... version="2.0"
	noCertificado=""
	sello=""
	certificado="">

Remarks

  1. The output from the PIPESTRING action is UTF-8. This may not appear correctly when output to the stdout console. To see the correct form, always output to a text file. See FAQ.
  2. You will need a UTF-8-aware text editor to create the input XML file and to read the output files. We use IDM Computer Solutions' Ultra-Edit text editor which automatically detects and displays UTF-8 characters. The more recent versions of Windows NotePad are UTF-8-aware.
  3. The XMLOK action merely confirms that the XML file is correctly formed. The validation provided by FirmaSAT uses a DTD file and may not catch every strict detail such as types. See XML Validation for more details.

Complemento Detallista extension for retailers

Version 2.0 includes support for the Complemento Detallista extension for retailers as per [REF2]. There is an example XML file in the distribution (detallista_base.xml) that can be signed with the test keys (detallista-new-signed.xml) and the result passes the SAT validation. We have had only limited examples of this extension to test. We shall not comment about the awful verbosity that this new extension adds, nor the inconsistency in mixing element content and attributes, nor the inconsistent capitalization of field names. No, we shall not comment.

Here is a sample of the detallista part. Only nine fields in this extra section are used in the piped string. If you want to send us further examples of detallista XML files, please do.

<Complemento>
    <detallista:detallista type="SimpleInvoiceType" 
        documentStructureVersion="AMC8.1" 
        documentStatus="ORIGINAL" 
        contentVersion="1.3.1">
        <detallista:requestForPaymentIdentification>
            <detallista:entityType>INVOICE</detallista:entityType>
        </detallista:requestForPaymentIdentification>
        
        ...etc, etc...
        
    </detallista:detallista>
</Complemento>

Examples

These examples use the sample test files provided in FirmaSATtestfiles.zip. Note that the test certificates and keys used (from the SAT site) are due to expire in August 2010.


FirmaSAT XMLOK Muestra_v2_base2.xml

will check that the input file is validly formed XML. The output in this case should be

OK

If the XML file is not validly formed, the output would be like:

Error code -27: Invalid XML format: XML Validation Error: Required attribute 
'formaDePago' missing for element 'Comprobante' (Line: 2 Col: 311); ... etc ...

Note that this is merely checking that the XML formatting of the input file is OK.


FirmaSAT PIPESTRING Muestra_v2_base2.xml

will output the "piped-string" to the console, e.g.

||2.0|A|1|2009-08-16T16:30:00|1|2009|ingreso|
...etc...
|150.00|150|IVA|15.00|52.50||

Note that non-ASCII characters will not display properly on the console. It is better to output directly to a file:

FirmaSAT PIPESTRING Muestra_v2_base2.xml pipedstring.txt

FirmaSAT MAKESIG -k aaa010101aaa_csd_01.key -p a0123456789 Muestra_v2_base2.xml

will create the signature `sello' from the input XML file using the private key and password provided. The output should be

UlUSwGNEicfigV6i4RhTy0eb2RYWFYyFatJFcM/u5Wlkb5XRxXiCizTGw5Yxz9oZNk8msAgO4C5Gevjh
+S2TJPZueYhaQeZlo6k0rE3CQexkOGVRpHkvAoAgOM5kGKzYe24DKZbTgjNL+ai+tbhEHmRAFcpv2rDp
ehbL3w6BnYU=

FirmaSAT SIGNXML -s @ -k aaa010101aaa_csd_01.key -p a0123456789 ¶
   -c aaa010101aaa_csd_01.cer -i Muestra_v2_base2.xml -o Muestra_v2_signed2-new.xml

will create a new signed XML file `Muestra_v2_signed2-new.xml' from the input XML file `Muestra_v2_base2.xml'. It will sign using the private key in `aaa010101aaa_csd_01.key' and will add the `certificado' details from the X.509 certificate file `aaa010101aaa_csd_01.cer'. (Note that the above line is split for display purposes - it should be entered in one continuous line.) In version 2 it is now an error if the certificate and key do not match. See also the caution below about hard-coding passwords.


FirmaSAT VERIFYSIG Muestra_v2_signed2.xml

will verify the signature in the signed XML file. In this case it will use the `certificado' details in the XML file itself.

OK
FirmaSAT VERIFYSIG Muestra_v2_signed2-nocert.xml

will try to verify the signature in the signed XML file. In this case, there is no `certificado' field in the XML file and an error will result:

Error code -8: The data is invalid/Los datos no es válida: Invalid X.509 certificate
FirmaSAT VERIFYSIG -c aaa010101aaa_CSD_01.cer Muestra_v2_signed2-nocert.xml

will use the certificate `aaa010101aaa_CSD_01.cer' to verify the signature in the XML file. This should produce

OK

FirmaSAT ATTRIBUTE -d -a sello -e Comprobante -i Muestra_v2_signed2.xml

will extract the attribute `sello' from the element `Comprobante' in the input XML file. The output should look like this:

Attribute=[sello] Element=[Comprobante]
UlUSwGNEicfigV6i4RhTy0eb2RYWFYyFatJFcM/u5Wlkb5XRxXiCizTGw5Yxz9oZNk8msAgO4C5Gevjh
+S2TJPZueYhaQeZlo6k0rE3CQexkOGVRpHkvAoAgOM5kGKzYe24DKZbTgjNL+ai+tbhEHmRAFcpv2rDp
ehbL3w6BnYU=

FirmaSAT NUMBERCERT Muestra_v2_signed2.xml

will extract the serial number from the X.509 embedded in the `certificado' field of the XML file The output should look like this:

10001200000000022517

FirmaSAT DATENOTAFTER aaa010101aaa_CSD_01.cer

will extract the expiry date from the X.509 certificate file directly.

2010-08-21T15:22:08Z

FirmaSAT CERTSTRING aaa010101aaa_CSD_01.cer

will form the certificate string from the X.509 certificate file in the required base64 format to insert in the `certificado` field. The output should look like this:

MIIDhDCCAmygAwIBAgIUMTAwMDEyMDAwMDAwMDAwMjI1MTcwDQYJKoZIhvcNAQEFBQAwgcMxGTAXBgNV
BAcTEENpdWRhZCBkZSBNZXhpY28xFTATBgNVBAgTDE1leGljbywgRC5GLjELMAkGA1UEBhMCTVgxGjAY
...
tfROdG+1qYeA1q/is04O4AXNmMByGp7ZnvGNrO9LDBvs3eKN4ZYcQyjxFEbr1X/xUqHCRF1VEkkC5jJQ
1ktC4g==

FirmaSAT FORMDIGEST Muestra_v2_signed2.xml

will form the piped string from the XML file and then compute its message digest in hex form. The output should look like this:

4cd8ed248d7a02314c50778a37d1522d

This should match both the digest extracted with EXTRACTDIGEST (see below) and the "cadena original" displayed by the S.A.T. Validador. If it does not there is a problem - see Troubleshooting.


FirmaSAT EXTRACTDIGEST Muestra_v2_signed2.xml

will extract the message digest in hex form from the signature field in the XML file. It will use the embedded certificate in the XML file to decrypt the signature. The output should look like this:

4CD8ED248D7A02314C50778A37D1522D

FirmaSAT EXTRACTDIGEST -c aaa010101aaa_CSD_01.cer Muestra_v2_signed2-nocert.xml

will extract the message digest in hex form from the signature field in the XML file. In this case, as there is no embedded certificate, it requires the name of the X.509 certificate file. The output should look like this:

4CD8ED248D7A02314C50778A37D1522D

FirmaSAT HELP

will display the usage syntax.

FirmaSAT AYUDA -w

will display the usage syntax in Spanish (the -w option makes sure it displays properly on the Windows console).

FirmaSAT LIBINFO

will display details about the program and the libraries it depends on.


Hard-coded passwords - no!

CAUTION: You should never hard-code the password for your production private key anywhere. You should always require the user to enter it each time. Here is an example of a simple batch file that expects the password to be typed in as the first parameter.

@echo off
if "%1"=="" goto NOPASSWORD

set mypwd=%1

FirmaSAT SIGNXML -s @ -k aaa010101aaa_csd_01.key -p %mypwd% ¶
   -c aaa010101aaa_csd_01.cer -i Muestra_v2_base2.xml -o Muestra_v2_signed2-new.xml

set mypwd=
goto DONE
:NOPASSWORD
echo ERROR: no password
:DONE	

Use a text editor to create a batch file called, say, SignXMLTest.bat with the above text in it (the line beginning "FirmaSAT" with the ¶ character should be entered as one line).

Then type "SignXMLTest a0123456789" on the command line.

>SignXMLTest a0123456789
STATUS: 0
ERRORDESCRIPTION: OK
DATETIMECREATED: Thu Jan 14 11:48:13 2010

Obviously, you could adapt this batch file to cope with different files and certificates.

API Interface

To call from a C or C++ program, use

#include diFirmaSAT2.h

in your source code, call the functions, and link with the diFirmaSAT2.lib library. For more details on the core functions, see the file diFirmaSAT2.h.

.NET Interface for VB.NET and C# Programmers

The .NET interface allows programmers to call functions in FirmaSAT directly from C# and VB.NET (VB2005/8/x) programs. The core library diFirmaSAT2.dll must be installed on your system (as well as CryptoSys PKI). The .NET interface requires you to add a reference to the .NET Class Library file diFirmaSatNet.dll (the other DLLs are found automatically provided they are in the Library Search Path). Full details of the .NET methods are available in the file FirmaSat.NET.chm (zipped, 95 kB). You can browse this help on-line.

  1. In your application, add a reference to the library:
    1. Project > Add Reference.
    2. In the .NET tab, click on the Browse button to find and select the library file diFirmaSatNet.dll.
    3. Click on OK and the wizard will add the reference of the API library to your project.
  2. Add the line (for C#)
    using FirmaSAT;
    
    or (for VB.NET)
    Imports FirmaSAT
    
    to your code.
  3. Use the API methods at will, e.g. in C#
    using FirmaSAT;
    int n = General.Version();
    Console.WriteLine("Version = {0}", n);
    
    or in VB.NET
    Imports FirmaSAT
    Dim n As Integer
    n = General.Version()
    Console.WriteLine("Version = {0}", n)
    

See the example test code provided in the distribution download: TestFirmaSat.cs for C# and TestFirmaSat.vb for VB.NET.

Frequently Asked Questions

Why do strange characters like é appear in my output?
All output (except help and error messages) is in UTF-8. On a command-line console or in an old text editor that is not UTF-8-aware, the accented characters (áéíóúñ) will appear as two `funny' characters. For example, "México" will appear as "México". The solution is always to output to a text file and use a text editor that can cope with UTF-8.
Why is this in English? Why is your Spanish so bad?
Sorry, we're Australian and not Spanish speakers. We have tried our best with what knowledge we have and the help of our trusty assistant, Miss Google Translate. Please provide us with feedback. And, yes, the Monty Python translation in the Help was a deliberate joke.
Why does my XML file not validate?
Probably because the input to the signature function is not correct. There are so many possible errors we cannot list them. Try following the suggestions under Troubleshooting.

Troubleshooting

Try the following tests:
  1. FirmaSAT XMLOK myfile.xml
    
    If this fails, your XML is badly-formed.
  2. FirmaSAT FORMDIGEST myfile.xml
    
    4cd8ed248d7a02314c50778a37d1522d
    
  3. FirmaSAT EXTRACTDIGEST myfile.xml
    
    4CD8ED248D7A02314C50778A37D1522D
    

    If this test fails, your embedded signature (sello field) is corrupted or the certificate (certificado field) is wrong.

  4. Submit your file to the S.A.T. Validador site (which does not work with Firefox 3 because the site has an invalid security certificate!)
    El sello del comprobante es válido:
    Comprobante C:\somepath\myfile.xml leido exitosamente
    ...
    Digestión MD5 de cadena como HEX:
    4cd8ed248d7a02314c50778a37d1522d
    

The MD5 digest results for tests 2, 3 and 4 should all be the same (it does not matter that the letters are in upper-case [A-F] or lower-case [a-f]). If test 1 is OK, and the results of 2, 3 and 4 are the same, and the XML file still fails SAT validation, please send the file to us for further investigation.

Tests 2 and 3 are equivalent to

FirmaSAT VERIFYSIG myfile.xml

but they provide extra clues as to where the problem may be if the VERIFYSIG action fails.

Test 2
re-computes the MD5 digest of the piped-string (cadena) from the relevant fields in the XML file provided. If this matches test 4 then you know you are at least forming the piped-string correctly.
Test 3
extracts the digest from the signature embedded in the XML file (the signature is, in effect, an encrypted form of the MD5 digest). If you can extract anything from this test, you know you have created the RSA signature correctly, perhaps with the wrong input.
Test 4
gives the "official" correct version of the MD5 digest.

If tests 2 and 4 give the same result, but test 3 is different, then you are forming the piped-string correctly but somehow passing the wrong data to the signature function.

If tests 2 and 4 give different results, then there is an error in forming the piped-string. Remember, get just one character wrong in the piped-string and there will be an error.

If tests 2 and 3 give the same result, but test 4 is different then you are at least being internally consistent in creating the signature, but forming the piped-string incorrectly.

XML Validation

The XMLOK action validates the XML, meaning in this case merely that the XML is well formed (i.e. it says nothing about the digital signature). Validation of the XML is carried out using a DTD file plus some other checks. This catches almost all problems but will not catch strict element typing issues (like using a letter in a field where a number is required). The content of the Addenda element is ignored completely.

To carry out a more accurate validation using the XSD file provided by SAT, you will need to use a dedicated XML validation tool (try WMHelp.com's free XMLPad 3).

The "validation" carried out by the Validador site [SAT-VALIDADOR] is both a validation of the XML and a verification of the signature.

Legal Bits

Technical Details

The program should work on all 32-bit versions of Windows 95/98/Me/NT4/2000/XP/2003/Vista/W7.

The relevant executables are:

diFirmaSAT2.dll
The core FirmaSAT Win32 DLL required by all interfaces.
FirmaSAT.exe
Command line program.
diFirmaSatNet.dll
Dot-NET class library.
diCrPKI.dll
Core Win32 DLL for the CryptoSys PKI Toolkit (sold separately).

Dependencies: The program FirmaSAT.exe and the .NET class library diFirmaSatNet.dll are both dependent on the library file diFirmaSat2.dll, which, in turn, is dependent on the core CryptoSys PKI DLL diCrPKI.dll.

None of these files need to be (or can be) registered with RegSvr32.

Acknowledgments

References

[REF1]
Modificación al Anexo 20 de la Resolución Miscelánea Fiscal para 2006, Servicio de Administración Tributaria, Mexico, 22 June 2006, (pdf) 242 kB <ftp-link>
[REF2]
Complemento Detallista, Servicio de Administración Tributaria, Mexico, 19 December 2008, (pdf) 668 kB <ftp-link>
[SAT-VALIDADOR]
Validador de forma y sintaxis de Comprobantes Fiscales Digitales <link> (2010-01-14: does not work with FireFox 3 because the site has an invalid security certificate!)

Contact us

Contact: Send us an email.

For more information on the CryptoSys PKI Toolkit, go to <www.cryptosys.net/pki/>.

Revision History

This page last updated 24 January 2010