facho-signer: se separa main de libreria facho-signer
FossilOrigin-Name: ccb333de3a3210a4e82fb102e3eb41cb2d26c8fea5dd153898728978f85539b0
This commit is contained in:
parent
95bc4e73f5
commit
c08629337c
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user