/* $Id: diFirmaSat2.h $ */

/* Copyright (C) 2006-10 DI Management Services Pty Limited. 
   All rights reserved. <www.di-mgt.com.au> <www.cryptosys.net>

   Last updated:
   $Date: 2010-01-12 17:16 $
   $Revision: 2.0.0 $
*/

#ifndef DIFIRMASAT_H_
#define DIFIRMASAT_H_ 1

/* __stdcall convention required for Win32 DLL only */
#if defined(unix) || defined (linux) || defined(__linux)
#define _stdcall
#endif  

/* CONSTANTS */
#ifndef SAT_ENCODE_DEFINED_
#define SAT_ENCODE_UTF8   0
#define SAT_ENCODE_LATIN1 1
#define SAT_ENCODE_DEFINED_
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* DIAGNOSTIC FUNCTIONS */
long _stdcall SAT_Version(void);
long _stdcall SAT_CompileTime(char *szOutput, long nOutChars);
long _stdcall SAT_ModuleName(char *szOutput, long nOutChars, long reserved);
long _stdcall SAT_LicenceType(void);
long _stdcall SAT_PKIVersion(void);
long _stdcall SAT_PKICompileTime(char *szOutput, long nOutChars);
long _stdcall SAT_PKIModuleName(char *szOutput, long nOutChars, long reserved);
long _stdcall SAT_LastError(char *szErrMsg, long nMsgLen);
long _stdcall SAT_ErrorLookup(char *szErrMsg, long nMsgLen, long nErrCode);

/* SAT XML FUNCTIONS */
long _stdcall SAT_MakePipeStringFromXml(char *szOut, long nOutChars, const char *szXmlFile, long nOptions);
/*
SUMMARY: Creates the "piped" string (cadena) from an XML file.
INPUT:   XML file. 
OUTPUT:  "Piped" string (cadena).
RETURNS: Number of bytes in output string(*) or a negative error code.
OPTIONS: None.
REMARKS: Return value when querying may be too large if there are extra spaces to be removed
         -- this will not affect the final result.
*/

long _stdcall SAT_MakeSignatureFromXml(char *szOut, long nOutChars, const char *szXmlFile,
    const char *szKeyFile, const char *szPassword);
/*
SUMMARY: Creates the signature as a base64 string from data in an XML file.
INPUT:   XML file, encrypted key file, password
OUTPUT:  Signature string in base64 ready for insertion as `sello` field in XML.
RETURNS: Number of bytes in output string(*) or a negative error code.
*/

long _stdcall SAT_ValidateXml(const char *szXmlFile, long nOptions);
/*
SUMMARY: Validates an XML file against SAT specifications.
INPUT:   XML file.
OUTPUT:  "OK" or "validation fails" if file is (is not) correctly-formed SAT XML format.
RETURNS: Zero on success or a negative error code.
OPTIONS: None.
REMARKS: This just validates the XML, not the signature.
*/

long _stdcall SAT_VerifySignature(const char *szXmlFile, const char *szCertFile, long nOptions);
/*
SUMMARY: Verifies the signature (sello) in an XML file
INPUT:   XML file, [optional certificate file]
OUTPUT:  "OK" or "verification fails" if signature is/(is not) valid. 
RETURNS: Zero on success or a negative error code.
OPTIONS: None.
REMARKS: If no certificate file is specified, then the `certificado` field in the XML file will be used.
         If a separate certificate file is specified, it will be used instead.
*/

long _stdcall SAT_SignXml(const char *szOutputFile, const char *szInputXmlFile,
    const char *szKeyFile, const char *szPassword, const char *szCertFile, long nOptions);
/*
SUMMARY: Signs an XML file.
INPUT:   XML file with empty `sello` and [optional] `certificado`, `noCertificado` fields; 
         key filename; password; [certificate file].
OUTPUT:  New XML file with sello [and certificado, noCertificado] strings completed.
RETURNS: Zero on success or a negative error code.
OPTIONS: None.
REMARKS: Any existing file called `szOutputFile` will be over-written without warning.
         The input and output files can be the same.
         If a certificate file is specified AND an empty `certificado` field exists, the
         certificado string will be completed in the output XML file. Ditto for `noCertificado`.
*/

long _stdcall SAT_GetXmlAttribute(char *szOut, long nOutChars, const char *szXmlFile,
    const char *szAttribute, const char *szElement);
/*
SUMMARY: Extracts attribute data from an XML file
INPUT:   XML file, attribute name, element name.
OUTPUT:  String containing attribute data.
RETURNS: Number of bytes in output string(*) or a negative error code.
REMARKS: Attribute and element names are case-sensitive.
*/

long _stdcall SAT_MakeDigestFromXml(char *szOut, long nOutChars, const char *szXmlFile, long nOptions);
/*
SUMMARY: Forms the MD5 digest of piped string (cadena) from an XML file.
INPUT:   XML file. 
OUTPUT:  MD5 digest of "piped" string in hex form (expect 32 characters).
RETURNS: Number of bytes in output string(*) or a negative error code.
OPTIONS: None.
*/

long _stdcall SAT_ExtractDigestFromSignature(char *szOut, long nOutChars, const char *szXmlFile, 
    const char *szCertFile, long nOptions);
/*
SUMMARY: Extracts the MD5 digest from the signature (sello) in an XML file.
INPUT:   XML file, [optional certificate file]
OUTPUT:  MD5 digest in hex form extracted from signature field (expect 32 characters).
RETURNS: Number of bytes in output string(*) or a negative error code.
OPTIONS: None.
REMARKS: If the XML file contains a `certificado` field, then that certificate will be used;
         otherwise the user must specify a separate certificate file.
*/

long _stdcall SAT_GetCertNumber(char *szOut, long nOutChars, const char *szFileName, long nOptions);
/*
SUMMARY: Gets the serial number of the X.509 certificate in "special" SAT format.
INPUT:   XML file with `certificado` field OR X.509 certificate file
OUTPUT:  Certificate number in ACSII string (expect 20 characters).
RETURNS: Number of bytes in output string(*) or a negative error code.
OPTIONS: None.
REMARKS: This only works with a certificate issed by SAT with their special serial number format.
         If input is an XML file, this extracts the number directly from the `certificado` field,
         not the `noCertificado` field.
*/

long _stdcall SAT_GetCertExpiry(char *szOut, long nOutChars, const char *szFileName, long nOptions);
/*
SUMMARY: Gets the expiry date of the X.509 certificate in ISO time format.
INPUT:   XML file with `certificado` field OR X.509 certificate file
OUTPUT:  Expiry date of certificate in ISO time string format (expect 20 characters 'yyyy-mm-ddThh:nn:ssZ').
RETURNS: Number of bytes in output string(*) or a negative error code.
OPTIONS: None.
REMARKS: The time is GMT (UTC, Zulu time), not local.
*/

long _stdcall SAT_GetCertAsString(char *szOut, long nOutChars, const char *szFileName, long nOptions);
/*
SUMMARY: Gets the certificate data as a base64 string.
INPUT:   X.509 certificate file or XML file with `Certificado` field 
OUTPUT:  Certificate as a string of base64 characters.
RETURNS: Number of bytes in output string(*) or a negative error code.
OPTIONS: None.
REMARKS: Use to obtain the value for the `certificado` field from a .CER file.
         If input is an XML file, this is equivalent to SAT_GetXmlAttribute(..., "certificado", "Comprobante").
         If szOut is too small, it is set to the empty string.
*/

/*
(*) NOTE:
Functions that provide output in `szOut` require the string to be pre-dimensioned to the required length
PLUS one extra for the NUL-terminating byte.
The functions return the total length of the string they tried to create. 
Passing a NULL `szOut' or zero `nOutChars' will return the required length of the output string in bytes 
EXCLUDING the NUL-terminating byte, so remember to add one if allocating memory in C.
All output is UTF-8 encoded. 
For example:
    long nChars;
    char *lpszOut;
    nChars = SAT_MakePipeStringFromXml(NULL, 0, xmlfile, 0);
    if (nChars <= 0) error();
    lpszOut = malloc(nChars+1);  // NB +1
    nChars = SAT_MakePipeStringFromXml(lpszOut, nChars, xmlfile, 0);
    ...
*/

#ifdef __cplusplus
}
#endif

#endif /* DIFIRMASAT_H_ */