Adjust upstream/1.2.39 to tizen_base 08/306708/2 accepted/tizen_base accepted/tizen_base_asan accepted/tizen_base_toolchain accepted/tizen_base_x accepted/tizen_base_x_asan tizen_base accepted/tizen/base/20240227.052606 accepted/tizen/base/asan/20240422.015341 accepted/tizen/base/toolchain/20240301.141928 accepted/tizen/base/toolchain/20240301.142023 accepted/tizen/base/x/20240227.045209 accepted/tizen/base/x/asan/20240412.003422 upstream/1.2.39
authorDaniel Kita <d.kita@samsung.com>
Mon, 26 Feb 2024 11:07:54 +0000 (12:07 +0100)
committerDaniel Kita <d.kita@samsung.com>
Mon, 26 Feb 2024 12:14:45 +0000 (12:14 +0000)
Change-Id: Iec2c31d4f0b6868c71df9f4bbd25df7db5746122

include/xmlsec/keyinfo.h
include/xmlsec/xmldsig.h
src/openssl/digests.c
src/openssl/x509vfy.c
src/xmldsig.c

index 9a56374..ec61eb2 100644 (file)
@@ -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).
index 3dfa0c0..2ff21ab 100644 (file)
@@ -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);
 
 /**************************************************************************
  *
index 6584d5f..9862772 100644 (file)
@@ -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;
index 5f6e4dd..2319fbe 100644 (file)
@@ -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;
index 668ea23..58633d8 100644 (file)
@@ -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 <dsig:Signature/> 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);
         }