[xmlsec] populate KeyInfo node before calculating Reference nodes
- From: Aleksey Sanin <aleksey src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [xmlsec] populate KeyInfo node before calculating Reference nodes
- Date: Fri, 9 Oct 2015 18:06:44 +0000 (UTC)
commit 8f6c95a90735c4d6e13bddf84de7a5284132826c
Author: Aleksey Sanin <aleksey aleksey com>
Date: Fri Oct 9 11:05:27 2015 -0700
populate KeyInfo node before calculating Reference nodes
src/xmldsig.c | 122 ++++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 91 insertions(+), 31 deletions(-)
---
diff --git a/src/xmldsig.c b/src/xmldsig.c
index 10ba03f..de5ba66 100644
--- a/src/xmldsig.c
+++ b/src/xmldsig.c
@@ -39,7 +39,8 @@
static int xmlSecDSigCtxProcessSignatureNode (xmlSecDSigCtxPtr dsigCtx,
xmlNodePtr node);
static int xmlSecDSigCtxProcessSignedInfoNode (xmlSecDSigCtxPtr dsigCtx,
- xmlNodePtr node);
+ xmlNodePtr node,
+
xmlNodePtr * firstReferenceNode);
static int xmlSecDSigCtxProcessKeyInfoNode (xmlSecDSigCtxPtr dsigCtx,
xmlNodePtr node);
static int xmlSecDSigCtxProcessObjectNode (xmlSecDSigCtxPtr dsigCtx,
@@ -47,6 +48,9 @@ static int xmlSecDSigCtxProcessObjectNode (xmlSecDSigCtxPtr dsigCt
static int xmlSecDSigCtxProcessManifestNode (xmlSecDSigCtxPtr dsigCtx,
xmlNodePtr node);
+static int xmlSecDSigCtxProcessReferences (xmlSecDSigCtxPtr dsigCtx,
+
xmlNodePtr firstReferenceNode);
+
/* The ID attribute in XMLDSig is 'Id' */
static const xmlChar* xmlSecDSigIds[] = { xmlSecAttrId, NULL };
@@ -470,6 +474,7 @@ xmlSecDSigCtxProcessSignatureNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
xmlSecTransformDataType firstType;
xmlNodePtr signedInfoNode = NULL;
xmlNodePtr keyInfoNode = NULL;
+ xmlNodePtr firstReferenceNode = NULL;
xmlNodePtr cur;
int ret;
@@ -558,7 +563,7 @@ xmlSecDSigCtxProcessSignatureNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
}
/* now validated all the references and prepare transform */
- ret = xmlSecDSigCtxProcessSignedInfoNode(dsigCtx, signedInfoNode);
+ ret = xmlSecDSigCtxProcessSignedInfoNode(dsigCtx, signedInfoNode, &firstReferenceNode);
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
NULL,
@@ -567,15 +572,12 @@ xmlSecDSigCtxProcessSignatureNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
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);
+ /* now read key info node */
ret = xmlSecDSigCtxProcessKeyInfoNode(dsigCtx, keyInfoNode);
if(ret < 0) {
xmlSecError(XMLSEC_ERRORS_HERE,
@@ -588,6 +590,21 @@ xmlSecDSigCtxProcessSignatureNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
/* as the result, we should have a key */
xmlSecAssert2(dsigCtx->signKey != NULL, -1);
+ /* now actually process references and calculate digests */
+ ret = xmlSecDSigCtxProcessReferences(dsigCtx, firstReferenceNode);
+ if(ret < 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ "xmlSecDSigCtxProcessReferences",
+ XMLSEC_ERRORS_R_XMLSEC_FAILED,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+ /* references processing might change the status */
+ if(dsigCtx->status != xmlSecDSigStatusUnknown) {
+ return(0);
+ }
+
/* if we need to write result to xml node then we need base64 encode result */
if(dsigCtx->operation == xmlSecTransformOperationSign) {
xmlSecTransformPtr base64Encode;
@@ -683,8 +700,8 @@ xmlSecDSigCtxProcessSignatureNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
*
*/
static int
-xmlSecDSigCtxProcessSignedInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
- xmlSecDSigReferenceCtxPtr dsigRefCtx;
+xmlSecDSigCtxProcessSignedInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node, xmlNodePtr *
firstReferenceNode) {
+ xmlSecSize refNodesCount = 0;
xmlNodePtr cur;
int ret;
@@ -693,8 +710,9 @@ xmlSecDSigCtxProcessSignedInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
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);
+ xmlSecAssert2(firstReferenceNode != NULL, -1);
+ xmlSecAssert2((*firstReferenceNode) == NULL, -1);
/* first node is required CanonicalizationMethod. */
cur = xmlSecGetNextElementNode(node->children);
@@ -788,12 +806,72 @@ xmlSecDSigCtxProcessSignedInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
}
dsigCtx->signMethod->operation = dsigCtx->operation;
- /* calculate references */
+ /* read references */
if(cur != NULL) {
cur = xmlSecGetNextElementNode(cur->next);
}
while((cur != NULL) && (xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs))) {
- /* create reference */
+ /* record first reference node */
+ if((*firstReferenceNode) == NULL) {
+ (*firstReferenceNode) = cur;
+ }
+ ++refNodesCount;
+
+ /* go to next */
+ cur = xmlSecGetNextElementNode(cur->next);
+ }
+
+ /* check that we have at least one Reference */
+ if(refNodesCount == 0) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ NULL,
+ XMLSEC_ERRORS_R_DSIG_NO_REFERENCES,
+ XMLSEC_ERRORS_NO_MESSAGE);
+ return(-1);
+ }
+
+ /* 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);
+ }
+
+ /* done */
+ return(0);
+}
+
+
+static int
+xmlSecDSigCtxProcessReferences(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr firstReferenceNode) {
+ xmlSecDSigReferenceCtxPtr dsigRefCtx;
+ xmlNodePtr cur;
+ int ret;
+
+ xmlSecAssert2(dsigCtx != NULL, -1);
+ xmlSecAssert2(dsigCtx->status == xmlSecDSigStatusUnknown, -1);
+ xmlSecAssert2((dsigCtx->operation == xmlSecTransformOperationSign) || (dsigCtx->operation ==
xmlSecTransformOperationVerify), -1);
+ xmlSecAssert2(xmlSecPtrListGetSize(&(dsigCtx->signedInfoReferences)) == 0, -1);
+ xmlSecAssert2(firstReferenceNode != NULL, -1);
+
+ /* process references */
+ for(cur = firstReferenceNode; (cur != NULL); cur = xmlSecGetNextElementNode(cur->next)) {
+ /* already checked but we trust none */
+ if(!xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs)) {
+ xmlSecError(XMLSEC_ERRORS_HERE,
+ NULL,
+ xmlSecErrorsSafeString(xmlSecNodeGetName(cur)),
+ XMLSEC_ERRORS_R_INVALID_NODE,
+ "expected=%s",
+ xmlSecErrorsSafeString(xmlSecNodeReference));
+ return(-1);
+ }
+
+ /* create reference */
dsigRefCtx = xmlSecDSigReferenceCtxCreate(dsigCtx, xmlSecDSigReferenceOriginSignedInfo);
if(dsigRefCtx == NULL) {
xmlSecError(XMLSEC_ERRORS_HERE,
@@ -833,31 +911,13 @@ xmlSecDSigCtxProcessSignedInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
dsigCtx->status = xmlSecDSigStatusInvalid;
return(0);
}
- 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);
- return(-1);
}
- /* 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);
- }
+ /* done */
return(0);
}
+
static int
xmlSecDSigCtxProcessKeyInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node) {
int ret;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]