diff --git a/src/Signer.php b/src/Signer.php
index d6b4e44..1ac573a 100755
--- a/src/Signer.php
+++ b/src/Signer.php
@@ -32,7 +32,7 @@
class Signer
{
- const CANONICAL = [true,false,null,null];
+ const CANONICAL = [true, false, null, null];
/**
* Make Signature tag
@@ -174,6 +174,7 @@ private static function createSignature(
$x509DataNode->appendChild($x509CertificateNode);
return $dom;
}
+
/**
* Remove old signature from document to replace it
* @param string $content
@@ -196,6 +197,7 @@ public static function removeSignature($content)
}
return $dom->saveXML();
}
+
/**
* Verify if xml signature is valid
* @param string $content
@@ -218,9 +220,10 @@ public static function isSigned($content, $tagname = '', $canonical = self::CANO
/**
* Check if Signature tag already exists
* @param string $content
+ * @param string|null $rootname
* @return boolean
*/
- public static function existsSignature($content)
+ public static function existsSignature($content, $rootname = null)
{
if (!Validator::isXML($content)) {
throw SignerException::isNotXml();
@@ -229,8 +232,23 @@ public static function existsSignature($content)
$dom->formatOutput = false;
$dom->preserveWhiteSpace = false;
$dom->loadXML($content);
- $signature = $dom->getElementsByTagName('Signature')->item(0);
- return !empty($signature);
+
+ if (empty($rootname)) {
+ return !empty($dom->getElementsByTagName('Signature')->item(0));
+ }
+
+ $root = $dom->documentElement->getElementsByTagName($rootname)->item(0);
+ if ($dom->documentElement->tagName == $rootname) {
+ $root = $dom->documentElement;
+ }
+
+ foreach ($root->childNodes as $child) {
+ if ($child->nodeName == 'Signature') {
+ return true;
+ }
+ }
+
+ return false;
}
/**
@@ -256,7 +274,7 @@ public static function signatureCheck($xml, $canonical = self::CANONICAL)
$publicKey = PublicKey::createFromContent($certificateContent);
$signInfoNode = self::canonize($signature->getElementsByTagName('SignedInfo')->item(0), $canonical);
$signatureValue = $signature->getElementsByTagName('SignatureValue')->item(0)->nodeValue;
- $decodedSignature = base64_decode(str_replace(array("\r", "\n"), '', $signatureValue));
+ $decodedSignature = base64_decode(str_replace(["\r", "\n"], '', $signatureValue));
if (!$publicKey->verify($signInfoNode, $decodedSignature, $algorithm)) {
throw SignerException::signatureComparisonFailed();
}
diff --git a/tests/SignerTest.php b/tests/SignerTest.php
index 655bc4b..ebbcfbf 100755
--- a/tests/SignerTest.php
+++ b/tests/SignerTest.php
@@ -79,6 +79,30 @@ public function testIsSignedFailDigest()
Signer::isSigned($xml);
}
+ public function testExistsSignatureRootnode(): void
+ {
+ $content = '';
+ $this->assertTrue(Signer::existsSignature($content));
+
+ $content = '';
+ $this->assertTrue(Signer::existsSignature($content));
+
+ $content = '';
+ $this->assertFalse(Signer::existsSignature($content, 'a'));
+
+ $content = '';
+ $this->assertTrue(Signer::existsSignature($content, 'a'));
+
+ $content = '';
+ $this->assertFalse(Signer::existsSignature($content, 'c'));
+
+ $content = '';
+ $this->assertTrue(Signer::existsSignature($content, 'c'));
+
+ $content = '';
+ $this->assertTrue(Signer::existsSignature($content, 'b'));
+ }
+
/**
* @covers Signer::existsSignature
* @covers Signer::digestCheck