diff options
-rw-r--r-- | include/xmlsec/xmldsig.h | 39 | ||||
-rw-r--r-- | src/xmldsig.c | 847 |
2 files changed, 179 insertions, 707 deletions
diff --git a/include/xmlsec/xmldsig.h b/include/xmlsec/xmldsig.h index 5a375985..886bba98 100644 --- a/include/xmlsec/xmldsig.h +++ b/include/xmlsec/xmldsig.h @@ -94,6 +94,33 @@ typedef enum { */ #define XMLSEC_DSIG_FLAGS_USE_VISA3D_HACK 0x00000010 +/** TIZEN CUSTUMIZED + * XMLSEC_DSIG_FLAGS_IGNORE_REFERENCES: + * + * If this flag is set then <dsig:Reference/> nodes will not be processed. + */ +#define XMLSEC_DSIG_FLAGS_IGNORE_REFERENCES 0x00000020 + +/** TIZEN CUSTUMIZED + * XMLSEC_DSIG_FLAGS_CHECK_PROXY: + * + * If this flag is set then xmlSecProxyCtx will be processed. + */ +#define XMLSEC_DSIG_FLAGS_CHECK_PROXY 0x00000040 + +/** TIZEN CUSTUMIZED + * @cache: the cache include reference uri for supporting partial mode. + * cache represented uri will be check on processing references. + * @next: the pointer to indicate linked node (xmlSecProxyCtx). + */ +struct _xmlSecProxyCtx { + xmlChar* cache; + struct _xmlSecProxyCtx* next; +}; + +typedef struct _xmlSecProxyCtx xmlSecProxyCtx, + *xmlSecProxyCtxPtr; + /** * xmlSecDSigCtx: * @userData: the pointer to user data (xmlsec and xmlsec-crypto libraries @@ -143,6 +170,9 @@ struct _xmlSecDSigCtx { xmlSecTransformId defC14NMethodId; xmlSecTransformId defDigestMethodId; + /* TIZEN CUTUMIZED: these data user can set before performing the operation */ + xmlSecProxyCtxPtr proxyCtxPtr; + /* these data are returned */ xmlSecKeyPtr signKey; xmlSecTransformOperation operation; @@ -181,6 +211,10 @@ XMLSEC_EXPORT void xmlSecDSigCtxDebugDump (xmlSecDSigCtxPt XMLSEC_EXPORT void xmlSecDSigCtxDebugXmlDump (xmlSecDSigCtxPtr dsigCtx, FILE* output); +/* TIZEN CUSTUMIZED: xmlSecProxyCtx operator */ +XMLSEC_EXPORT int xmlSecProxyCtxAdd (xmlSecProxyCtxPtr* proxyCtxPtrPtr, + const xmlChar* uri); +XMLSEC_EXPORT void xmlSecProxyCtxDestroy (xmlSecProxyCtxPtr proxyCtxPtr); /************************************************************************** * @@ -257,11 +291,6 @@ 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 ec4338c4..0664c485 100644 --- a/src/xmldsig.c +++ b/src/xmldsig.c @@ -50,13 +50,10 @@ static int xmlSecDSigCtxProcessManifestNode (xmlSecDSigCtxPtr dsigCt static int xmlSecDSigCtxProcessReferences (xmlSecDSigCtxPtr dsigCtx, xmlNodePtr firstReferenceNode); -/* Tizen : Support for various validation mode */ -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); +/* TIZEN CUSTUMIZED */ +static int xmlSecHexToInt (char a); +static int xmlSecDecodeCmp (const xmlChar* encoded, + const xmlChar* plain); /* The ID attribute in XMLDSig is 'Id' */ static const xmlChar* xmlSecDSigIds[] = { xmlSecAttrId, NULL }; @@ -224,6 +221,49 @@ xmlSecDSigCtxFinalize(xmlSecDSigCtxPtr dsigCtx) { memset(dsigCtx, 0, sizeof(xmlSecDSigCtx)); } +/* TIZEN CUSTUMIZED */ +int +xmlSecProxyCtxAdd(xmlSecProxyCtxPtr* proxyCtxPtrPtr, const xmlChar* uri) { + xmlSecProxyCtxPtr pc = (xmlSecProxyCtxPtr)xmlMalloc(sizeof(xmlSecProxyCtx)); + if(pc == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_R_MALLOC_FAILED, + "size=%d", sizeof(xmlSecProxyCtx)); + return(-1); + } + + pc->cache = xmlStrdup(uri); + if(pc->cache == NULL) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + "xmlStrdup", + XMLSEC_ERRORS_R_MALLOC_FAILED, + "node=%s", + xmlSecErrorsSafeString(uri)); + return(-1); + } + pc->next = NULL; + + while(*proxyCtxPtrPtr != NULL) + proxyCtxPtrPtr = &((*proxyCtxPtrPtr)->next); + + *proxyCtxPtrPtr = pc; + return(0); +} + +void xmlSecProxyCtxDestroy(xmlSecProxyCtxPtr proxyCtxPtr) { + while(proxyCtxPtr != NULL) { + if(proxyCtxPtr->cache != NULL) + xmlFree(proxyCtxPtr->cache); + + xmlSecProxyCtxPtr next = proxyCtxPtr->next; + xmlFree(proxyCtxPtr); + proxyCtxPtr = next; + } +} + /** * xmlSecDSigCtxEnableReferenceTransform: * @dsigCtx: the pointer to <dsig:Signature/> processing context. @@ -597,19 +637,29 @@ 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) { + /* TIZEN CUSTUMIZED : if no-hash mode, skip processing references */ + if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_IGNORE_REFERENCES) != 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); + NULL, + XMLSEC_ERRORS_MAX_NUMBER, + "Skip processing references. no-hash mode."); + dsigCtx->status = xmlSecDSigStatusSucceeded; + } else { + /* 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 */ @@ -851,6 +901,40 @@ xmlSecDSigCtxProcessSignedInfoNode(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node, xm return(0); } +static int +xmlSecHexToInt(char a) +{ + if (a >= '0' && a <= '9') return(a - '0'); + if (a >= 'A' && a <= 'F') return(a - 'A' + 10); + if (a >= 'a' && a <= 'f') return(a - 'a' + 10); + + return(-1); +} + +static int +xmlSecDecodeCmp(const xmlChar* encoded, const xmlChar* plain) { + while(*plain != NULL) { + if(*encoded == NULL) + return(-1); + + /* check encoded char is same with plain char */ + if(*encoded == '%') { + if(*(encoded + 1) == NULL && *(encoded + 2) == NULL) + return(-1); + + if((int)*plain != + xmlSecHexToInt(*(encoded + 1)) * 16 + xmlSecHexToInt(*(encoded + 2))) + return(-1); + + encoded += 3; + plain++; + } else { + if(*(encoded++) != *(plain++)) + return(-1); + } + } + return(0); +} static int xmlSecDSigCtxProcessReferences(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr firstReferenceNode) { @@ -877,6 +961,49 @@ xmlSecDSigCtxProcessReferences(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr firstReferen return(-1); } + /* TIZEN CUTUMIZED : check proxy caches for partial mode */ + if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_CHECK_PROXY) != 0) { + int isInProxy = 0; + if(dsigCtx->proxyCtxPtr != NULL) { + xmlChar* refUri = xmlGetProp(cur, xmlSecAttrURI); + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_MAX_NUMBER, + "Start to search reference on proxy : %s.", + refUri); + + xmlSecProxyCtxPtr pc = dsigCtx->proxyCtxPtr; + int uriLen = strlen((const char*)refUri); + while(pc != NULL) { + if(xmlSecDecodeCmp(refUri, pc->cache) == 0) { + isInProxy = 1; + break; + } + pc = pc->next; + } + } else { + /* if proxy is not exist, process references */ + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_MAX_NUMBER, + "Proxy doesn't exist."); + isInProxy = 1; + } + + /* if not exist on proxy, skip on processing references */ + if(isInProxy == 0) { + xmlSecError(XMLSEC_ERRORS_HERE, + NULL, + NULL, + XMLSEC_ERRORS_MAX_NUMBER, + "Skip %s on processing references.", + xmlGetProp(cur, xmlSecAttrURI)); + continue; + } + } + /* create reference */ dsigRefCtx = xmlSecDSigReferenceCtxCreate(dsigCtx, xmlSecDSigReferenceOriginSignedInfo); if(dsigRefCtx == NULL) { @@ -1850,690 +1977,6 @@ xmlSecDSigReferenceCtxDebugXmlDump(xmlSecDSigReferenceCtxPtr dsigRefCtx, FILE* o } } - - -int -xmlSecDSigCtxVerifyEx(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node, int noHash, void* pList) { - int ret; - int len = 0; - - 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; - } - return(0); -} - -int -xmlSecDSigCtxProcessSignatureNodeEx (xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node, int noHash, void* pList) { - xmlSecTransformDataType firstType; - xmlNodePtr signedInfoNode = NULL; - xmlNodePtr keyInfoNode = NULL; - xmlNodePtr cur; - int ret; - - 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); - } - return(0); -} - -int -xmlSecDSigCtxProcessSignedInfoNodeEx(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr node, int noHash, void* pList) { - xmlSecDSigReferenceCtxPtr dsigRefCtx; - xmlNodePtr cur; - int ret = -1; - - 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 */ - if (cur != NULL) { - 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 */ - if(noHash != 1) { //if 0, then partial ///if 1, then no_hash - 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))); - - ret = -1; - goto error; - } - } - - dsigRefCtx->status = xmlSecDSigStatusSucceeded; - - /* bail out if next Reference processing failed */ - if(dsigRefCtx->status != xmlSecDSigStatusSucceeded) { - xmlSecError(XMLSEC_ERRORS_HERE, NULL, NULL, XMLSEC_ERRORS_MAX_NUMBER, "###### false"); - 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; - } -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); - - 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); - xmlSecAssert2(dsigRefCtx->uri != NULL, -1); - - while(pNextTmp[i] != NULL) { - len = strlen(pNextTmp[i]); - cmpResult = strncmp((const char *)dsigRefCtx->uri, (const char *)pNextTmp[i], len); - if(cmpResult == 0) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - NULL, - XMLSEC_ERRORS_MAX_NUMBER, - "uri: %s", - xmlSecErrorsSafeString(pNextTmp[i])); - 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) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecTransformCtxExecute", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "uri:%s", - xmlSecErrorsSafeString(dsigRefCtx->uri)); - 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) { - xmlSecError(XMLSEC_ERRORS_HERE, - NULL, - "xmlSecTransformVerifyNodeContent", - XMLSEC_ERRORS_R_XMLSEC_FAILED, - "uri:%s", - xmlSecErrorsSafeString(dsigRefCtx->uri)); - 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; - } - -partial: - return(0); -} - /************************************************************************** * * xmlSecDSigReferenceCtxListKlass |