facho-signer: se adiciona policy Hash usando como contenido archivo pdf

FossilOrigin-Name: fcbbfe001fcbd8131064b5feee76f838e4c345a99eea26c5d0592b0277fbff17
This commit is contained in:
bit4bit 2021-12-15 01:16:03 +00:00
parent 012615f984
commit 7181c004cb
5 changed files with 157 additions and 41 deletions

View File

@ -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));
}

File diff suppressed because one or more lines are too long

View File

@ -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,12 +305,13 @@ 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);
if ( digestMethod != NULL ) {
node = xmlSecAddChild(parentNode, xmlSecNodeDigestMethod, xmlSecDSigNs);
if (node == NULL) {
xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestMethod)", NULL);
@ -326,7 +324,9 @@ xmlXadesTmplAddDigest(xmlNodePtr parentNode, const xmlChar *digestMethod, const
xmlFreeNode(node);
return(NULL);
}
}
if ( digestValue != NULL ) {
node = xmlSecAddChild(parentNode, xmlSecNodeDigestValue, xmlSecDSigNs);
if (node == NULL) {
xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestValue)", NULL);
@ -337,6 +337,7 @@ xmlXadesTmplAddDigest(xmlNodePtr parentNode, const xmlChar *digestMethod, const
xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
return(NULL);
}
}
return parentNode;
}

View File

@ -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);
}
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);
printf("IDENTIFIER %s\n", identifier);
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));
}

View File

@ -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);