facho-signer: se separa main de libreria facho-signer
FossilOrigin-Name: ccb333de3a3210a4e82fb102e3eb41cb2d26c8fea5dd153898728978f85539b0
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
				
			|||||||
bin_PROGRAMS = facho_signer
 | 
					bin_PROGRAMS = facho_signer
 | 
				
			||||||
facho_signer_SOURCES = xades/xmlsec1/xmltree.c xades/xmlsec1/errors.c xades/templates.c xades/xades.c facho_signer.c
 | 
					facho_signer_SOURCES = xades/xmlsec1/xmltree.c xades/xmlsec1/errors.c xades/templates.c xades/xades.c facho_signer.c main.c
 | 
				
			||||||
facho_signer_CFLAGS = $(OPENSSL_CFLAGS) $(XMLSEC1_CFLAGS) -DXMLSEC_NOT_CRYPTO_DYNAMIC_LOADING
 | 
					facho_signer_CFLAGS = $(OPENSSL_CFLAGS) $(XMLSEC1_CFLAGS) -DXMLSEC_NOT_CRYPTO_DYNAMIC_LOADING
 | 
				
			||||||
facho_signer_LDADD = $(OPENSSL_LIBS) $(LIBLTDL) $(XMLSEC1_LIBS)
 | 
					facho_signer_LDADD = $(OPENSSL_LIBS) $(LIBLTDL) $(XMLSEC1_LIBS)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,27 +10,24 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define xmlFachoPrintError(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
 | 
				
			||||||
#define print_error(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
 | 
					#define xmlFachoPrintInfo(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
 | 
				
			||||||
#define print_info(fmt, ...) fprintf(stdout, fmt, ##__VA_ARGS__)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const xmlChar ublExtensionDSigNs[] = "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2";
 | 
					const xmlChar ublExtensionDSigNs[] = "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2";
 | 
				
			||||||
const xmlChar policyIdDescription[] = "Política de firma para facturas electrónicas de la República de Colombia.";
 | 
					const xmlChar policyIdDescription[] = "Política de firma para facturas electrónicas de la República de Colombia.";
 | 
				
			||||||
const xmlChar policyIdIdentifier[] = "https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf";
 | 
					const xmlChar policyIdIdentifier[] = "https://facturaelectronica.dian.gov.co/politicadefirma/v2/politicadefirmav2.pdf";
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
char *basename = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// crea elemento /Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent
 | 
					// crea elemento /Invoice/ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent
 | 
				
			||||||
xmlNodePtr
 | 
					static xmlNodePtr
 | 
				
			||||||
xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc);
 | 
					xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FeC requiere que el digest value del policy identifier sea
 | 
					// FeC requiere que el digest value del policy identifier sea
 | 
				
			||||||
// apartir del contenido de la url.
 | 
					// apartir del contenido de la url.
 | 
				
			||||||
int
 | 
					static int
 | 
				
			||||||
xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *, xmlSecBufferPtr);
 | 
					xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *, xmlSecBufferPtr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					static int
 | 
				
			||||||
xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) {
 | 
					xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) {
 | 
				
			||||||
  xmlNodePtr qualifyingPropertiesNode = NULL;
 | 
					  xmlNodePtr qualifyingPropertiesNode = NULL;
 | 
				
			||||||
  xmlNodePtr signedPropertiesNode = NULL;
 | 
					  xmlNodePtr signedPropertiesNode = NULL;
 | 
				
			||||||
@@ -47,13 +44,13 @@ xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) {
 | 
				
			|||||||
  
 | 
					  
 | 
				
			||||||
  qualifyingPropertiesNode = xmlXadesTmplQualifyingPropertiesCreate(doc, signNode, BAD_CAST "xades-ref1");
 | 
					  qualifyingPropertiesNode = xmlXadesTmplQualifyingPropertiesCreate(doc, signNode, BAD_CAST "xades-ref1");
 | 
				
			||||||
  if (  qualifyingPropertiesNode == NULL ) {
 | 
					  if (  qualifyingPropertiesNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add QualifyingProperties node.\n");
 | 
					    xmlFachoPrintError("error: failed to add QualifyingProperties node.\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  signedPropertiesNode = xmlXadesTmplAddSignedProperties(qualifyingPropertiesNode, signedPropertiesId);
 | 
					  signedPropertiesNode = xmlXadesTmplAddSignedProperties(qualifyingPropertiesNode, signedPropertiesId);
 | 
				
			||||||
  if ( signedPropertiesNode == NULL ) {
 | 
					  if ( signedPropertiesNode == NULL ) {
 | 
				
			||||||
    print_error("error: xades failed to add signed properties node.\n");
 | 
					    xmlFachoPrintError("error: xades failed to add signed properties node.\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,54 +60,54 @@ xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) {
 | 
				
			|||||||
                                            signedPropertiesRef,
 | 
					                                            signedPropertiesRef,
 | 
				
			||||||
                                            BAD_CAST "http://uri.etsi.org/01903#SignedProperties");
 | 
					                                            BAD_CAST "http://uri.etsi.org/01903#SignedProperties");
 | 
				
			||||||
  if ( refNode == NULL ) {
 | 
					  if ( refNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add reference to signature template xades.\n");
 | 
					    xmlFachoPrintError("error: failed to add reference to signature template xades.\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformInclC14NId) == NULL ) {
 | 
					  if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformInclC14NId) == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add enveloped transform to reference for xades\n");
 | 
					    xmlFachoPrintError("error: failed to add enveloped transform to reference for xades\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const time_t now = time(NULL);
 | 
					  const time_t now = time(NULL);
 | 
				
			||||||
  signedSignaturePropertiesNode = xmlXadesTmplAddSignedSignatureProperties(signedPropertiesNode, localtime(&now));
 | 
					  signedSignaturePropertiesNode = xmlXadesTmplAddSignedSignatureProperties(signedPropertiesNode, localtime(&now));
 | 
				
			||||||
  if ( signedSignaturePropertiesNode == NULL ) {
 | 
					  if ( signedSignaturePropertiesNode == NULL ) {
 | 
				
			||||||
    print_error("error: xades failed to add signed signature properties node.\n");
 | 
					    xmlFachoPrintError("error: xades failed to add signed signature properties node.\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  signingCertificateNode = xmlXadesTmplAddSigningCertificate(signedSignaturePropertiesNode, xmlSecTransformSha256Id);
 | 
					  signingCertificateNode = xmlXadesTmplAddSigningCertificate(signedSignaturePropertiesNode, xmlSecTransformSha256Id);
 | 
				
			||||||
  if ( signingCertificateNode == NULL ) {
 | 
					  if ( signingCertificateNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add SigningCertificate node \n");
 | 
					    xmlFachoPrintError("error: failed to add SigningCertificate node \n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  signaturePolicyIdentifierNode = xmlXadesTmplAddSignaturePolicyIdentifier(signedSignaturePropertiesNode);
 | 
					  signaturePolicyIdentifierNode = xmlXadesTmplAddSignaturePolicyIdentifier(signedSignaturePropertiesNode);
 | 
				
			||||||
  if ( signaturePolicyIdentifierNode == NULL ) {
 | 
					  if ( signaturePolicyIdentifierNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add PolicyIdentifier node\n");
 | 
					    xmlFachoPrintError("error: failed to add PolicyIdentifier node\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  signaturePolicyIdNode = xmlXadesTmplAddSignaturePolicyId(signaturePolicyIdentifierNode);
 | 
					  signaturePolicyIdNode = xmlXadesTmplAddSignaturePolicyId(signaturePolicyIdentifierNode);
 | 
				
			||||||
  if ( signaturePolicyIdNode == NULL ) {
 | 
					  if ( signaturePolicyIdNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add SignaturePolicyId node.\n");
 | 
					    xmlFachoPrintError("error: failed to add SignaturePolicyId node.\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sigPolicyIdNode = xmlXadesTmplAddSigPolicyId(signaturePolicyIdNode, policyIdIdentifier, policyIdDescription);
 | 
					  sigPolicyIdNode = xmlXadesTmplAddSigPolicyId(signaturePolicyIdNode, policyIdIdentifier, policyIdDescription);
 | 
				
			||||||
  if ( sigPolicyIdNode == NULL ) {
 | 
					  if ( sigPolicyIdNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add SigPolicyId node.\n");
 | 
					    xmlFachoPrintError("error: failed to add SigPolicyId node.\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sigPolicyHashNode = xmlXadesTmplAddSigPolicyHash(signaturePolicyIdNode, xmlSecTransformSha256Id);
 | 
					  sigPolicyHashNode = xmlXadesTmplAddSigPolicyHash(signaturePolicyIdNode, xmlSecTransformSha256Id);
 | 
				
			||||||
  if ( sigPolicyHashNode == NULL ) {
 | 
					  if ( sigPolicyHashNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add SigPolicyHash node.\n");
 | 
					    xmlFachoPrintError("error: failed to add SigPolicyHash node.\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  signerRoleNode = xmlXadesTmplAddSignerRole(signedSignaturePropertiesNode, BAD_CAST "supplier");
 | 
					  signerRoleNode = xmlXadesTmplAddSignerRole(signedSignaturePropertiesNode, BAD_CAST "supplier");
 | 
				
			||||||
  if ( signerRoleNode == NULL ) {
 | 
					  if ( signerRoleNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add SignerRole node.\n");
 | 
					    xmlFachoPrintError("error: failed to add SignerRole node.\n");
 | 
				
			||||||
    goto fail;
 | 
					    goto fail;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -122,18 +119,18 @@ xmlFachoTmplXadesCreate(xmlDocPtr doc, xmlNodePtr signNode) {
 | 
				
			|||||||
  return(-1);
 | 
					  return(-1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					int
 | 
				
			||||||
xmlXadesAppInit() {
 | 
					xmlFachoInit() {
 | 
				
			||||||
  xmlInitParser();
 | 
					  xmlInitParser();
 | 
				
			||||||
  LIBXML_TEST_VERSION;
 | 
					  LIBXML_TEST_VERSION;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if ( xmlSecInit() < 0 ) {
 | 
					  if ( xmlSecInit() < 0 ) {
 | 
				
			||||||
    print_error("xmlsec initialization failed.\n");
 | 
					    xmlFachoPrintError("xmlsec initialization failed.\n");
 | 
				
			||||||
    return(-1);
 | 
					    return(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( xmlSecCheckVersion() != 1 ) {
 | 
					  if ( xmlSecCheckVersion() != 1 ) {
 | 
				
			||||||
    print_error("loaded xmlsec library version is not compatible.\n");
 | 
					    xmlFachoPrintError("loaded xmlsec library version is not compatible.\n");
 | 
				
			||||||
    return(-1);
 | 
					    return(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,61 +144,39 @@ xmlXadesAppInit() {
 | 
				
			|||||||
#endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
 | 
					#endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
 | 
				
			||||||
   
 | 
					   
 | 
				
			||||||
  if ( xmlSecCryptoAppInit(NULL) < 0 ) {
 | 
					  if ( xmlSecCryptoAppInit(NULL) < 0 ) {
 | 
				
			||||||
    print_error("crypto initialization failed.\n");
 | 
					    xmlFachoPrintError("crypto initialization failed.\n");
 | 
				
			||||||
    return(-1);
 | 
					    return(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( xmlSecCryptoInit() < 0 ) {
 | 
					  if ( xmlSecCryptoInit() < 0 ) {
 | 
				
			||||||
    print_error("xmlsec-crypto initialization failed.\n");
 | 
					    xmlFachoPrintError("xmlsec-crypto initialization failed.\n");
 | 
				
			||||||
    return(-1);
 | 
					    return(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return(0);
 | 
					  return(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					int
 | 
				
			||||||
xmlXadesAppShutdown() {
 | 
					xmlFachoShutdown() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( xmlSecCryptoShutdown() < 0 ) {
 | 
					  if ( xmlSecCryptoShutdown() < 0 ) {
 | 
				
			||||||
    print_error("xmlSecCryptoShutdown failed.\n");
 | 
					    xmlFachoPrintError("xmlSecCryptoShutdown failed.\n");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( xmlSecCryptoAppShutdown() < 0 ) {
 | 
					  if ( xmlSecCryptoAppShutdown() < 0 ) {
 | 
				
			||||||
    print_error("xmlSecCryptoAppShutdown failed.\n");
 | 
					    xmlFachoPrintError("xmlSecCryptoAppShutdown failed.\n");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if ( xmlSecShutdown() < 0 ) {
 | 
					  if ( xmlSecShutdown() < 0 ) {
 | 
				
			||||||
    print_error("xmlsec shutdown failed.\n");
 | 
					    xmlFachoPrintError("xmlsec shutdown failed.\n");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  xmlCleanupParser();
 | 
					  xmlCleanupParser();
 | 
				
			||||||
  return(0);
 | 
					  return(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*    
 | 
					int
 | 
				
			||||||
    X509 *cert = xmlSecOpenSSLKeyDataX509GetCert(keyData, 0);
 | 
					xmlFachoSignFile(FILE *out, const char *filename, const char *pkcs12name, const char *password) {
 | 
				
			||||||
    if (cert == NULL) {
 | 
					 | 
				
			||||||
      print_error("xmlSecOpenSSLKeyDataX509GetKeyCert fail\n");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    char *issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    printf("x509 issuer: %s\n", issuer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //https://stackoverflow.com/questions/9749560/how-to-calculate-x-509-certificates-sha-1-fingerprint-in-c-c-objective-c
 | 
					 | 
				
			||||||
    unsigned char md[EVP_MAX_MD_SIZE];
 | 
					 | 
				
			||||||
    unsigned int n;
 | 
					 | 
				
			||||||
    const EVP_MD *digest = EVP_get_digestbyname("sha256");
 | 
					 | 
				
			||||||
    X509_digest(cert, digest, md, &n);
 | 
					 | 
				
			||||||
    printf("%s", "Fingerprint:");
 | 
					 | 
				
			||||||
    for(int pos = 0; pos < 19 ; pos++) {
 | 
					 | 
				
			||||||
      printf("%02x:", md[pos]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    printf("%02x\n", md[19]);
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int
 | 
					 | 
				
			||||||
xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *password) {
 | 
					 | 
				
			||||||
  xmlDocPtr doc = NULL;
 | 
					  xmlDocPtr doc = NULL;
 | 
				
			||||||
  xmlNodePtr signNode = NULL;
 | 
					  xmlNodePtr signNode = NULL;
 | 
				
			||||||
  xmlNodePtr refNode = NULL;
 | 
					  xmlNodePtr refNode = NULL;
 | 
				
			||||||
@@ -219,14 +194,14 @@ xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *passw
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  doc = xmlParseFile(filename);
 | 
					  doc = xmlParseFile(filename);
 | 
				
			||||||
  if ( (doc == NULL) || (xmlDocGetRootElement(doc) == NULL) ) {
 | 
					  if ( (doc == NULL) || (xmlDocGetRootElement(doc) == NULL) ) {
 | 
				
			||||||
    print_error("error: unable to parse file %s\n", filename);
 | 
					    xmlFachoPrintError("error: unable to parse file %s\n", filename);
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformInclC14NId,
 | 
					  signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformInclC14NId,
 | 
				
			||||||
                                       xmlSecTransformRsaSha256Id, NULL);
 | 
					                                       xmlSecTransformRsaSha256Id, NULL);
 | 
				
			||||||
  if ( signNode == NULL ) {
 | 
					  if ( signNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to create signature template.\n");
 | 
					    xmlFachoPrintError("error: failed to create signature template.\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -238,11 +213,11 @@ xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *passw
 | 
				
			|||||||
                                            BAD_CAST "", //uri
 | 
					                                            BAD_CAST "", //uri
 | 
				
			||||||
                                            NULL); //type
 | 
					                                            NULL); //type
 | 
				
			||||||
  if ( refNode == NULL ) {
 | 
					  if ( refNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add reference to signature template.\n");
 | 
					    xmlFachoPrintError("error: failed to add reference to signature template.\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL ) {
 | 
					  if ( xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add enveloped transform to reference\n");
 | 
					    xmlFachoPrintError("error: failed to add enveloped transform to reference\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -252,72 +227,79 @@ xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *passw
 | 
				
			|||||||
                                            BAD_CAST "#xmldsig-facho-KeyInfo",
 | 
					                                            BAD_CAST "#xmldsig-facho-KeyInfo",
 | 
				
			||||||
                                            NULL);
 | 
					                                            NULL);
 | 
				
			||||||
  if ( refNode == NULL ) {
 | 
					  if ( refNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add reference to signature template key-info.\n");
 | 
					    xmlFachoPrintError("error: failed to add reference to signature template key-info.\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, BAD_CAST "xmldsig-facho-KeyInfo");
 | 
					  keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, BAD_CAST "xmldsig-facho-KeyInfo");
 | 
				
			||||||
  if ( keyInfoNode == NULL ) {
 | 
					  if ( keyInfoNode == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add key info.\n");
 | 
					    xmlFachoPrintError("error: failed to add key info.\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  x509DataNode = xmlSecTmplKeyInfoAddX509Data(keyInfoNode);
 | 
					  x509DataNode = xmlSecTmplKeyInfoAddX509Data(keyInfoNode);
 | 
				
			||||||
  if ( x509DataNode == NULL ) {
 | 
					  if ( x509DataNode == NULL ) {
 | 
				
			||||||
    print_error("error: failde to add x509 DATA \n");
 | 
					    xmlFachoPrintError("error: failde to add x509 DATA \n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( xmlSecTmplX509DataAddCertificate(x509DataNode) == NULL ) {
 | 
					  if ( xmlSecTmplX509DataAddCertificate(x509DataNode) == NULL ) {
 | 
				
			||||||
    print_error("error: failde to add x509Certificate node\n");
 | 
					    xmlFachoPrintError("error: failde to add x509Certificate node\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( xmlFachoTmplXadesCreate(doc, signNode) < 0 ){
 | 
					  if ( xmlFachoTmplXadesCreate(doc, signNode) < 0 ){
 | 
				
			||||||
    print_error("error: xmlFachoTmplXadesCreate failed.\n");
 | 
					    xmlFachoPrintError("error: xmlFachoTmplXadesCreate failed.\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  dsigCtx = xmlSecDSigCtxCreate(NULL);
 | 
					  dsigCtx = xmlSecDSigCtxCreate(NULL);
 | 
				
			||||||
  if ( dsigCtx == NULL ) {
 | 
					  if ( dsigCtx == NULL ) {
 | 
				
			||||||
    print_error("error: dsig context creating failed\n");
 | 
					    xmlFachoPrintError("error: dsig context creating failed\n");
 | 
				
			||||||
    return(-1);
 | 
					    return(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // cargamos el archivo pkcs12 con llave privado y certificados x509
 | 
				
			||||||
  dsigCtx->signKey = xmlSecCryptoAppKeyLoad(pkcs12name,
 | 
					  dsigCtx->signKey = xmlSecCryptoAppKeyLoad(pkcs12name,
 | 
				
			||||||
                                            xmlSecKeyDataFormatPkcs12,
 | 
					                                            xmlSecKeyDataFormatPkcs12,
 | 
				
			||||||
                                            password,
 | 
					                                            password,
 | 
				
			||||||
                                            NULL, NULL);
 | 
					                                            NULL, NULL);
 | 
				
			||||||
  if ( dsigCtx->signKey == NULL ) {
 | 
					  if ( dsigCtx->signKey == NULL ) {
 | 
				
			||||||
    print_error("error: failed to load pkcs12\n");
 | 
					    xmlFachoPrintError("error: failed to load pkcs12\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  xmlXadesPolicyIdentifierCtx policyIdCtx;
 | 
					  xmlXadesPolicyIdentifierCtx policyIdCtx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // por ahora el hash del identificador lo tomamos del pdf de la dian
 | 
				
			||||||
  policyIdCtx.contentCallback = &xmlFachoPolicyIdentifierCtxFromFilename;
 | 
					  policyIdCtx.contentCallback = &xmlFachoPolicyIdentifierCtxFromFilename;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  xadesDsigCtx = xmlXadesDSigCtxCreate(dsigCtx, XADES_DIGEST_SHA256, &policyIdCtx);
 | 
					  xadesDsigCtx = xmlXadesDSigCtxCreate(dsigCtx, XADES_DIGEST_SHA256, &policyIdCtx);
 | 
				
			||||||
  if ( xadesDsigCtx == NULL ) {
 | 
					  if ( xadesDsigCtx == NULL ) {
 | 
				
			||||||
    print_error("error: xades context creating failed.\n");
 | 
					    xmlFachoPrintError("error: xades context creating failed.\n");
 | 
				
			||||||
    return(-1);
 | 
					    return(-1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ( xmlXadesDSigCtxSign(xadesDsigCtx, signNode) < 0 ) {
 | 
					  // debe existir el elemento antes del firmado
 | 
				
			||||||
    print_error("error: signature failed\n");
 | 
					  node = xmlFachoTmplUBLExtensionAddExtensionContent(doc);
 | 
				
			||||||
 | 
					  if ( node == NULL ) {
 | 
				
			||||||
 | 
					    xmlFachoPrintError("error: failed to add UBLExtensions/UBLExtension/ExtensionContent\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  node = xmlFachoTmplUBLExtensionAddExtensionContent(doc);
 | 
					
 | 
				
			||||||
  if ( node == NULL ) {
 | 
					  // realizar firma de documento
 | 
				
			||||||
    print_error("error: failed to add UBLExtensions/UBLExtension/ExtensionContent\n");
 | 
					  if ( xmlXadesDSigCtxSign(xadesDsigCtx, signNode) < 0 ) {
 | 
				
			||||||
 | 
					    xmlFachoPrintError("error: signature failed\n");
 | 
				
			||||||
    goto done;
 | 
					    goto done;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  xmlUnlinkNode(signNode);
 | 
					  xmlUnlinkNode(signNode);
 | 
				
			||||||
  xmlSecAddChildNode(node, signNode);
 | 
					  xmlSecAddChildNode(node, signNode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  xmlDocDump(stdout, doc);
 | 
					  xmlDocDump(out, doc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  res = 0;
 | 
					  res = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -336,32 +318,7 @@ xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *passw
 | 
				
			|||||||
  return(res);
 | 
					  return(res);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char *argv[]) {
 | 
					static xmlNodePtr
 | 
				
			||||||
  basename = argv[0];
 | 
					 | 
				
			||||||
  int exitStatus = EXIT_SUCCESS;
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  if (argc != 4) {
 | 
					 | 
				
			||||||
    print_error("%s: <factura.xml> <pc12> <password>\n", basename);
 | 
					 | 
				
			||||||
    return(EXIT_FAILURE);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if ( xmlXadesAppInit() < 0 ) {
 | 
					 | 
				
			||||||
    print_error("initialization failed.\n");
 | 
					 | 
				
			||||||
    return(EXIT_FAILURE);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if ( xmlXadesSignFile( argv[1], argv[2], argv[3] ) != 0 ) {
 | 
					 | 
				
			||||||
    print_error("%s", "fail to sign file\n");
 | 
					 | 
				
			||||||
    exitStatus = EXIT_FAILURE;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  xmlXadesAppShutdown();  
 | 
					 | 
				
			||||||
  return(exitStatus);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
xmlNodePtr
 | 
					 | 
				
			||||||
xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc) {
 | 
					xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc) {
 | 
				
			||||||
  xmlNodePtr node = NULL;
 | 
					  xmlNodePtr node = NULL;
 | 
				
			||||||
  xmlNodePtr parent = NULL;
 | 
					  xmlNodePtr parent = NULL;
 | 
				
			||||||
@@ -373,28 +330,30 @@ xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc) {
 | 
				
			|||||||
  if ( parent == NULL ) {
 | 
					  if ( parent == NULL ) {
 | 
				
			||||||
    parent = xmlSecAddChild(xmlDocGetRootElement(doc), ublExtensionsName,  ublExtensionDSigNs);
 | 
					    parent = xmlSecAddChild(xmlDocGetRootElement(doc), ublExtensionsName,  ublExtensionDSigNs);
 | 
				
			||||||
    if ( parent == NULL ) {
 | 
					    if ( parent == NULL ) {
 | 
				
			||||||
      print_error("error: failed to cleate UBLExtensions.\n");
 | 
					      xmlFachoPrintError("error: failed to cleate UBLExtensions.\n");
 | 
				
			||||||
      return(NULL);
 | 
					      return(NULL);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // adicionamos nuevo elemento UBLExtension
 | 
				
			||||||
  node = xmlSecAddChild(parent, ublExtensionName, ublExtensionDSigNs);
 | 
					  node = xmlSecAddChild(parent, ublExtensionName, ublExtensionDSigNs);
 | 
				
			||||||
  if ( node == NULL ) {
 | 
					  if ( node == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add UBLExtension\n");
 | 
					    xmlFachoPrintError("error: failed to add UBLExtension\n");
 | 
				
			||||||
    xmlFreeNode(parent);
 | 
					    xmlFreeNode(parent);
 | 
				
			||||||
    return(NULL);
 | 
					    return(NULL);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // adicionamos nuevo elemento ExtensionContent
 | 
				
			||||||
  node = xmlSecAddChild(node, extensionContentName, ublExtensionDSigNs);
 | 
					  node = xmlSecAddChild(node, extensionContentName, ublExtensionDSigNs);
 | 
				
			||||||
  if ( node == NULL ) {
 | 
					  if ( node == NULL ) {
 | 
				
			||||||
    print_error("error: failed to add ExtensionContent");
 | 
					    xmlFachoPrintError("error: failed to add ExtensionContent");
 | 
				
			||||||
    return(NULL);
 | 
					    return(NULL);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return(node);
 | 
					  return(node);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					static int
 | 
				
			||||||
xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *policyId, xmlSecBufferPtr buffer) {
 | 
					xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *policyId, xmlSecBufferPtr buffer) {
 | 
				
			||||||
  static unsigned char politicafirmav2[] = {
 | 
					  static unsigned char politicafirmav2[] = {
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								experimental/facho-signer/src/facho_signer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								experimental/facho-signer/src/facho_signer.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					#ifndef FACHO_SIGNER_H
 | 
				
			||||||
 | 
					#define FACHO_SIGNER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					xmlFachoInit();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					xmlFachoShutdown();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					xmlFachoSignFile(FILE *out, const char *filename, const char *pkcs12name, const char *password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* FACHO_SIGNER_H */
 | 
				
			||||||
							
								
								
									
										32
									
								
								experimental/facho-signer/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								experimental/facho-signer/src/main.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					#include "xades/xades.h"
 | 
				
			||||||
 | 
					#include "facho_signer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *basename = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char *argv[]) {
 | 
				
			||||||
 | 
					  int exitStatus = EXIT_SUCCESS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  basename = argv[0];
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if (argc != 4) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "%s: <factura.xml> <pc12> <password>\n", basename);
 | 
				
			||||||
 | 
					    return(EXIT_FAILURE);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ( xmlFachoInit() < 0 ) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "initialization failed.\n");
 | 
				
			||||||
 | 
					    return(EXIT_FAILURE);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if ( xmlFachoSignFile( stdout, argv[1], argv[2], argv[3] ) != 0 ) {
 | 
				
			||||||
 | 
					    fprintf(stderr, "fail to sign file\n");
 | 
				
			||||||
 | 
					    exitStatus = EXIT_FAILURE;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  xmlFachoShutdown();  
 | 
				
			||||||
 | 
					  return(exitStatus);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user