Skip to content
Snippets Groups Projects
SignerTest.php 6.15 KiB
Newer Older
Tim van Dijen's avatar
Tim van Dijen committed
namespace SimpleSAML\Test\XML;
use org\bovigo\vfs\vfsStream;
Tim van Dijen's avatar
Tim van Dijen committed
use SimpleSAML\Configuration;
use SimpleSAML\Test\SigningTestCase;
use SimpleSAML\XML\Signer;

/**
 * Tests for SimpleSAML\XML\Signer.
 */
class SignerTest extends SigningTestCase
    /** @var string */
    private $other_certificate_file;

    // openssl req -new -x509 -key good.key.pem -out public2.pem -days 3650
    /** @var string */
    private $other_certificate = <<<'NOWDOC'
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUGPKUWW1GN07xxAsGENQ+rZPyABAwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0xOTAyMTgxNTU5MDRaFw0yOTAy
MTUxNTU5MDRaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCqY2fhu3+OsweCha3BctzaiTXsEeHU7kRNuf2srcoW
OTcFenndoa96KWX4ptbtKCuIZlJrUoETa5pDLaZmmIFCoWstyAqG3NoI0vIG8o6j
NCGf9c3qbaQ3wQNloYgbG0z/rKlQCfK2xwajZsrPIe06Ng4/AR4AuKrv5itHUFzZ
fTk7JW51XxaO7xBQKbs2jzn9M6PEPpKtZRe4Q8mbRGLJUx5mG4qa3GbSQHZm1DSU
pWI7FouIFGJb1OV1j3g1od+BplKkKauKSiJLhAniFOjicRWmPH7UEMkhqvdt/Ef6
/C4uU6hmDcoj0Fhxabmf5crBPGeFoFYzwwfc+2Ys1utHAgMBAAGjUzBRMB0GA1Ud
DgQWBBSJC3ioF0fu+hgZTQCy0dg1LwNE0TAfBgNVHSMEGDAWgBSJC3ioF0fu+hgZ
TQCy0dg1LwNE0TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB/
otEPUNWLWIEJXOnF7pPv1orXdeCGpCgNK+k8pJDYkl7jTNs3sq8U/aCy9qIrrFOA
MH0D5dh9xVf+DeDeUKT6/Td8EvPrXnzfkfU2xDgbCKk+WIk1luMvCwOzxYFlPCOo
pBCt2aQAHuqKeR6uXOjyRv5Kw0jdr94df/FquqHFkSQxVSPBSLW8jzwxXKSh291j
d2udRIYG0WcjQTk86+EraXNGtuwUaknQ7WPKlJwLzypuZM8lk3F1FXxXWomHN3SH
29N8MpL1tceQuMX8F6cdQuhjLThs4b+Dy6ITF05Pgm7xr1tByO+C5e7dNpEDwA3I
31r+Yt4vwxjeCqQDSZik
-----END CERTIFICATE-----
NOWDOC;

    const ROOTDIRNAME = 'testdir';
    const DEFAULTCERTDIR = 'certdir';
    const OTHER_CERTIFICATE = 'other_certificate.pem';
Tim van Dijen's avatar
Tim van Dijen committed

    /**
     * @return array
     */
    public function getCertDirContent()
        return [
            self::GOOD_PRIVATE_KEY => $this->good_private_key,
            self::GOOD_CERTIFICATE => $this->good_certificate,
            self::OTHER_CERTIFICATE => $this->other_certificate,
        ];
Tim van Dijen's avatar
Tim van Dijen committed

    /**
     * @return void
     */
    public function testSignerBasic()
    {
        $res = new Signer([]);

        $this->assertNotNull($res);
    }

Tim van Dijen's avatar
Tim van Dijen committed

    /**
     * @return void
     */
    public function testSignBasic()
    {
        $node = new \DOMDocument();
        $node->loadXML('<?xml version="1.0"?><node>value</node>');
        $element = $node->getElementsByTagName("node")->item(0);

        $doc = new \DOMDocument();
        $insertInto = $doc->appendChild(new \DOMElement('insert'));

        $signer = new Signer([]);
        $signer->loadPrivateKey($this->good_private_key_file, null, true);
        $signer->sign($element, $insertInto);

        $res = $doc->saveXML();

        $this->assertContains('DigestValue', $res);
        $this->assertContains('SignatureValue', $res);
    }

Tim van Dijen's avatar
Tim van Dijen committed
     * @param string $certificate
Tim van Dijen's avatar
Tim van Dijen committed
     * @return string
     */
    private static function getCertificateValue($certificate)
    {
        $replacements = [
            "-----BEGIN CERTIFICATE-----",
            "-----END CERTIFICATE-----",
            "\n",

        return str_replace($replacements, "", $certificate);
    }

Tim van Dijen's avatar
Tim van Dijen committed

    /**
     * @return void
     */
    public function testSignWithCertificate()
    {
        $node = new \DOMDocument();
        $node->loadXML('<?xml version="1.0"?><node>value</node>');
        $element = $node->getElementsByTagName("node")->item(0);

        $doc = new \DOMDocument();
        $insertInto = $doc->appendChild(new \DOMElement('insert'));

        $signer = new Signer([]);
        $signer->loadPrivateKey($this->good_private_key_file, null, true);
        $signer->loadCertificate($this->good_certificate_file, true);
        $signer->sign($element, $insertInto);

        $res = $doc->saveXML();

        $expected = self::getCertificateValue($this->good_certificate);

        $this->assertContains('X509Certificate', $res);
        $this->assertContains($expected, $res);
    }

Tim van Dijen's avatar
Tim van Dijen committed

    /**
     * @return void
     */
    public function testSignWithMultiCertificate()
    {
        $this->other_certificate_file = $this->certdir . DIRECTORY_SEPARATOR . self::OTHER_CERTIFICATE;
        $node = new \DOMDocument();
        $node->loadXML('<?xml version="1.0"?><node>value</node>');
        $element = $node->getElementsByTagName("node")->item(0);

        $doc = new \DOMDocument();
        $insertInto = $doc->appendChild(new \DOMElement('insert'));

        $signer = new Signer([]);
        $signer->loadPrivateKey($this->good_private_key_file, null, true);
        $signer->loadCertificate($this->good_certificate_file, true);
        $signer->addCertificate($this->other_certificate_file, true);
        $signer->sign($element, $insertInto);

        $res = $doc->saveXML();

        $expected1 = self::getCertificateValue($this->good_certificate);
        $expected2 = self::getCertificateValue($this->other_certificate);

        $this->assertContains('X509Certificate', $res);
        $this->assertContains($expected1, $res);
        $this->assertContains($expected2, $res);
    }

Tim van Dijen's avatar
Tim van Dijen committed

    /**
     * @return void
     */
    public function testSignMissingPrivateKey()
    {
        $node = new \DOMDocument();
        $node->loadXML('<?xml version="1.0"?><node>value</node>');
        $element = $node->getElementsByTagName("node")->item(0);

        $doc = new \DOMDocument();
        $insertInto = $doc->appendChild(new \DOMElement('insert'));

        $signer = new Signer([]);
        $this->expectException(\Exception::class);
        $signer->sign($element, $insertInto);
    }

Tim van Dijen's avatar
Tim van Dijen committed
     * @param \SimpleSAML\Configuration $service
     * @param string $className
     * @param mixed|null $value
Tim van Dijen's avatar
Tim van Dijen committed
     * @return void
     */
Tim van Dijen's avatar
Tim van Dijen committed
    protected function clearInstance(Configuration $service, $className, $value = null)
    {
        $reflectedClass = new \ReflectionClass($className);
        $reflectedInstance = $reflectedClass->getProperty('instance');
        $reflectedInstance->setAccessible(true);
        $reflectedInstance->setValue($service, $value);
        $reflectedInstance->setAccessible(false);
    }
}