diff options
author | Konrad Lipinski <k.lipinski2@samsung.com> | 2019-07-22 18:20:09 +0200 |
---|---|---|
committer | Konrad Lipinski <k.lipinski2@samsung.com> | 2019-08-01 14:54:38 +0200 |
commit | 8ebee53b1dd1fc005ec1f27652b35abd56202a32 (patch) | |
tree | 7f4ff1146605a2fee5fa55c3bc2732f0f53c18dc | |
parent | cc6febdd37186eeea33bcbce89d79f661ee0009f (diff) | |
download | xmlsec1-upstream/1.2.28.tar.gz xmlsec1-upstream/1.2.28.tar.bz2 xmlsec1-upstream/1.2.28.zip |
Adjust upstream c4d0493d545b99194eea1b2b058930d5a9bb91b1 (1.2.28) to Tizenupstream/1.2.28
Change-Id: Id22df649ea95852ef01b6077beb90b31809004d0
-rw-r--r-- | include/xmlsec/keyinfo.h | 11 | ||||
-rw-r--r-- | include/xmlsec/xmldsig.h | 42 | ||||
-rw-r--r-- | src/openssl/digests.c | 4 | ||||
-rw-r--r-- | src/openssl/x509vfy.c | 5 | ||||
-rw-r--r-- | src/xmldsig.c | 171 |
5 files changed, 220 insertions, 13 deletions
diff --git a/include/xmlsec/keyinfo.h b/include/xmlsec/keyinfo.h index 1f79284d..49b96016 100644 --- a/include/xmlsec/keyinfo.h +++ b/include/xmlsec/keyinfo.h @@ -155,6 +155,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 7dab2411..2225bb90 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 <dsig:Reference/> 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 537a7399..d27cf8d5 100644 --- a/src/openssl/digests.c +++ b/src/openssl/digests.c @@ -272,14 +272,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 2e54f136..a6200773 100644 --- a/src/openssl/x509vfy.c +++ b/src/openssl/x509vfy.c @@ -331,6 +331,11 @@ xmlSecOpenSSLX509StoreVerify(xmlSecKeyDataStorePtr store, XMLSEC_STACK_OF_X509* err = X509_STORE_CTX_get_error(xsc); 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; diff --git a/src/xmldsig.c b/src/xmldsig.c index 619e725a..73b6171a 100644 --- a/src/xmldsig.c +++ b/src/xmldsig.c @@ -55,6 +55,15 @@ 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 }; @@ -193,6 +202,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 <dsig:Signature/> processing context. @@ -511,15 +555,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 */ @@ -710,6 +760,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) { @@ -731,6 +819,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) { @@ -1405,7 +1554,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; @@ -1428,7 +1577,7 @@ xmlSecDSigReferenceCtxProcessNode(xmlSecDSigReferenceCtxPtr dsigRefCtx, xmlNodeP ret = xmlSecTransformVerifyNodeContent(dsigRefCtx->digestMethod, digestValueNode, transformCtx); if(ret < 0) { - xmlSecInternalError("xmlSecTransformVerifyNodeContent", NULL); + xmlSecInternalError("xmlSecTransformVerifyNodeContent", dsigRefCtx->uri); return(-1); } |