From ff6aad475d15bed96efab84439733cb8802e68fe Mon Sep 17 00:00:00 2001 From: Daniel Kita Date: Mon, 26 Feb 2024 12:07:54 +0100 Subject: [PATCH] Adjust upstream/1.2.39 to tizen_base Change-Id: Iec2c31d4f0b6868c71df9f4bbd25df7db5746122 --- include/xmlsec/keyinfo.h | 11 +++ include/xmlsec/xmldsig.h | 42 ++++++++++++ src/openssl/digests.c | 4 +- src/openssl/x509vfy.c | 5 ++ src/xmldsig.c | 172 ++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 221 insertions(+), 13 deletions(-) diff --git a/include/xmlsec/keyinfo.h b/include/xmlsec/keyinfo.h index 9a56374..ec61eb2 100644 --- a/include/xmlsec/keyinfo.h +++ b/include/xmlsec/keyinfo.h @@ -156,6 +156,17 @@ typedef enum { #define XMLSEC_KEYINFO_FLAGS_X509DATA_SKIP_STRICT_CHECKS 0x00004000 /** + * XMLSEC_KEYINFO_FLAGS_SKIP_VERIFY_CHAIN: + * + * If the flag is set then we wont stop document validation + * on certificate chain error. Instead of stopping validation + * we'll just set flag XMLSEC_KEYINFO_ERROR_FLAGS_BROKEN_CHAIN + * as flags2 value. + */ +#define XMLSEC_KEYINFO_FLAGS_ALLOW_BROKEN_CHAIN 0x00008000 +#define XMLSEC_KEYINFO_ERROR_FLAGS_BROKEN_CHAIN 0x00000001 + +/** * xmlSecKeyInfoCtx: * @userData: the pointer to user data (xmlsec and xmlsec-crypto * never touch this). diff --git a/include/xmlsec/xmldsig.h b/include/xmlsec/xmldsig.h index 3dfa0c0..2ff21ab 100644 --- a/include/xmlsec/xmldsig.h +++ b/include/xmlsec/xmldsig.h @@ -94,6 +94,40 @@ typedef enum { */ #define XMLSEC_DSIG_FLAGS_USE_VISA3D_HACK 0x00000010 +/** TIZEN CUSTOMIZED + * XMLSEC_DSIG_FLAGS_IGNORE_REFERENCES: + * + * If this flag is set then nodes will not be processed. + */ +#define XMLSEC_DSIG_FLAGS_IGNORE_REFERENCES 0x00000020 + +/** TIZEN CUSTOMIZED + * XMLSEC_DSIG_FLAGS_CHECK_PROXY: + * + * If this flag is set then xmlSecProxyCtx will be processed. + */ +#define XMLSEC_DSIG_FLAGS_CHECK_PROXY 0x00000040 + +/** TIZEN CUSTOMIZED + * XMLSEC_DSIG_FLAGS_SKIP_PROXY: + * + * If this flag is set then xmlSecProxyCtx will not be processed. + */ +#define XMLSEC_DSIG_FLAGS_SKIP_PROXY 0x00000080 + +/** TIZEN CUSTOMIZED + * @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 +177,10 @@ struct _xmlSecDSigCtx { xmlSecTransformId defC14NMethodId; xmlSecTransformId defDigestMethodId; + /* TIZEN CUSTOMIZED: these data user can set before performing the operation */ + xmlSecProxyCtxPtr skipReferences; + xmlSecProxyCtxPtr checkReferences; + /* these data are returned */ xmlSecKeyPtr signKey; xmlSecTransformOperation operation; @@ -181,6 +219,10 @@ XMLSEC_EXPORT void xmlSecDSigCtxDebugDump (xmlSecDSigCtxPt XMLSEC_EXPORT void xmlSecDSigCtxDebugXmlDump (xmlSecDSigCtxPtr dsigCtx, FILE* output); +/* TIZEN CUSTOMIZED: xmlSecProxyCtx operator */ +XMLSEC_EXPORT int xmlSecProxyCtxAdd (xmlSecProxyCtxPtr* proxyCtxPtrPtr, + const xmlChar* uri); +XMLSEC_EXPORT void xmlSecProxyCtxDestroy (xmlSecProxyCtxPtr proxyCtxPtr); /************************************************************************** * diff --git a/src/openssl/digests.c b/src/openssl/digests.c index 6584d5f..9862772 100644 --- a/src/openssl/digests.c +++ b/src/openssl/digests.c @@ -348,14 +348,14 @@ xmlSecOpenSSLEvpDigestVerify(xmlSecTransformPtr transform, xmlSecInvalidSizeError("Digest", dataSize, ctx->dgstSize, xmlSecTransformGetName(transform)); transform->status = xmlSecTransformStatusFail; - return(0); + return -1; } if(memcmp(ctx->dgst, data, ctx->dgstSize) != 0) { xmlSecInvalidDataError("data and digest do not match", xmlSecTransformGetName(transform)); transform->status = xmlSecTransformStatusFail; - return(0); + return -1; } transform->status = xmlSecTransformStatusOk; diff --git a/src/openssl/x509vfy.c b/src/openssl/x509vfy.c index 5f6e4dd..2319fbe 100644 --- a/src/openssl/x509vfy.c +++ b/src/openssl/x509vfy.c @@ -371,6 +371,11 @@ xmlSecOpenSSLX509StoreVerify(xmlSecKeyDataStorePtr store, XMLSEC_STACK_OF_X509* X509_STORE_CTX_cleanup (xsc); + if(ret != 1 && keyInfoCtx->flags & XMLSEC_KEYINFO_FLAGS_ALLOW_BROKEN_CHAIN){ + ret = 1; + keyInfoCtx->flags2 |= XMLSEC_KEYINFO_ERROR_FLAGS_BROKEN_CHAIN; + } + if(ret == 1) { res = cert; goto done; diff --git a/src/xmldsig.c b/src/xmldsig.c index 668ea23..58633d8 100644 --- a/src/xmldsig.c +++ b/src/xmldsig.c @@ -58,6 +58,16 @@ static int xmlSecDSigCtxProcessManifestNode (xmlSecDSigCtxPtr dsigCt static int xmlSecDSigCtxProcessReferences (xmlSecDSigCtxPtr dsigCtx, xmlNodePtr firstReferenceNode); +/* TIZEN CUSTOMIZED */ +static int xmlSecHexToInt (char a); +static int xmlSecDecodeCmp (const xmlChar* encoded, + const xmlChar* plain); +#define xmlSecTizenError(...) do {\ + xmlSecError(XMLSEC_ERRORS_HERE,NULL,NULL,\ + XMLSEC_ERRORS_MAX_NUMBER,\ + __VA_ARGS__);\ + } while (0) + /* The ID attribute in XMLDSig is 'Id' */ static const xmlChar* xmlSecDSigIds[] = { xmlSecAttrId, NULL }; @@ -195,6 +205,41 @@ xmlSecDSigCtxFinalize(xmlSecDSigCtxPtr dsigCtx) { memset(dsigCtx, 0, sizeof(xmlSecDSigCtx)); } +/* TIZEN CUSTOMIZED */ +int +xmlSecProxyCtxAdd(xmlSecProxyCtxPtr* proxyCtxPtrPtr, const xmlChar* uri) { + xmlSecProxyCtxPtr pc = (xmlSecProxyCtxPtr)xmlMalloc(sizeof(xmlSecProxyCtx)); + if(pc == NULL) { + xmlSecMallocError(sizeof(xmlSecProxyCtx), NULL); + return(-1); + } + + pc->cache = xmlStrdup(uri); + if(pc->cache == NULL) { + xmlSecStrdupError(uri, NULL); + xmlFree(pc); + 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 processing context. @@ -517,15 +562,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) { - xmlSecInternalError("xmlSecDSigCtxProcessReferences", NULL); - return(-1); - } - /* references processing might change the status */ - if(dsigCtx->status != xmlSecDSigStatusUnknown) { - return(0); + /* TIZEN CUSTOMIZED : if no-hash mode, skip processing references */ + if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_IGNORE_REFERENCES) != 0) { + xmlSecTizenError("Skip processing references. no-hash mode."); + dsigCtx->status = xmlSecDSigStatusSucceeded; + } else { + /* now actually process references and calculate digests */ + ret = xmlSecDSigCtxProcessReferences(dsigCtx, firstReferenceNode); + if(ret < 0) { + xmlSecInternalError("xmlSecDSigCtxProcessReferences", NULL); + 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 */ @@ -717,6 +768,44 @@ 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) { + + xmlSecAssert2(encoded != NULL, -1); + xmlSecAssert2(plain != NULL, -1); + + while(*plain != '\0') { + if(*encoded == '\0') + return(-1); + + /* check encoded char is same with plain char */ + if(*encoded == '%') { + if(*(encoded + 1) == '\0' &&*(encoded + 2) == '\0') + 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) { @@ -738,6 +827,67 @@ xmlSecDSigCtxProcessReferences(xmlSecDSigCtxPtr dsigCtx, xmlNodePtr firstReferen return(-1); } + /* TIZEN CUSTOMIZED : skip uri in proxy caches for proxy mode */ + if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_SKIP_PROXY) != 0) { + + int isInProxy = 0; + if(dsigCtx->skipReferences != NULL) { + xmlChar* refUri = xmlGetProp(cur, xmlSecAttrURI); + if(refUri == NULL) { + xmlSecInvalidNodeAttributeError(cur, NULL, NULL, "empty"); + return(-1); + } + + xmlSecProxyCtxPtr pc = dsigCtx->skipReferences; + while(pc != NULL) { + if(strncmp((char*)refUri, (char*)pc->cache, xmlStrlen(refUri)) == 0) { + isInProxy = 1; + xmlSecTizenError("[%s] is already checked by singature-validator.", refUri); + break; + } + pc = pc->next; + } + xmlFree(refUri); + } else { + /* if proxy is not exist, process references */ + xmlSecTizenError("Proxy doesn't exist."); + } + + if(isInProxy) + continue; + } + + /* TIZEN CUSTOMIZED : check uri only in proxy caches for partial mode */ + if((dsigCtx->flags & XMLSEC_DSIG_FLAGS_CHECK_PROXY) != 0) { + + int isInProxy = 0; + if(dsigCtx->checkReferences != NULL) { + xmlChar* refUri = xmlGetProp(cur, xmlSecAttrURI); + if(refUri == NULL) { + xmlSecInvalidNodeAttributeError(cur, NULL, NULL, "empty"); + return(-1); + } + + xmlSecProxyCtxPtr pc = dsigCtx->checkReferences; + while(pc != NULL) { + if(xmlSecDecodeCmp(refUri, pc->cache) == 0) { + isInProxy = 1; + xmlSecTizenError("Check [%s] on processing references.", refUri); + break; + } + pc = pc->next; + } + xmlFree(refUri); + } else { + /* if proxy is not exist, process references */ + xmlSecTizenError("Proxy doesn't exist."); + } + + /* if not exist on proxy, skip on processing references */ + if(isInProxy == 0) + continue; + } + /* create reference */ dsigRefCtx = xmlSecDSigReferenceCtxCreate(dsigCtx, xmlSecDSigReferenceOriginSignedInfo); if(dsigRefCtx == NULL) { @@ -1413,7 +1563,7 @@ xmlSecDSigReferenceCtxProcessNode(xmlSecDSigReferenceCtxPtr dsigRefCtx, xmlNodeP /* finally get transforms results */ ret = xmlSecTransformCtxExecute(transformCtx, node->doc); if(ret < 0) { - xmlSecInternalError("xmlSecTransformCtxExecute", NULL); + xmlSecInternalError("xmlSecTransformCtxExecute", dsigRefCtx->uri); return(-1); } dsigRefCtx->result = transformCtx->result; @@ -1441,7 +1591,7 @@ xmlSecDSigReferenceCtxProcessNode(xmlSecDSigReferenceCtxPtr dsigRefCtx, xmlNodeP ret = xmlSecTransformVerifyNodeContent(dsigRefCtx->digestMethod, digestValueNode, transformCtx); if(ret < 0) { - xmlSecInternalError("xmlSecTransformVerifyNodeContent", NULL); + xmlSecInternalError("xmlSecTransformVerifyNodeContent", dsigRefCtx->uri); return(-1); } -- 2.7.4