facho-signer: se adicionan digest de certificados
FossilOrigin-Name: 86d510a9c5ea4bf2ec5e297d9fb9fbc04b99761bd62f364b4d32dc749a1cf3bc
This commit is contained in:
		
							
								
								
									
										422
									
								
								experimental/facho-signer/xades/templates.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										422
									
								
								experimental/facho-signer/xades/templates.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,422 @@
 | 
			
		||||
#include "xades.h"
 | 
			
		||||
 | 
			
		||||
#include <xmlsec/templates.h>
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#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;
 | 
			
		||||
  char* cpath = strdup((char *)path);
 | 
			
		||||
  char* savePtr;
 | 
			
		||||
  xmlNodePtr curNode = NULL;
 | 
			
		||||
  xmlNodePtr parentNode = startNode;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  curToken = strtok_r(cpath, "/", &savePtr);
 | 
			
		||||
  while(curToken != NULL) {
 | 
			
		||||
    curNode = xmlSecFindChild(parentNode, BAD_CAST curToken, nsPrefix);
 | 
			
		||||
    if (curNode == NULL) {
 | 
			
		||||
      curNode = xmlSecAddChild(parentNode, BAD_CAST curToken, nsPrefix);
 | 
			
		||||
      if (curNode == NULL) {
 | 
			
		||||
        xmlXadesInternalError("xmlSecAddChild(%s)", curToken);
 | 
			
		||||
        return(NULL);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    parentNode = curNode;
 | 
			
		||||
 | 
			
		||||
    curToken = strtok_r(NULL, "/", &savePtr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  free(cpath);
 | 
			
		||||
  return(curNode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplQualifyingPropertiesCreate(xmlDocPtr doc, xmlNodePtr signatureNode, const xmlChar *id) {
 | 
			
		||||
  xmlNodePtr objectNode;
 | 
			
		||||
  xmlNodePtr qualifyingPropertiesNode;
 | 
			
		||||
 | 
			
		||||
  xmlNewGlobalNs(doc, xmlXadesDSigNs, BAD_CAST "xades");
 | 
			
		||||
 | 
			
		||||
  objectNode = xmlSecTmplSignatureAddObject(signatureNode, NULL, NULL, NULL);
 | 
			
		||||
  if (objectNode == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecTmplSignatureAddObject(signatureNode)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  qualifyingPropertiesNode = xmlSecAddChild(objectNode, xmlXadesNodeQualifyingProperties, xmlXadesDSigNs);
 | 
			
		||||
  if (qualifyingPropertiesNode == NULL) {
 | 
			
		||||
    xmlXadesXmlError2("xmlNewDocNode", NULL, "node=%s", xmlXadesErrorsSafeString(xmlXadesNodeQualifyingProperties));
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (id != NULL) {
 | 
			
		||||
    xmlSetProp(qualifyingPropertiesNode, BAD_CAST "Id", id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(qualifyingPropertiesNode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplQualifyingPropertiesCreateNsPref(xmlDocPtr doc, const xmlChar* id, const xmlChar* nsPrefix) {
 | 
			
		||||
  xmlNodePtr qualifyingPropertiesNode;
 | 
			
		||||
  xmlNsPtr ns;
 | 
			
		||||
 | 
			
		||||
  // crear nodo
 | 
			
		||||
  qualifyingPropertiesNode = xmlNewDocNode(doc, NULL, xmlXadesNodeQualifyingProperties, NULL);
 | 
			
		||||
  if (qualifyingPropertiesNode == NULL) {
 | 
			
		||||
    xmlXadesXmlError2("xmlNewDocNode", NULL, "node=%s", xmlXadesErrorsSafeString(xmlXadesNodeQualifyingProperties));
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // crear namespace y asignar
 | 
			
		||||
  ns = xmlNewNs(qualifyingPropertiesNode, xmlXadesDSigNs, nsPrefix);
 | 
			
		||||
  if (ns == NULL) {
 | 
			
		||||
    xmlXadesXmlError2("xmlNewNs", NULL,
 | 
			
		||||
                   "ns=%s", xmlXadesErrorsSafeString(xmlXadesDSigNs));
 | 
			
		||||
    xmlFreeNode(qualifyingPropertiesNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
  xmlSetNs(qualifyingPropertiesNode, ns);
 | 
			
		||||
 | 
			
		||||
  if (id != NULL) {
 | 
			
		||||
    xmlSetProp(qualifyingPropertiesNode, BAD_CAST "Id", id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
  return (qualifyingPropertiesNode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignedProperties(xmlNodePtr qualifyingPropertiesNode, const xmlChar* id) {
 | 
			
		||||
  xmlNodePtr cur;
 | 
			
		||||
 | 
			
		||||
  xmlXadesAssert2(qualifyingPropertiesNode != NULL, NULL);
 | 
			
		||||
  
 | 
			
		||||
  cur = xmlSecAddChild(qualifyingPropertiesNode, xmlXadesNodeSignedProperties, xmlXadesDSigNs);
 | 
			
		||||
  if (cur == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignedProperties)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (id != NULL) {
 | 
			
		||||
    xmlSetProp(cur, BAD_CAST "Id", id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(cur);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignedSignatureProperties(xmlNodePtr signedPropertiesNode, struct tm* signingTime) {
 | 
			
		||||
  xmlNodePtr cur;
 | 
			
		||||
  xmlNodePtr node;
 | 
			
		||||
 | 
			
		||||
  xmlXadesAssert2(signedPropertiesNode != NULL, NULL);
 | 
			
		||||
  
 | 
			
		||||
  // add SignedSignatureProperties
 | 
			
		||||
  node = xmlSecAddChild(signedPropertiesNode, xmlXadesNodeSignedSignatureProperties, xmlXadesDSigNs);
 | 
			
		||||
  if (node == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignedSignatureProperties)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // add SignigTime
 | 
			
		||||
  cur = xmlSecAddChild(node, xmlXadesNodeSigningTime, xmlXadesDSigNs);
 | 
			
		||||
  if (cur == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigningTime)", NULL);
 | 
			
		||||
    xmlFreeNode(node);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    int ret;
 | 
			
		||||
    char strtime[200];
 | 
			
		||||
 | 
			
		||||
    if (strftime(strtime, sizeof(strtime), "%Y-%m-%dT%T", signingTime) == 0) {
 | 
			
		||||
      xmlXadesInternalError("strftime", NULL);
 | 
			
		||||
      xmlFreeNode(cur);
 | 
			
		||||
      xmlFreeNode(node);
 | 
			
		||||
      return(NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ret = xmlSecNodeEncodeAndSetContent(cur, BAD_CAST strtime);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
      xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
 | 
			
		||||
      xmlFreeNode(cur);
 | 
			
		||||
      xmlFreeNode(node);
 | 
			
		||||
      return(NULL);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSigningCertificate(xmlNodePtr signedSignaturePropertiesNode, xmlSecTransformId digestMethodId) {
 | 
			
		||||
  xmlNodePtr node;
 | 
			
		||||
 | 
			
		||||
  xmlXadesAssert2(signedSignaturePropertiesNode != NULL, NULL);
 | 
			
		||||
  if (xmlSecFindChild(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, xmlXadesDSigNs) != NULL) {
 | 
			
		||||
    xmlXadesNodeAlreadyPresentError(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  node = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSigningCertificate, xmlXadesDSigNs);
 | 
			
		||||
  if (node == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSigningCertificate)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddCert(xmlNodePtr signingCertificateNode) {
 | 
			
		||||
  xmlNodePtr certNode;
 | 
			
		||||
 | 
			
		||||
  xmlXadesAssert2(signingCertificateNode != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  certNode = xmlSecAddChild(signingCertificateNode, xmlXadesNodeCert, xmlXadesDSigNs);
 | 
			
		||||
  if (certNode == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeCert)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(certNode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddCertDigest(xmlNodePtr certNode, const xmlChar *digestMethod, const xmlChar *digestValue) {
 | 
			
		||||
  xmlNodePtr node;
 | 
			
		||||
 | 
			
		||||
  xmlXadesAssert2(certNode != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  node = xmlSecAddChild(certNode, xmlXadesNodeCertDigest, xmlXadesDSigNs);
 | 
			
		||||
  if ( node == NULL ) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeCertDigest)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ( xmlXadesTmplAddDigest(node, digestMethod, digestValue) == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlXadesTmplAddDigest(node, digestMethodId)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(certNode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignaturePolicyIdentifier(xmlNodePtr signedSignaturePropertiesNode) {
 | 
			
		||||
  xmlNodePtr cur;
 | 
			
		||||
  
 | 
			
		||||
  xmlXadesAssert2(signedSignaturePropertiesNode != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  cur = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSignaturePolicyIdentifier, xmlXadesDSigNs);
 | 
			
		||||
  if (cur == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSignaturePolicyIdentifier)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(cur);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignaturePolicyId(xmlNodePtr signaturePolicyIdentifierNode) {
 | 
			
		||||
  xmlNodePtr cur;
 | 
			
		||||
  
 | 
			
		||||
  xmlXadesAssert2(signaturePolicyIdentifierNode != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  cur = xmlSecAddChild(signaturePolicyIdentifierNode, xmlXadesNodeSignaturePolicyId, xmlXadesDSigNs);
 | 
			
		||||
  if (cur == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlsecAddChild(xmlXadesNodeSignaturePolicyId)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return(cur);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSigPolicyId(xmlNodePtr signaturePolicyId, const xmlChar* identifier, const xmlChar *description, xmlSecTransformId policyDigestMethodId) {
 | 
			
		||||
  xmlNodePtr sigPolicyIdNode;
 | 
			
		||||
  xmlNodePtr node;
 | 
			
		||||
  int ret;
 | 
			
		||||
  
 | 
			
		||||
  sigPolicyIdNode = xmlSecAddChild(signaturePolicyId, xmlXadesNodeSigPolicyId, xmlXadesDSigNs);
 | 
			
		||||
  if (sigPolicyIdNode == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigPolicyId)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  node = xmlSecAddChild(sigPolicyIdNode, xmlXadesNodeIdentifier, xmlXadesDSigNs);
 | 
			
		||||
  if (node == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeIdentifier)", NULL);
 | 
			
		||||
    xmlFreeNode(sigPolicyIdNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ret = xmlSecNodeEncodeAndSetContent(node, identifier);
 | 
			
		||||
  if (ret < 0) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
 | 
			
		||||
    xmlFreeNode(sigPolicyIdNode);
 | 
			
		||||
    xmlFreeNode(node);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  node = xmlSecAddChild(sigPolicyIdNode, xmlXadesNodeDescription, xmlXadesDSigNs);
 | 
			
		||||
  if (node == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeDescription)", NULL);
 | 
			
		||||
    xmlFreeNode(sigPolicyIdNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ret = xmlSecNodeEncodeAndSetContent(node, identifier);
 | 
			
		||||
  if (ret < 0) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
 | 
			
		||||
    xmlFreeNode(sigPolicyIdNode);
 | 
			
		||||
    xmlFreeNode(node);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(sigPolicyIdNode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSigPolicyHash(xmlNodePtr parentNode) {
 | 
			
		||||
  xmlNodePtr node;
 | 
			
		||||
  xmlXadesAssert2(parentNode != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  //add policyHash
 | 
			
		||||
  node = xmlSecAddChild(parentNode, xmlXadesNodeSigPolicyHash, xmlXadesDSigNs);
 | 
			
		||||
  if (node == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSigPolicyHash)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MACHETE(bit4bit) como usar SecTransform para almacenar el digest
 | 
			
		||||
static 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);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  node = xmlSecAddChild(parentNode, xmlSecNodeDigestValue, xmlSecDSigNs);
 | 
			
		||||
  if (node == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlSecNodeDigestValue)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (xmlSecNodeEncodeAndSetContent(node, digestValue) < 0) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return parentNode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignerRole(xmlNodePtr signedSignaturePropertiesNode, const xmlChar* role) {
 | 
			
		||||
  xmlNodePtr signerRoleNode;
 | 
			
		||||
  xmlNodePtr claimedRolesNode;
 | 
			
		||||
  xmlNodePtr claimedRoleNode;
 | 
			
		||||
  int ret;
 | 
			
		||||
 | 
			
		||||
  signerRoleNode = xmlSecAddChild(signedSignaturePropertiesNode, xmlXadesNodeSignerRole, xmlXadesDSigNs);
 | 
			
		||||
  if (signerRoleNode == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeSignerRole)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  claimedRolesNode = xmlSecAddChild(signerRoleNode, xmlXadesNodeClaimedRoles, xmlXadesDSigNs);
 | 
			
		||||
  if (claimedRolesNode == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeClaimedRoles)", NULL);
 | 
			
		||||
    xmlUnlinkNode(signerRoleNode);
 | 
			
		||||
    xmlFreeNode(signerRoleNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  claimedRoleNode = xmlSecAddChild(claimedRolesNode, xmlXadesNodeClaimedRole, xmlXadesDSigNs);
 | 
			
		||||
  if (claimedRoleNode == NULL) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeClaimedRole)", NULL);
 | 
			
		||||
    xmlUnlinkNode(signerRoleNode);
 | 
			
		||||
    xmlFreeNode(signerRoleNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ret = xmlSecNodeEncodeAndSetContent(claimedRoleNode, role);
 | 
			
		||||
  if (ret < 0) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
 | 
			
		||||
    xmlUnlinkNode(signerRoleNode);
 | 
			
		||||
    xmlFreeNode(signerRoleNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(signerRoleNode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddIssuerSerial(xmlNodePtr certNode, const xmlChar *issuerName, const xmlChar *issuerNumber) {
 | 
			
		||||
  xmlNodePtr issuerSerialNode;
 | 
			
		||||
  xmlNodePtr node;
 | 
			
		||||
 | 
			
		||||
  xmlXadesAssert2(certNode != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  issuerSerialNode = xmlSecAddChild(certNode, xmlXadesNodeIssuerSerial, xmlXadesDSigNs);
 | 
			
		||||
  if ( issuerSerialNode == NULL ) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(certNode, xmlXadesIssuerSerial)", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  node = xmlSecAddChild(issuerSerialNode, xmlXadesNodeX509IssuerName, xmlSecDSigNs);
 | 
			
		||||
  if ( node == NULL ) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeX509IssuerName)", NULL);
 | 
			
		||||
    xmlFreeNode(issuerSerialNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (xmlSecNodeEncodeAndSetContent(node, issuerName) < 0) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
 | 
			
		||||
    xmlUnlinkNode(issuerSerialNode);
 | 
			
		||||
    xmlFreeNode(issuerSerialNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  node = xmlSecAddChild(issuerSerialNode, xmlXadesNodeX509IssuerNumber, xmlSecDSigNs);
 | 
			
		||||
  if ( node == NULL ) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecAddChild(xmlXadesNodeX509IssuerNumber)", NULL);
 | 
			
		||||
    xmlFreeNode(issuerSerialNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (xmlSecNodeEncodeAndSetContent(node, issuerNumber) < 0) {
 | 
			
		||||
    xmlXadesInternalError("xmlSecNodeEncodeAndSetContent", NULL);
 | 
			
		||||
    xmlUnlinkNode(issuerSerialNode);
 | 
			
		||||
    xmlFreeNode(issuerSerialNode);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return(issuerSerialNode);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,58 +1,159 @@
 | 
			
		||||
#include "xades.h"
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
xmlFachoAppSign(xmlDocPtr doc,
 | 
			
		||||
                xmlSecTransformId hashMethodId) {
 | 
			
		||||
  xmlXadesAssert2(doc != NULL, NULL);
 | 
			
		||||
  xmlNodePtr cur;
 | 
			
		||||
  xmlNodePtr signedSignaturePropertiesNode;
 | 
			
		||||
  xmlNodePtr signaturePolicyIdentifierNode;
 | 
			
		||||
  xmlNodePtr signaturePolicyIdNode;
 | 
			
		||||
  xmlChar* signedPropertiesId = BAD_CAST "ref1-signedprops";
 | 
			
		||||
  time_t now = time(NULL);
 | 
			
		||||
  
 | 
			
		||||
  cur = xmlXadesTmplQualifyingPropertiesCreateNsPref(doc, "qualify-ref1", BAD_CAST "ds");
 | 
			
		||||
  if (cur == NULL) {
 | 
			
		||||
    return(-1);
 | 
			
		||||
#include <libxml/xpath.h>
 | 
			
		||||
#include <libxml/xpathInternals.h>
 | 
			
		||||
#include <openssl/x509.h>
 | 
			
		||||
#include <openssl/x509v3.h>
 | 
			
		||||
#include <openssl/bio.h>
 | 
			
		||||
#include <openssl/asn1.h>
 | 
			
		||||
#include <openssl/bn.h>
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
 | 
			
		||||
static xmlNodePtr
 | 
			
		||||
xmlXadesXPathFirstElement(xmlDocPtr doc, const xmlChar *xpath) {
 | 
			
		||||
  xmlXPathContextPtr xpathCtx;
 | 
			
		||||
  xmlXPathObjectPtr xpathResult;
 | 
			
		||||
  xmlNodePtr node;
 | 
			
		||||
 | 
			
		||||
  // obtener QualifyingProteries
 | 
			
		||||
 | 
			
		||||
  xpathCtx = xmlXPathNewContext(doc);
 | 
			
		||||
  /* register namespaces */
 | 
			
		||||
  // TOMADO DE: xmlsec1/src/xpath.c
 | 
			
		||||
  for(xmlNsPtr ns = xmlDocGetRootElement(doc)->nsDef; ns != NULL; ns = ns->next) {
 | 
			
		||||
    /* check that we have no other namespace with same prefix already */
 | 
			
		||||
    if((ns->prefix != NULL) && (xmlXPathNsLookup(xpathCtx, ns->prefix) == NULL)){
 | 
			
		||||
      int ret = xmlXPathRegisterNs(xpathCtx, ns->prefix, ns->href);
 | 
			
		||||
      if(ret != 0) {
 | 
			
		||||
        xmlXadesXmlError2("xmlXPathRegisterNs", NULL,
 | 
			
		||||
                          "prefix=%s", xmlSecErrorsSafeString(ns->prefix));
 | 
			
		||||
        return(NULL);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  cur = xmlXadesTmplAddSignedProperties(cur, signedPropertiesId);
 | 
			
		||||
  if (cur == NULL) {
 | 
			
		||||
    return(-1);
 | 
			
		||||
 | 
			
		||||
  xpathResult = xmlXPathEvalExpression(BAD_CAST "//ds:Object/xades:QualifyingProperties[1]", xpathCtx);
 | 
			
		||||
  if ( xmlXPathNodeSetIsEmpty( xpathResult->nodesetval ) ) {
 | 
			
		||||
    xmlXadesInternalError("can't find ds:Signature/ds:Object/xades:QualifyingProperties \n", NULL);
 | 
			
		||||
    xmlXPathFreeObject(xpathResult);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  signedSignaturePropertiesNode = xmlXadesTmplAddSignedSignatureProperties(cur,  now);
 | 
			
		||||
  if (signedSignaturePropertiesNode == NULL) {
 | 
			
		||||
    return(-1);
 | 
			
		||||
  // obtener puntero a nodo
 | 
			
		||||
  node = xpathResult->nodesetval->nodeTab[0];
 | 
			
		||||
  if ( node->type != XML_ELEMENT_NODE ) {
 | 
			
		||||
    xmlXadesInternalError("expected element QualifyingProperties\n", NULL);
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // addSigningCertificate
 | 
			
		||||
 | 
			
		||||
  // addSignaturePolicyIdentifier
 | 
			
		||||
 | 
			
		||||
  signaturePolicyIdNode = xmlXadesAddChildRecursiveNs(signedSignaturePropertiesNode, BAD_CAST "SignaturePolicyIdentifier/SignaturePolicyId", xmlXadesDSigNs)
 | 
			
		||||
  if (signaturePolicyIdNode == NULL) {
 | 
			
		||||
    return(-1);
 | 
			
		||||
  }
 | 
			
		||||
  cur = xmlXadesTmplAddSigPolicyId(signaturePolicyIdNode, identifier, description, hashMethodId);
 | 
			
		||||
  if (cur == NULL) {
 | 
			
		||||
    return(-1);
 | 
			
		||||
  }
 | 
			
		||||
  // SignaturePolicyIdentifier/SignaturePolicyId/SigPolicyHash
 | 
			
		||||
  cur = xmlXadesTmplAddSigPolicyHash(signaturePolicyIdNode);
 | 
			
		||||
  if (cur == NULL) {
 | 
			
		||||
    return(-1);
 | 
			
		||||
  }
 | 
			
		||||
  cur = xmlXadesTmplAddDigest(cur, hashMethodId);
 | 
			
		||||
  if (cur == NULL) {
 | 
			
		||||
    return(-1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // addSignerRole
 | 
			
		||||
  xmlXadesTmplAddSignerRole(signedSignaturePropertiesNode, BAD_CAST "supplier");
 | 
			
		||||
  
 | 
			
		||||
  cur = xmlSecTmplSignatureAddReference(xmlDocGetRootElement(doc),
 | 
			
		||||
                                        hashMethodId,
 | 
			
		||||
                                        signedPropertiesId,
 | 
			
		||||
                                        NULL, NULL);
 | 
			
		||||
  return(node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
xmlXadesDSigCtxPtr
 | 
			
		||||
xmlXadesDSigCtxCreate(xmlSecDSigCtxPtr dsigCtx) {
 | 
			
		||||
  xmlXadesDSigCtxPtr ctx = NULL;
 | 
			
		||||
 | 
			
		||||
  ctx = malloc(sizeof(xmlXadesDSigCtx));
 | 
			
		||||
  if ( ctx == NULL ) {
 | 
			
		||||
    return(NULL);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ctx->dsigCtx = dsigCtx;
 | 
			
		||||
  return ctx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
xmlXadesDSigCtxSign(xmlXadesDSigCtxPtr ctx, xmlNodePtr signNode) {
 | 
			
		||||
  xmlNodePtr signingCertificateNode = NULL;
 | 
			
		||||
  xmlSecKeyDataPtr keyDataX509;
 | 
			
		||||
  xmlSecSize certsSize;
 | 
			
		||||
 | 
			
		||||
  signingCertificateNode = xmlXadesXPathFirstElement(signNode->doc, BAD_CAST "//ds:Object/xades:QualifyingProperties//xades:SigningCertificate[1]");
 | 
			
		||||
  if ( signingCertificateNode == NULL ) {
 | 
			
		||||
    return(-1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  keyDataX509 = xmlSecKeyEnsureData(ctx->dsigCtx->signKey, xmlSecKeyDataX509Id);
 | 
			
		||||
  if ( keyDataX509 == NULL ) {
 | 
			
		||||
    xmlXadesInternalError("failed to get X509.\n", NULL);
 | 
			
		||||
    return(-1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  certsSize = xmlSecOpenSSLKeyDataX509GetCertsSize(keyDataX509);
 | 
			
		||||
  for (xmlSecSize i = 0; i < certsSize; i++) {
 | 
			
		||||
    // calculamos el digest del certificado
 | 
			
		||||
    unsigned char md[EVP_MAX_MD_SIZE];
 | 
			
		||||
    unsigned int md_n;
 | 
			
		||||
    // TODO(bit4bit) podemos obtener el digest de openssl por medio de la transformacion? o se puede usar la transformacion para generar el digest?
 | 
			
		||||
    xmlChar *digestMethod = (xmlChar *)xmlSecTransformSha256Id->href;
 | 
			
		||||
    const EVP_MD *digest = EVP_sha256();
 | 
			
		||||
 | 
			
		||||
    X509 *cert = xmlSecOpenSSLKeyDataX509GetCert(keyDataX509, i);
 | 
			
		||||
    if ( cert == NULL ) {
 | 
			
		||||
      xmlXadesInternalError("openssl: failed to get X509 cert.\n", NULL);
 | 
			
		||||
      return(-1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    X509_digest(cert, digest, md, &md_n);
 | 
			
		||||
    xmlChar *digestValue = xmlSecBase64Encode(md, md_n, 0);
 | 
			
		||||
 | 
			
		||||
    xmlNodePtr certNode = xmlXadesTmplAddCert(signingCertificateNode);
 | 
			
		||||
    if ( certNode == NULL ) {
 | 
			
		||||
      xmlXadesInternalError("xmlXadesTmplAddCert(signingCertificateNode)\n", NULL);
 | 
			
		||||
      return(-1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // adicionamos digest 
 | 
			
		||||
    xmlXadesTmplAddCertDigest(certNode,
 | 
			
		||||
                              digestMethod,
 | 
			
		||||
                              digestValue);
 | 
			
		||||
 | 
			
		||||
    char *issuerName = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
 | 
			
		||||
 | 
			
		||||
    /* TODO(bit4bit) formatear?
 | 
			
		||||
    char *issuerNamePtr = issuerName;
 | 
			
		||||
    
 | 
			
		||||
    for(issuerNamePtr = strchr(issuerNamePtr, '/'); issuerNamePtr != NULL; issuerNamePtr = strchr(issuerNamePtr, '/')) {
 | 
			
		||||
      if (issuerNamePtr == issuerName) {
 | 
			
		||||
        issuerName += 1;
 | 
			
		||||
      } else {
 | 
			
		||||
        *issuerNamePtr = ',';
 | 
			
		||||
      }
 | 
			
		||||
      }*/
 | 
			
		||||
 | 
			
		||||
    ASN1_INTEGER *serial = X509_get_serialNumber(cert);
 | 
			
		||||
    BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL);
 | 
			
		||||
    if ( bn == NULL ) {
 | 
			
		||||
      xmlXadesInternalError("unable to convert ASN1_INTEGER_to_BN to BN\n", NULL);
 | 
			
		||||
      return(-1);
 | 
			
		||||
    }
 | 
			
		||||
    char *issuerNumber = BN_bn2dec(bn);
 | 
			
		||||
    if ( issuerNumber == NULL ) {
 | 
			
		||||
      xmlXadesInternalError("unable to convert BN to decimal string\n", NULL);
 | 
			
		||||
      return(-1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (xmlXadesTmplAddIssuerSerial(certNode, BAD_CAST issuerName, BAD_CAST issuerNumber) == NULL) {
 | 
			
		||||
      xmlXadesInternalError("xmlXadesTmplAddIssuerSerial", NULL);
 | 
			
		||||
      return(-1);
 | 
			
		||||
    }
 | 
			
		||||
    BN_free(bn);
 | 
			
		||||
    OPENSSL_free(issuerNumber);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return xmlSecDSigCtxSign(ctx->dsigCtx, signNode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
xmlXadesDSigCtxDestroy(xmlXadesDSigCtxPtr ctx) {
 | 
			
		||||
  if ( ctx == NULL ) {
 | 
			
		||||
    return(-1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  free(ctx);
 | 
			
		||||
  return(0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,45 @@
 | 
			
		||||
#ifndef XADES_H
 | 
			
		||||
#define XADES_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <libxml/tree.h>
 | 
			
		||||
 | 
			
		||||
#include <xmlsec/xmltree.h>
 | 
			
		||||
#include <xmlsec/transforms.h>
 | 
			
		||||
#include <xmlsec/app.h>
 | 
			
		||||
#include <xmlsec/xmldsig.h>
 | 
			
		||||
#include <xmlsec/openssl/x509.h>
 | 
			
		||||
#include <xmlsec/base64.h>
 | 
			
		||||
 | 
			
		||||
#include "xmlsec1/errors_helpers.h"
 | 
			
		||||
 | 
			
		||||
#define xmlXadesAssert2(p, ret) \
 | 
			
		||||
  xmlSecAssert2(p, ret)
 | 
			
		||||
 | 
			
		||||
#define xmlXadesNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject) \
 | 
			
		||||
  xmlSecNodeNotFoundError(errorFunction, startNode, targetNodeName, errorObject)
 | 
			
		||||
 | 
			
		||||
#define xmlXadesXmlError2(errorFunction, errorObject, msg, param) \
 | 
			
		||||
  xmlSecXmlError2(errorFunction, errorObject, msg, param)
 | 
			
		||||
 | 
			
		||||
#define xmlXadesErrorsSafeString(msg) \
 | 
			
		||||
  xmlSecErrorsSafeString(msg)
 | 
			
		||||
 | 
			
		||||
#define xmlXadesInternalError(errorFunction, errorObject) \
 | 
			
		||||
  xmlSecInternalError(errorFunction, errorObject)
 | 
			
		||||
 | 
			
		||||
#define xmlXadesNodeAlreadyPresentError(parent, nodeName, errObject) \
 | 
			
		||||
  xmlSecNodeAlreadyPresentError(parent, nodeName, errObject)
 | 
			
		||||
 | 
			
		||||
static const xmlChar xmlXadesNodeQualifyingProperties[] = "QualifyingProperties";
 | 
			
		||||
static const xmlChar xmlXadesNodeSignedProperties[] = "SignedProperties";
 | 
			
		||||
 | 
			
		||||
static const xmlChar xmlXadesNodeSignedSignatureProperties[] = "SignedSignatureProperties";
 | 
			
		||||
static const xmlChar xmlXadesNodeSigningTime[] = "SigningTime";
 | 
			
		||||
static const xmlChar xmlXadesNodeSigningCertificate[] = "SigningCertificate";
 | 
			
		||||
static const xmlChar xmlXadesNodeCertificate[] = "Cert";
 | 
			
		||||
static const xmlChar xmlXadesNodeCert[] = "Cert";
 | 
			
		||||
static const xmlChar xmlXadesNodeCertDigest[] = "CertDigest";
 | 
			
		||||
static const xmlChar xmlXadesNodeSignaturePolicyIdentifier[] = "SignaturePolicyIdentifier";
 | 
			
		||||
static const xmlChar xmlXadesNodeSignaturePolicyId[] = "SignaturePolicyId";
 | 
			
		||||
static const xmlChar xmlXadesNodeSigPolicyId[] = "SignaturePolicyId";
 | 
			
		||||
@@ -25,21 +50,59 @@ static const xmlChar xmlXadesNodeSigPolicyHash[] = "SigPolicyHash";
 | 
			
		||||
static const xmlChar xmlXadesNodeSignerRole[] = "SignerRole";
 | 
			
		||||
static const xmlChar xmlXadesNodeClaimedRoles[] = "ClaimedRoles";
 | 
			
		||||
static const xmlChar xmlXadesNodeClaimedRole[] = "ClaimedRole";
 | 
			
		||||
 | 
			
		||||
static const xmlChar xmlXadesNodeIssuerSerial[] = "IssuerSerial";
 | 
			
		||||
static const xmlChar xmlXadesNodeX509IssuerName[] = "X509IssuerName";
 | 
			
		||||
static const xmlChar xmlXadesNodeX509IssuerNumber[] = "X509IssuerNumber";
 | 
			
		||||
  
 | 
			
		||||
static const xmlChar xmlXadesDSigNs[] = "http://uri.etsi.org/01903/v1.3.2#";
 | 
			
		||||
 | 
			
		||||
typedef struct _xmlXadesDSigCtx xmlXadesDSigCtx, *xmlXadesDSigCtxPtr;
 | 
			
		||||
struct _xmlXadesDSigCtx {
 | 
			
		||||
  xmlSecDSigCtxPtr dsigCtx;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
xmlXadesDSigCtxPtr
 | 
			
		||||
xmlXadesDSigCtxCreate(xmlSecDSigCtxPtr dsigCtx);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
xmlXadesDSigCtxSign(xmlXadesDSigCtxPtr ctx, xmlNodePtr signNode);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
xmlXadesDSigCtxDestroy(xmlXadesDSigCtxPtr ctx);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplQualifyingPropertiesCreate(xmlDocPtr doc, xmlNodePtr signatureNode, const xmlChar *id);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplQualifyingPropertiesCreateNsPref(xmlDocPtr doc, const xmlChar* id, const xmlChar* nsPrefix);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignedProperties(xmlNodePtr qualifyingPropertiesNode, const xmlChar* id);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSigningCertificate(xmlNodePtr parentNode);
 | 
			
		||||
xmlXadesTmplAddSigningCertificate(xmlNodePtr parentNode, xmlSecTransformId digestMethodId);
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddCert(xmlNodePtr signingCertificateNode);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddCertDigest(xmlNodePtr signingCertificateNode, const xmlChar *digestMethod, const xmlChar *digestValue);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignaturePolicyIdentifier(xmlNodePtr signedSignaturePropertiesNode);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignerRole(xmlNodePtr signedSignaturePropertiesNode, const xmlChar* role);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignaturePolicyIdentifierSignaturePolicyId(xmlNodePtr signedSignaturePropertiesNode);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddSignedSignatureProperties(xmlNodePtr parentNode, struct tm* signingTime);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesTmplAddIssuerSerial(xmlNodePtr certNode, const xmlChar *issuerName, const xmlChar *issuerNumber);
 | 
			
		||||
 | 
			
		||||
xmlNodePtr
 | 
			
		||||
xmlXadesAddChildRecursiveNs(xmlNodePtr parentNode, const xmlChar* path, const xmlChar* nsPrefix);
 | 
			
		||||
#endif //XADES_H
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user