summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcc1.yim <cc1.yim@samsung.com>2013-07-16 03:02:03 (GMT)
committerAnas Nashif <anas.nashif@intel.com>2013-09-23 08:27:23 (GMT)
commitc8b0fdde7214fc7879563ea7dd69152894d268ed (patch)
tree7ed247694d7f062e08b12052f7f71abf04e264e5
parent54bb2f3d916df410e0576638822b7693d8b4cf9a (diff)
downloadxmlsec1-c8b0fdde7214fc7879563ea7dd69152894d268ed.zip
xmlsec1-c8b0fdde7214fc7879563ea7dd69152894d268ed.tar.gz
xmlsec1-c8b0fdde7214fc7879563ea7dd69152894d268ed.tar.bz2
modify partial hash for RDSrefs/changes/79/10179/1
Change-Id: Ibd000b86426709d14298f8a1a33b300785c40c2e Signed-off-by: cc1.yim <cc1.yim@samsung.com> Signed-off-by: Anas Nashif <anas.nashif@intel.com>
-rw-r--r--include/xmlsec/xmldsig.h5
-rw-r--r--src/xmldsig.c725
2 files changed, 719 insertions, 11 deletions
diff --git a/include/xmlsec/xmldsig.h b/include/xmlsec/xmldsig.h
index 3cd311e..8ee78a4 100644
--- a/include/xmlsec/xmldsig.h
+++ b/include/xmlsec/xmldsig.h
@@ -257,6 +257,11 @@ XMLSEC_EXPORT void xmlSecDSigReferenceCtxDebugDump (xmlSecDSigRefer
XMLSEC_EXPORT void xmlSecDSigReferenceCtxDebugXmlDump(xmlSecDSigReferenceCtxPtr dsigRefCtx,
FILE* output);
+XMLSEC_EXPORT int xmlSecDSigCtxVerifyEx(xmlSecDSigCtxPtr dsigCtx,
+ xmlNodePtr node, int noHash, void* pList);
+
+
+
/**************************************************************************
*
* xmlSecDSigReferenceCtxListKlass
diff --git a/src/xmldsig.c b/src/xmldsig.c
index 800aa25..8977a95 100644
--- a/src/xmldsig.c
+++ b/src/xmldsig.c
@@ -36,19 +36,30 @@
* xmlSecDSigCtx
*
*************************************************************************/
-static int xmlSecDSigCtxProcessSignatureNode (xmlSecDSigCtxPtr dsigCtx,
- xmlNodePtr node);
-static int xmlSecDSigCtxProcessSignedInfoNode (xmlSecDSigCtxPtr dsigCtx,
- xmlNodePtr node);
-static int xmlSecDSigCtxProcessKeyInfoNode (xmlSecDSigCtxPtr dsigCtx,
- xmlNodePtr node);
-static int xmlSecDSigCtxProcessObjectNode (xmlSecDSigCtxPtr dsigCtx,
- xmlNodePtr node);
-static int xmlSecDSigCtxProcessManifestNode (xmlSecDSigCtxPtr dsigCtx,
- xmlNodePtr node);
+static int xmlSecDSigCtxProcessSignatureNode (xmlSecDSigCtxPtr dsigCtx,
+ xmlNodePtr node);
+static int xmlSecDSigCtxProcessSignedInfoNode (xmlSecDSigCtxPtr dsigCtx,
+ xmlNodePtr node);
+static int xmlSecDSigCtxProcessKeyInfoNode (xmlSecDSigCtxPtr dsigCtx,
+ xmlNodePtr node);
+static int xmlSecDSigCtxProcessObjectNode (xmlSecDSigCtxPtr dsigCtx,
+ xmlNodePtr node);
+static int xmlSecDSigCtxProcessManifestNode (xmlSecDSigCtxPtr dsigCtx,
+ xmlNodePtr node);
+static int xmlSecDSigCtxProcessSignatureNodeEx (xmlSecDSigCtxPtr dsigCtx,
+ xmlNodePtr node, int noHash, void* pList);
+static int xmlSecDSigCtxProcessSignedInfoNodeEx (xmlSecDSigCtxPtr dsigCtx,
+ xmlNodePtr node, int noHash, void* pList);
+static int xmlSecDSigReferenceCtxProcessNodeEx (xmlSecDSigReferenceCtxPtr dsigRefCtx,
+ xmlNodePtr node, int noHash, void* pList);
+
/* The ID attribute in XMLDSig is 'Id' */
-static const xmlChar* xmlSecDSigIds[] = { xmlSecAttrId, NULL };
+static const xmlChar* xmlSecDSigIds[] = { xmlSecAttrId, NULL };
+
+
+#define _start //xmlSecError(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_MAX_NUMBER," >> start ");
+#define _end //xmlSecError(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_MAX_NUMBER," >> end ");
static char logMsg[1024];
/**
@@ -1770,6 +1781,698 @@ xmlSecDSigReferenceCtxDebugXmlDump(xmlSecDSigReferenceCtxPtr dsigRefCtx, FILE* o
}
+
+int
+xmlSecDSigCtxVerifyEx(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node, int noHash, void* pList) {
+ int ret;
+ int len = 0;
+
+ if(noHash == 1)
+ _start
+
+ xmlSecAssert2(dsigCtx != NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(node->doc != NULL, -1);
+
+ /* add ids for Signature nodes */
+ dsigCtx->operation = xmlSecTransformOperationVerify;
+ dsigCtx->status = xmlSecDSigStatusUnknown;
+ xmlSecAddIDs(node->doc, node, xmlSecDSigIds);
+
+ /* read siganture info */
+ ret = xmlSecDSigCtxProcessSignatureNodeEx(dsigCtx, node, noHash, pList);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecDSigCtxProcessSignatureNodeEx",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+
+ return(-1);
+ }
+ xmlSecAssert2(dsigCtx->signMethod != NULL, -1);
+ xmlSecAssert2(dsigCtx->signValueNode != NULL, -1);
+
+ /* references processing might change the status */
+ if(dsigCtx->status != xmlSecDSigStatusUnknown) {
+ return(0);
+ }
+
+ /* verify SignatureValue node content */
+ ret = xmlSecTransformVerifyNodeContent(dsigCtx->signMethod, dsigCtx->signValueNode,
+ &(dsigCtx->transformCtx));
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformVerifyNodeContent",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+
+ return(-1);
+ }
+
+ /* set status and we are done */
+ if(dsigCtx->signMethod->status == xmlSecTransformStatusOk) {
+ dsigCtx->status = xmlSecDSigStatusSucceeded;
+ } else {
+ dsigCtx->status = xmlSecDSigStatusInvalid;
+ }
+ _end
+ return(0);
+}
+
+int
+xmlSecDSigCtxProcessSignatureNodeEx (xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node, int noHash, void* pList) {
+ xmlSecTransformDataType firstType;
+ xmlNodePtr signedInfoNode = NULL;
+ xmlNodePtr keyInfoNode = NULL;
+ xmlNodePtr cur;
+ int ret;
+
+ _start
+ xmlSecAssert2(dsigCtx != NULL, -1);
+ xmlSecAssert2((dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify), -1);
+ xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1);
+ xmlSecAssert2(dsigCtx->signValueNode == NULL, -1);
+ xmlSecAssert2(dsigCtx->signMethod == NULL, -1);
+ xmlSecAssert2(dsigCtx->c14nMethod == NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ if(!xmlSecCheckNodeName(node, xmlSecNodeSignature, xmlSecDSigNs)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(node)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "expected=%s",
+ xmlSecErrorsSafeString(xmlSecNodeSignature));
+ return(-1);
+ }
+
+ /* read node data */
+ xmlSecAssert2(dsigCtx->id == NULL, -1);
+ dsigCtx->id = xmlGetProp(node, xmlSecAttrId);
+
+ /* first node is required SignedInfo */
+ cur = xmlSecGetNextElementNode(node->children);
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeSignedInfo, xmlSecDSigNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "expected=%s",
+ xmlSecErrorsSafeString(xmlSecNodeSignedInfo));
+ return(-1);
+ }
+ signedInfoNode = cur;
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* next node is required SignatureValue */
+ if((cur == NULL) || (!xmlSecCheckNodeName(cur, xmlSecNodeSignatureValue, xmlSecDSigNs))) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "expected=%s",
+ xmlSecErrorsSafeString(xmlSecNodeSignatureValue));
+ return(-1);
+ }
+ dsigCtx->signValueNode = cur;
+ cur = xmlSecGetNextElementNode(cur->next);
+
+ /* next node is optional KeyInfo */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeKeyInfo, xmlSecDSigNs))) {
+ keyInfoNode = cur;
+ cur = xmlSecGetNextElementNode(cur->next);
+ } else {
+ keyInfoNode = NULL;
+ }
+
+ /* next nodes are optional Object nodes */
+ while((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeObject, xmlSecDSigNs))) {
+ /* read manifests from objects */
+ if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_IGNORE_MANIFESTS) == 0) {
+ ret = xmlSecDSigCtxProcessObjectNode(dsigCtx, cur);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecDSigCtxProcessObjectNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* if there is something left than it's an error */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* now validated all the references and prepare transform */
+ ret = xmlSecDSigCtxProcessSignedInfoNodeEx(dsigCtx, signedInfoNode, noHash, pList);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecDSigCtxProcessSignedInfoNodeEx",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ /* references processing might change the status */
+ if(dsigCtx->status != xmlSecDSigStatusUnknown) {
+ return(0);
+ }
+
+ /* as the result, we should have sign and c14n methods set */
+ xmlSecAssert2(dsigCtx->signMethod != NULL, -1);
+ xmlSecAssert2(dsigCtx->c14nMethod != NULL, -1);
+
+ ret = xmlSecDSigCtxProcessKeyInfoNode(dsigCtx, keyInfoNode);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecDSigCtxProcessKeyInfoNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ /* as the result, we should have a key */
+ xmlSecAssert2(dsigCtx->signKey != NULL, -1);
+
+ /* if we need to write result to xml node then we need base64 encode result */
+ if(dsigCtx->operation == xmlSecTransformOperationSign) {
+ xmlSecTransformPtr base64Encode;
+
+ /* we need to add base64 encode transform */
+ base64Encode = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx),
+ xmlSecTransformBase64Id);
+ if(base64Encode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxCreateAndAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ base64Encode->operation = xmlSecTransformOperationEncode;
+ }
+
+ firstType = xmlSecTransformGetDataType(dsigCtx->transformCtx.first,
+ xmlSecTransformModePush, &(dsigCtx->transformCtx));
+ if((firstType & xmlSecTransformDataTypeXml) != 0) {
+ xmlSecNodeSetPtr nodeset = NULL;
+
+ xmlSecAssert2(signedInfoNode != NULL, -1);
+ nodeset = xmlSecNodeSetGetChildren(signedInfoNode->doc, signedInfoNode, 1, 0);
+ if(nodeset == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecNodeSetGetChildren",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(signedInfoNode)));
+ return(-1);
+ }
+
+ /* calculate the signature */
+ ret = xmlSecTransformCtxXmlExecute(&(dsigCtx->transformCtx), nodeset);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxXmlExecute",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecNodeSetDestroy(nodeset);
+ return(-1);
+ }
+ xmlSecNodeSetDestroy(nodeset);
+ } else {
+ /* TODO */
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "the binary c14n transforms are not supported yet",
+ XMLSEC_ERRORS_R_NOT_IMPLEMENTED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ _end
+ return(0);
+}
+
+int
+xmlSecDSigCtxProcessSignedInfoNodeEx(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node, int noHash, void* pList) {
+ xmlSecDSigReferenceCtxPtr dsigRefCtx;
+ xmlNodePtr cur;
+ int ret = -1;
+
+ _start
+ xmlSecAssert2(dsigCtx != NULL, -1);
+ xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1);
+ xmlSecAssert2(dsigCtx->signMethod == NULL, -1);
+ xmlSecAssert2(dsigCtx->c14nMethod == NULL, -1);
+ xmlSecAssert2((dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation == xmlSecTransformOperationVerify), -1);
+ xmlSecAssert2(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) == 0, -1);
+ xmlSecAssert2(node != NULL, -1);
+
+ /* first node is required CanonicalizationMethod. */
+ cur = xmlSecGetNextElementNode(node->children);
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeCanonicalizationMethod, xmlSecDSigNs))) {
+ dsigCtx->c14nMethod = xmlSecTransformCtxNodeRead(&(dsigCtx->transformCtx),
+ cur, xmlSecTransformUsageC14NMethod);
+ if(dsigCtx->c14nMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
+ ret = -1;
+ goto error;
+ }
+ } else if(dsigCtx->defC14NMethodId != xmlSecTransformIdUnknown) {
+ /* the dsig spec does require CanonicalizationMethod node
+ * to be present but in some case it application might decide to
+ * minimize traffic */
+ dsigCtx->c14nMethod = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx),
+ dsigCtx->defC14NMethodId);
+ if(dsigCtx->c14nMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ ret = -1;
+ goto error;
+ }
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "CanonicalizationMethod",
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "expected=%s",
+ xmlSecErrorsSafeString(xmlSecNodeCanonicalizationMethod));
+ ret = -1;
+ goto error;
+ }
+
+ /* insert membuf if requested */
+ if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNATURE) != 0) {
+ xmlSecAssert2(dsigCtx->preSignMemBufMethod == NULL, -1);
+ dsigCtx->preSignMemBufMethod = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx),
+ xmlSecTransformMemBufId);
+ if(dsigCtx->preSignMemBufMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxCreateAndAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "transform=%s",
+ xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecTransformMemBufId)));
+ }
+ }
+
+ /* next node is required SignatureMethod. */
+ cur = xmlSecGetNextElementNode( ((cur != NULL) ? cur->next : node->children) );
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeSignatureMethod, xmlSecDSigNs))) {
+ dsigCtx->signMethod = xmlSecTransformCtxNodeRead(&(dsigCtx->transformCtx),
+ cur, xmlSecTransformUsageSignatureMethod);
+ if(dsigCtx->signMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
+ ret = -1;
+ goto error;
+ }
+ } else if(dsigCtx->defSignMethodId != xmlSecTransformIdUnknown) {
+ /* the dsig spec does require SignatureMethod node
+ * to be present but in some case it application might decide to
+ * minimize traffic */
+ dsigCtx->signMethod = xmlSecTransformCtxCreateAndAppend(&(dsigCtx->transformCtx),
+ dsigCtx->defSignMethodId);
+ if(dsigCtx->signMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ ret = -1;
+ goto error;
+ }
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "expected=%s",
+ xmlSecErrorsSafeString(xmlSecNodeSignatureMethod));
+ ret = -1;
+ goto error;
+ }
+ dsigCtx->signMethod->operation = dsigCtx->operation;
+
+ /* calculate references */
+ cur = xmlSecGetNextElementNode(cur->next);
+ while((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs))) {
+ /* create reference */
+ dsigRefCtx = xmlSecDSigReferenceCtxCreate(dsigCtx, xmlSecDSigReferenceOriginSignedInfo);
+ if(dsigRefCtx == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecDSigReferenceCtxCreate",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ ret = -1;
+ goto error;
+ }
+
+ /* add to the list */
+ ret = xmlSecPtrListAdd(&(dsigCtx->signedInfoReferences), dsigRefCtx);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecPtrListAdd",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ xmlSecDSigReferenceCtxDestroy(dsigRefCtx);
+ ret = -1;
+ goto error;
+ }
+
+ /* process */
+ ret = xmlSecDSigReferenceCtxProcessNodeEx(dsigRefCtx, cur, noHash, pList);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecDSigReferenceCtxProcessNode",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
+
+ if(noHash != 1){
+ ret = -1;
+ goto error;
+ }
+ }
+
+ if(noHash == 1) {
+ dsigRefCtx->status = xmlSecDSigStatusSucceeded;
+ }
+
+ /* bail out if next Reference processing failed */
+ if(dsigRefCtx->status != xmlSecDSigStatusSucceeded) {
+ dsigCtx->status = xmlSecDSigStatusInvalid;
+ ret = -1;
+ goto error;
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* check that we have at least one Reference */
+ if(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) == 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_DSIG_NO_REFERENCES,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ ret = -1;
+ goto error;
+ }
+
+ /* if there is something left than it's an error */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ ret = -1;
+ goto error;
+ }
+ _end
+error:
+ return(ret);
+}
+
+int
+xmlSecDSigReferenceCtxProcessNodeEx(xmlSecDSigReferenceCtxPtr dsigRefCtx, xmlNodePtr node, int noHash, void* pList) {
+ xmlSecTransformCtxPtr transformCtx;
+ xmlNodePtr digestValueNode;
+ xmlNodePtr cur;
+ int ret;
+ int cmpResult = -1;
+ int len = 0;
+ int i = 0;
+
+ char** pNextTmp = (char**)pList;
+
+ xmlSecAssert2(dsigRefCtx != NULL, -1);
+ xmlSecAssert2(dsigRefCtx->dsigCtx != NULL, -1);
+ xmlSecAssert2(dsigRefCtx->digestMethod == NULL, -1);
+ xmlSecAssert2(dsigRefCtx->digestMethod == NULL, -1);
+ xmlSecAssert2(dsigRefCtx->preDigestMemBufMethod == NULL, -1);
+ xmlSecAssert2(node != NULL, -1);
+ xmlSecAssert2(node->doc != NULL, -1);
+
+ _start
+
+ transformCtx = &(dsigRefCtx->transformCtx);
+
+ if(pList == NULL){
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* read attributes first */
+ dsigRefCtx->uri = xmlGetProp(node, xmlSecAttrURI);
+
+ while(pNextTmp[i] != NULL)
+ {
+ len = strlen(pNextTmp[i]);
+ cmpResult = strncmp((const char *)dsigRefCtx->uri, (const char *)pNextTmp[i], len);
+ if( cmpResult == 0 ) {
+ sprintf(logMsg, "uri: %s", (char*)pNextTmp[i]);
+ xmlSecError(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_MAX_NUMBER, logMsg);
+ break;
+ }
+ ++i;
+ }
+
+ if(cmpResult != 0) {
+ cmpResult = -1;
+ goto partial;
+ }
+
+ dsigRefCtx->id = xmlGetProp(node, xmlSecAttrId);
+ dsigRefCtx->type= xmlGetProp(node, xmlSecAttrType);
+
+ /* set start URI (and check that it is enabled!) */
+ ret = xmlSecTransformCtxSetUri(transformCtx, dsigRefCtx->uri, node);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxSetUri",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "uri=%s",
+ xmlSecErrorsSafeString(dsigRefCtx->uri));
+ return(-1);
+ }
+
+ /* first is optional Transforms node */
+ cur = xmlSecGetNextElementNode(node->children);
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeTransforms, xmlSecDSigNs))) {
+ ret = xmlSecTransformCtxNodesListRead(transformCtx,
+ cur, xmlSecTransformUsageDSigTransform);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxNodesListRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
+ return(-1);
+ }
+
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* insert membuf if requested */
+ if(((dsigRefCtx->origin == xmlSecDSigReferenceOriginSignedInfo) &&
+ ((dsigRefCtx->dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_SIGNEDINFO_REFERENCES) != 0)) ||
+ ((dsigRefCtx->origin == xmlSecDSigReferenceOriginManifest) &&
+ ((dsigRefCtx->dsigCtx->flags & XMLSEC_DSIG_FLAGS_STORE_MANIFEST_REFERENCES) != 0))) {
+ xmlSecAssert2(dsigRefCtx->preDigestMemBufMethod == NULL, -1);
+ dsigRefCtx->preDigestMemBufMethod = xmlSecTransformCtxCreateAndAppend(
+ transformCtx,
+ xmlSecTransformMemBufId);
+ if(dsigRefCtx->preDigestMemBufMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxCreateAndAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "transform=%s",
+ xmlSecErrorsSafeString(xmlSecTransformKlassGetName(xmlSecTransformMemBufId)));
+ return(-1);
+ }
+ }
+
+ /* next node is required DigestMethod. */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDigestMethod, xmlSecDSigNs))) {
+ dsigRefCtx->digestMethod = xmlSecTransformCtxNodeRead(&(dsigRefCtx->transformCtx),
+ cur, xmlSecTransformUsageDigestMethod);
+ if(dsigRefCtx->digestMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxNodeRead",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)));
+ return(-1);
+ }
+ cur = xmlSecGetNextElementNode(cur->next);
+ } else if(dsigRefCtx->dsigCtx->defSignMethodId != xmlSecTransformIdUnknown) {
+ /* the dsig spec does require DigestMethod node
+ * to be present but in some case it application might decide to
+ * minimize traffic */
+ dsigRefCtx->digestMethod = xmlSecTransformCtxCreateAndAppend(&(dsigRefCtx->transformCtx),
+ dsigRefCtx->dsigCtx->defSignMethodId);
+ if(dsigRefCtx->digestMethod == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "expected=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDigestMethod));
+ return(-1);
+ }
+
+ dsigRefCtx->digestMethod->operation = dsigRefCtx->dsigCtx->operation;
+
+ /* last node is required DigestValue */
+ if((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeDigestValue, xmlSecDSigNs))) {
+ digestValueNode = cur;
+ cur = xmlSecGetNextElementNode(cur->next);
+ } else {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ "node=%s",
+ xmlSecErrorsSafeString(xmlSecNodeDigestValue));
+ return(-1);
+ }
+
+ /* if we have something else then it's an error */
+ if(cur != NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_UNEXPECTED_NODE,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* if we need to write result to xml node then we need base64 encode result */
+ if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) {
+ xmlSecTransformPtr base64Encode;
+
+ /* we need to add base64 encode transform */
+ base64Encode = xmlSecTransformCtxCreateAndAppend(transformCtx, xmlSecTransformBase64Id);
+ if(base64Encode == NULL) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxCreateAndAppend",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ base64Encode->operation = xmlSecTransformOperationEncode;
+ }
+
+ /* finally get transforms results */
+ ret = xmlSecTransformCtxExecute(transformCtx, node->doc);
+ if(ret < 0) {
+ sprintf(logMsg, "uri:%s", (char*)dsigRefCtx->uri);
+ logMsg[strlen(dsigRefCtx->uri)+5] = '\0';
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxExecute",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ logMsg);
+ return(-1);
+ }
+
+ dsigRefCtx->result = transformCtx->result;
+
+ if(dsigRefCtx->dsigCtx->operation == xmlSecTransformOperationSign) {
+ if((dsigRefCtx->result == NULL) || (xmlSecBufferGetData(dsigRefCtx->result) == NULL)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformCtxExecute",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* write signed data to xml */
+ xmlNodeSetContentLen(digestValueNode,
+ xmlSecBufferGetData(dsigRefCtx->result),
+ xmlSecBufferGetSize(dsigRefCtx->result));
+
+ /* set success status and we are done */
+ dsigRefCtx->status = xmlSecDSigStatusSucceeded;
+ } else {
+ /* verify SignatureValue node content */
+ ret = xmlSecTransformVerifyNodeContent(dsigRefCtx->digestMethod,
+ digestValueNode, transformCtx);
+ if(ret < 0) {
+ sprintf(logMsg, "uri:%s", (char*)dsigRefCtx->uri);
+ logMsg[strlen(dsigRefCtx->uri)+5] = '\0';
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecTransformVerifyNodeContent",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED, logMsg);
+ return(-1);
+ }
+
+ /* set status and we are done */
+ if(dsigRefCtx->digestMethod->status == xmlSecTransformStatusOk) {
+ dsigRefCtx->status = xmlSecDSigStatusSucceeded;
+ } else {
+ dsigRefCtx->status = xmlSecDSigStatusInvalid;
+ }
+ }
+
+ if(dsigRefCtx->digestMethod->status == xmlSecTransformStatusOk) {
+ dsigRefCtx->status = xmlSecDSigStatusSucceeded;
+ }
+
+ _end
+
+partial:
+ return(0);
+}
+
+
/**************************************************************************
*
* xmlSecDSigReferenceCtxListKlass