summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonrad Lipinski <k.lipinski2@samsung.com>2019-07-22 16:20:09 (GMT)
committerKonrad Lipinski <k.lipinski2@samsung.com>2019-08-01 12:54:38 (GMT)
commit8ebee53b1dd1fc005ec1f27652b35abd56202a32 (patch)
tree7f4ff1146605a2fee5fa55c3bc2732f0f53c18dc
parentcc6febdd37186eeea33bcbce89d79f661ee0009f (diff)
downloadxmlsec1-8ebee53b1dd1fc005ec1f27652b35abd56202a32.zip
xmlsec1-8ebee53b1dd1fc005ec1f27652b35abd56202a32.tar.gz
xmlsec1-8ebee53b1dd1fc005ec1f27652b35abd56202a32.tar.bz2
Adjust upstream c4d0493d545b99194eea1b2b058930d5a9bb91b1 (1.2.28) to Tizenupstream/1.2.28refs/changes/84/210584/3
Change-Id: Id22df649ea95852ef01b6077beb90b31809004d0
-rw-r--r--include/xmlsec/keyinfo.h11
-rw-r--r--include/xmlsec/xmldsig.h42
-rw-r--r--src/openssl/digests.c4
-rw-r--r--src/openssl/x509vfy.c5
-rw-r--r--src/xmldsig.c171
5 files changed, 220 insertions, 13 deletions
diff --git a/include/xmlsec/keyinfo.h b/include/xmlsec/keyinfo.h
index 1f79284..49b9601 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 7dab241..2225bb9 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 537a739..d27cf8d 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 2e54f13..a620077 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 619e725..73b6171 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);
}