facho-signer: se adiciona policy Hash usando como contenido archivo pdf
FossilOrigin-Name: fcbbfe001fcbd8131064b5feee76f838e4c345a99eea26c5d0592b0277fbff17
This commit is contained in:
parent
012615f984
commit
7181c004cb
@ -25,8 +25,8 @@ xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc);
|
||||
|
||||
// FeC requiere que el digest value del policy identifier sea
|
||||
// apartir del contenido de la url.
|
||||
xmlXadesPolicyIdentifierCtxPtr
|
||||
xmlFachoPolicyIdentifierCtxFromFilename(const char *filename);
|
||||
int
|
||||
xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *, xmlSecBufferPtr);
|
||||
|
||||
|
||||
int
|
||||
@ -293,7 +293,11 @@ xmlXadesSignFile(const char *filename, const char *pkcs12name, const char *passw
|
||||
goto done;
|
||||
}
|
||||
|
||||
xadesDsigCtx = xmlXadesDSigCtxCreate(dsigCtx, XADES_DIGEST_SHA256, NULL);
|
||||
xmlXadesPolicyIdentifierCtx policyIdCtx;
|
||||
|
||||
policyIdCtx.contentCallback = &xmlFachoPolicyIdentifierCtxFromFilename;
|
||||
|
||||
xadesDsigCtx = xmlXadesDSigCtxCreate(dsigCtx, XADES_DIGEST_SHA256, &policyIdCtx);
|
||||
if ( xadesDsigCtx == NULL ) {
|
||||
print_error("error: xades context creating failed.\n");
|
||||
return(-1);
|
||||
@ -389,7 +393,14 @@ xmlFachoTmplUBLExtensionAddExtensionContent(xmlDocPtr doc) {
|
||||
return(node);
|
||||
}
|
||||
|
||||
xmlXadesPolicyIdentifierCtxPtr
|
||||
xmlFachoPolicyIdentifierCtxFromFilename(const char *filename) {
|
||||
return(NULL);
|
||||
int
|
||||
xmlFachoPolicyIdentifierCtxFromFilename(const xmlChar *policyId, xmlSecBufferPtr buffer) {
|
||||
static unsigned char politicafirmav2[] = {
|
||||
/**
|
||||
* generado con https://github.com/Jamesits/bin2array
|
||||
*/
|
||||
#include "politicafirmav2.c"
|
||||
};
|
||||
|
||||
return xmlSecBufferAppend(buffer, politicafirmav2, sizeof(politicafirmav2));
|
||||
}
|
||||
|
1
experimental/facho-signer/politicafirmav2.c
Normal file
1
experimental/facho-signer/politicafirmav2.c
Normal file
File diff suppressed because one or more lines are too long
@ -6,9 +6,6 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static xmlNodePtr
|
||||
xmlXadesTmplAddDigest(xmlNodePtr parentNode, const xmlChar *digestMethod, const xmlChar *digestValue);
|
||||
|
||||
xmlNodePtr
|
||||
xmlXadesAddChildRecursiveNs(xmlNodePtr startNode, const xmlChar* path, const xmlChar* nsPrefix) {
|
||||
char *curToken;
|
||||
@ -299,7 +296,7 @@ xmlXadesTmplAddSigPolicyHash(xmlNodePtr parentNode, xmlSecTransformId digestMeth
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if ( xmlXadesTmplAddDigest(node, digestMethodId->href, BAD_CAST "") == NULL) {
|
||||
if ( xmlXadesTmplAddDigest(node, digestMethodId->href, NULL) == NULL) {
|
||||
xmlXadesInternalError("xmlXadesTmplAddDigest(node, digestMethodId)", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
@ -308,36 +305,40 @@ xmlXadesTmplAddSigPolicyHash(xmlNodePtr parentNode, xmlSecTransformId digestMeth
|
||||
}
|
||||
|
||||
// MACHETE(bit4bit) como usar SecTransform para almacenar el digest
|
||||
static xmlNodePtr
|
||||
xmlNodePtr
|
||||
xmlXadesTmplAddDigest(xmlNodePtr parentNode, const xmlChar *digestMethod, const xmlChar *digestValue) {
|
||||
xmlNodePtr node;
|
||||
|
||||
xmlXadesAssert2(parentNode != NULL, NULL);
|
||||
|
||||
node = xmlSecAddChild(parentNode, xmlSecNodeDigestMethod, xmlSecDSigNs);
|
||||
if (node == NULL) {
|
||||
xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestMethod)", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
if (xmlSetProp(node, xmlSecAttrAlgorithm, digestMethod) == NULL) {
|
||||
xmlXadesXmlError2("xmlSetProp", NULL,
|
||||
"name=%s", xmlXadesErrorsSafeString(xmlSecAttrAlgorithm));
|
||||
xmlUnlinkNode(node);
|
||||
xmlFreeNode(node);
|
||||
return(NULL);
|
||||
if ( digestMethod != NULL ) {
|
||||
node = xmlSecAddChild(parentNode, xmlSecNodeDigestMethod, xmlSecDSigNs);
|
||||
if (node == NULL) {
|
||||
xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestMethod)", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
if (xmlSetProp(node, xmlSecAttrAlgorithm, digestMethod) == NULL) {
|
||||
xmlXadesXmlError2("xmlSetProp", NULL,
|
||||
"name=%s", xmlXadesErrorsSafeString(xmlSecAttrAlgorithm));
|
||||
xmlUnlinkNode(node);
|
||||
xmlFreeNode(node);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
node = xmlSecAddChild(parentNode, xmlSecNodeDigestValue, xmlSecDSigNs);
|
||||
if (node == NULL) {
|
||||
xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestValue)", NULL);
|
||||
return(NULL);
|
||||
if ( digestValue != NULL ) {
|
||||
node = xmlSecAddChild(parentNode, xmlSecNodeDigestValue, xmlSecDSigNs);
|
||||
if (node == NULL) {
|
||||
xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestValue)", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if (xmlSecNodeEncodeAndSetContent(node, digestValue) < 0) {
|
||||
xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (xmlSecNodeEncodeAndSetContent(node, digestValue) < 0) {
|
||||
xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
return parentNode;
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,14 @@
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
#include <xmlsec/buffer.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
static xmlChar *
|
||||
xmlXadesSha256DigestValueInBase64(const unsigned char *message, size_t message_len);
|
||||
|
||||
static xmlNodePtr
|
||||
xmlXadesXPathFirstElement(xmlDocPtr doc, const xmlChar *xpath);
|
||||
|
||||
@ -124,9 +129,74 @@ xmlXadesDSigCtxSign(xmlXadesDSigCtxPtr ctx, xmlNodePtr signNode) {
|
||||
xmlXadesInternalError("xmlXadesXPathFirstElement(xades:SigPolicyId/xades:Identifier\n", NULL);
|
||||
return(-1);
|
||||
}
|
||||
xmlChar *identifier = xmlNodeListGetString(signNode->doc, sigPolicyId->xmlChildrenNode, 1);
|
||||
printf("IDENTIFIER %s\n", identifier);
|
||||
xmlFree(identifier);
|
||||
|
||||
if ( ctx->policyCtx == NULL ) {
|
||||
xmlXadesInternalError("not found policy context.\n", NULL);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if ( ctx->policyCtx != NULL ) {
|
||||
|
||||
|
||||
if ( ctx->policyCtx->contentCallback == NULL ) {
|
||||
xmlXadesInternalError("not found policy content callback.\n", NULL);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
xmlSecTransformCtxPtr transformCtx = xmlSecTransformCtxCreate();
|
||||
if (transformCtx == NULL ) {
|
||||
xmlXadesInternalError("xmlSecTransformCtxCreate().\n", NULL);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// elemento del digest
|
||||
xmlNodePtr sigPolicyHashDigestMethod = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//xades:SigPolicyHash/ds:DigestMethod[1]");
|
||||
if ( sigPolicyHashDigestMethod == NULL ) {
|
||||
xmlXadesInternalError("xmlXadesXPathFirstElement(xades:SigPolicyHash/xades:DigestMethod\n", NULL);
|
||||
return(-1);
|
||||
}
|
||||
xmlSecTransformPtr transformPolicyDigestMethod = xmlSecTransformNodeRead(sigPolicyHashDigestMethod,
|
||||
xmlSecTransformUsageDigestMethod,
|
||||
transformCtx);
|
||||
if ( transformPolicyDigestMethod == NULL ) {
|
||||
xmlXadesInternalError("xmlSecTransformNodeRead\n", NULL);
|
||||
xmlFreeNode(sigPolicyHashDigestMethod);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if ( xmlSecTransformCheckId(transformPolicyDigestMethod, xmlSecTransformSha256Id) == 0 ) {
|
||||
xmlXadesInternalError("sigPolicyHash only support sha256 digest method .\n", NULL);
|
||||
xmlFreeNode(sigPolicyHashDigestMethod);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// TODO(bit4bit) podemos usar xmlSecTransform para calcular el digest?
|
||||
xmlNodePtr sigPolicyHashNode = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//xades:SigPolicyHash[1]");
|
||||
if ( sigPolicyHashNode == NULL ) {
|
||||
xmlXadesInternalError("failed to find sigPolicyHash node.\n", NULL);
|
||||
xmlFreeNode(sigPolicyHashDigestMethod);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// obtenemos contenido de la policy
|
||||
xmlChar *identifier = xmlNodeListGetString(signNode->doc, sigPolicyId->xmlChildrenNode, 1);
|
||||
xmlSecBufferPtr policyContent = xmlSecBufferCreate(1024);
|
||||
;
|
||||
if ( (ctx->policyCtx->contentCallback)(identifier, policyContent) < 0 ) {
|
||||
xmlXadesInternalError("policyContext callback fails.\n", NULL);
|
||||
xmlFree(identifier);
|
||||
return(-1);
|
||||
}
|
||||
xmlFree(identifier);
|
||||
|
||||
xmlChar *policyHashValue = xmlXadesSha256DigestValueInBase64(xmlSecBufferGetData(policyContent),
|
||||
xmlSecBufferGetSize(policyContent));
|
||||
|
||||
xmlSecBufferDestroy(policyContent);
|
||||
xmlXadesTmplAddDigest(sigPolicyHashNode, NULL, policyHashValue);
|
||||
}
|
||||
|
||||
return xmlSecDSigCtxSign(ctx->dsigCtx, signNode);
|
||||
}
|
||||
|
||||
@ -165,9 +235,9 @@ xmlXadesXPathFirstElement(xmlDocPtr doc, const xmlChar *xpath) {
|
||||
}
|
||||
|
||||
|
||||
xpathResult = xmlXPathEvalExpression(BAD_CAST "//ds:Object/xades:QualifyingProperties[1]", xpathCtx);
|
||||
xpathResult = xmlXPathEvalExpression(xpath, xpathCtx);
|
||||
if ( xmlXPathNodeSetIsEmpty( xpathResult->nodesetval ) ) {
|
||||
xmlXadesInternalError("can't find ds:Signature/ds:Object/xades:QualifyingProperties \n", NULL);
|
||||
xmlXadesInternalError("can't find %s \n", xpath);
|
||||
xmlXPathFreeObject(xpathResult);
|
||||
return(NULL);
|
||||
}
|
||||
@ -175,9 +245,40 @@ xmlXadesXPathFirstElement(xmlDocPtr doc, const xmlChar *xpath) {
|
||||
// obtener puntero a nodo
|
||||
node = xpathResult->nodesetval->nodeTab[0];
|
||||
if ( node->type != XML_ELEMENT_NODE ) {
|
||||
xmlXadesInternalError("expected element QualifyingProperties\n", NULL);
|
||||
xmlXadesInternalError("expected element\n", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
return(node);
|
||||
}
|
||||
|
||||
static xmlChar *
|
||||
xmlXadesSha256DigestValueInBase64(const unsigned char *message, size_t message_len)
|
||||
{
|
||||
unsigned char digest[2048];
|
||||
unsigned int digest_len;
|
||||
EVP_MD_CTX *mdctx;
|
||||
|
||||
if((mdctx = EVP_MD_CTX_new()) == NULL) {
|
||||
xmlXadesInternalError("EVP_MD_CTX_new().\n", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if(1 != EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) {
|
||||
xmlXadesInternalError("EVP_DigestInit_ex().\n", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if(1 != EVP_DigestUpdate(mdctx, message, message_len)) {
|
||||
xmlXadesInternalError("EVP_DigestUpdate().\n", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if(1 != EVP_DigestFinal_ex(mdctx, digest, &digest_len)) {
|
||||
xmlXadesInternalError("EVP_DigestFinal_ex().\n", NULL);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
EVP_MD_CTX_free(mdctx);
|
||||
return(xmlSecBase64Encode(digest, digest_len, 0));
|
||||
}
|
||||
|
@ -59,11 +59,10 @@ typedef enum _XADES_DIGEST_METHOD{
|
||||
XADES_DIGEST_SHA256
|
||||
} XADES_DIGEST_METHOD;
|
||||
|
||||
typedef int (*xmlXadesPolicyIdentifierContentCallback)(const xmlChar *policyId, xmlChar *content, xmlXadesSize *content_length);
|
||||
typedef int(*xmlXadesPolicyIdentifierContentCallback)(const xmlChar *policyId, xmlSecBuffer *);
|
||||
|
||||
typedef struct _xmlXadesPolicyIdentifierCtx *xmlXadesPolicyIdentifierCtxPtr;
|
||||
typedef struct _xmlXadesPolicyIdentifierCtx xmlXadesPolicyIdentifierCtx, *xmlXadesPolicyIdentifierCtxPtr;
|
||||
struct _xmlXadesPolicyIdentifierCtx {
|
||||
XADES_DIGEST_METHOD digestMethod;
|
||||
xmlXadesPolicyIdentifierContentCallback contentCallback;
|
||||
};
|
||||
|
||||
@ -116,6 +115,9 @@ xmlXadesTmplAddSigPolicyHash(xmlNodePtr parentNode, xmlSecTransformId digestMeth
|
||||
xmlNodePtr
|
||||
xmlXadesTmplAddSignerRole(xmlNodePtr signedSignaturePropertiesNode, const xmlChar* role);
|
||||
|
||||
xmlNodePtr
|
||||
xmlXadesTmplAddDigest(xmlNodePtr parentNode, const xmlChar *digestMethod, const xmlChar *digestValue);
|
||||
|
||||
xmlNodePtr
|
||||
xmlXadesTmplAddIssuerSerial(xmlNodePtr certNode, const xmlChar *issuerName, const xmlChar *issuerNumber);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user