diff --git a/lib/SimpleSAML/XML/Signer.php b/lib/SimpleSAML/XML/Signer.php
index b9bb9fce8b2477a1d0a5ec877e624b4a17451f0a..42ddfa350bb4ee9ec5b672b3e3b2c9b14b381151 100644
--- a/lib/SimpleSAML/XML/Signer.php
+++ b/lib/SimpleSAML/XML/Signer.php
@@ -123,14 +123,22 @@ class Signer
      *                      to the cert-directory.
      * @param string|null $pass  The passphrase on the private key. Pass no value or NULL if the private
      *                           key is unencrypted.
+     * @param bool $full_path  Whether the filename found in the configuration contains the
+     *                         full path to the private key or not. Default to false.
      * @throws \Exception
      */
-    public function loadPrivateKey($file, $pass = null)
+    public function loadPrivateKey($file, $pass = null, $full_path = false)
     {
         assert('is_string($file)');
         assert('is_string($pass) || is_null($pass)');
+        assert('is_bool($full_path)');
+
+        if (!$full_path) {
+            $keyFile = Config::getCertPath($file);
+        } else {
+            $keyFile = $file;
+        }
 
-        $keyFile = Config::getCertPath($file);
         if (!file_exists($keyFile)) {
             throw new \Exception('Could not find private key file "' . $keyFile . '".');
         }
@@ -178,13 +186,21 @@ class Signer
      *
      * @param string $file  The file which contains the certificate. The path is assumed to be relative to
      *                      the cert-directory.
+     * @param bool $full_path  Whether the filename found in the configuration contains the
+     *                         full path to the private key or not. Default to false.
      * @throws \Exception
      */
-    public function loadCertificate($file)
+    public function loadCertificate($file, $full_path = false)
     {
         assert('is_string($file)');
+        assert('is_bool($full_path)');
+
+        if (!$full_path) {
+            $certFile = Config::getCertPath($file);
+        } else {
+            $certFile = $file;
+        }
 
-        $certFile = Config::getCertPath($file);
         if (!file_exists($certFile)) {
             throw new \Exception('Could not find certificate file "' . $certFile . '".');
         }
@@ -216,13 +232,21 @@ class Signer
      * are added.
      *
      * @param string $file  The file which contains the certificate, relative to the cert-directory.
+     * @param bool $full_path  Whether the filename found in the configuration contains the
+     *                         full path to the private key or not. Default to false.
      * @throws \Exception
      */
-    public function addCertificate($file)
+    public function addCertificate($file, $full_path = false)
     {
         assert('is_string($file)');
+        assert('is_bool($full_path)');
+
+        if (!$full_path) {
+            $certFile = Config::getCertPath($file);
+        } else {
+            $certFile = $file;
+        }
 
-        $certFile = Config::getCertPath($file);
         if (!file_exists($certFile)) {
             throw new \Exception('Could not find extra certificate file "' . $certFile . '".');
         }
@@ -268,9 +292,12 @@ class Signer
             $options['id_name'] = $this->idAttrName;
         }
 
-        $objXMLSecDSig->addReferenceList(array($node), XMLSecurityDSig::SHA1,
+        $objXMLSecDSig->addReferenceList(
+            array($node),
+            XMLSecurityDSig::SHA1,
             array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
-            $options);
+            $options
+        );
 
         $objXMLSecDSig->sign($this->privateKey);
 
diff --git a/tests/lib/SimpleSAML/XML/SignerTest.php b/tests/lib/SimpleSAML/XML/SignerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..359836b8b8d6b6a2dfec24751a011621f011c68e
--- /dev/null
+++ b/tests/lib/SimpleSAML/XML/SignerTest.php
@@ -0,0 +1,239 @@
+<?php
+
+namespace SimpleSAML\Test\Utils;
+
+use \SimpleSAML_Configuration as Configuration;
+use \SimpleSAML\XML\Signer;
+
+use \org\bovigo\vfs\vfsStream;
+
+/**
+ * Tests for SimpleSAML\XML\Signer.
+ */
+class SignerTest extends \PHPUnit_Framework_TestCase
+{
+    // openssl genrsa -out private.pem 2048
+    private $private_key = <<<'NOWDOC'
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA5LoQYYPfKdHnSnuXI+SiHfUd648Ub0sn2YO81rmnwJ168Ol/
+FZODrGpm8tsRUTz5R9uXXSnwhnWwVJW4ckiZORcp1bEUGI0zXYR387yF3Ih87UFV
+KdqodrDXNN6Id7Xrw65AVa4gjwLN2DNBF3JnjbH7zKtnqhb7u2Qer7Lidhvw4WxY
+lC9t8c+Kv3xoJOgDvlG1gRaYTZv7pxTpBA7W1YnJpOj3xiXetVmAxRcGyB0Jc8aB
+nc1WoUBGudSvjvuc01kJ+rurjgklGEFjVP9AjPfcVkdcFTXc+ECets++AmZc/kk4
+Y6RKCn3fOJlL5L0RxVSJ8obnBcS7H4rZYordfwIDAQABAoIBAH364cTkPompPIyw
+0AmMB6MafFVfZHD8Y0GSJvPaJESaOLny0fWPX4oavQNsl/g37lGe6Jr+26Ujs3CT
+WplP1V01new+cYQoWa9bpDoSj2RtpOmE/6Ri9EETnCVZoK7W+7m3A2Zt1y8N61T2
+vhZtBA5uhvMvQZTUvehz99bsX4GPTUilYHCPEq4IPkfhCMGigv/c0lWtFQhOoNUF
+BjZHezH4Z/qQolIaHpzFZT0K0e7VD4gomBegGsIqPuEJ0gProCjULqA0O5QT4gQX
+IT52pUJuU0061d4JOfDcgDI3NT2SmBBMfig71n/R88eMn0azWKN4rn4/3QjxRW3q
+tdjL0UECgYEA/ynTXtuL7G5zOezKirakuSlSbHu/3TJ+tdG5p7WOLqWADUzgqss+
+k7rxxFUxw40dBpC0LfYP5YMhXi4cBiNoT5EWhT53x/UxCilXHuz5uYcrt/Wyaqa0
+mZuyIPYuw/yTASEBUE/sE1DU82PD3IlkPmqfgEyW6j8CVyLqo/LxMWECgYEA5XoM
+aVB5jhYk8jxy0APWn4jSTm2zpTBZpzHmqTPL19B4Es18XoU+ehWA8rWGQFFwbl1f
+TTUBE1hlS9MgMMI8MK6S1Qrhi7mVrHuMaMbp0ilwDBjv+4DSqlDGDoCSLCLrDkkl
+c0uDLLFGHkfDjNmk3uiSxPZvrUiVVuwJYLGNGt8CgYEAyvjWbsptz7E8b4Nwyk7n
+UXMRYcI+qRIVwUQHTuUZKPn1lp7kyHfMW2+GCgtK/qctw58v9K+bjZJ15JkBKdDY
+lRJwu6UpWyIr1E12Q9919qMTn84OEtBxMQ+s7pNmN/ieZ3N9vAkXXXYbL1DY6IFS
+AGSIZGKIWeWtUusvgyMpwYECgYEArGDIHfxTs0YzLrv1ywh3GpQe1sdVYUs2rX+w
+s32zLETvTcCKIj6ZNgAdQzTUyk/i0yTUyBx+2FdYkGLiFX5y1Gbu6ZYo41rfchfE
+25hAYJy8DHpXG2gj18ihXpd6NilsxOhxd3BL8zCfaXOjE5USYlf2mHo+Xb7eX9Mj
+ID1/r6UCgYBos8plM27v5BzI8gghUlkFAFLmmccJXQHCUlUhT1+d8FTMEhTZGjZk
+94a7cc/ps+6UCp6hOqJ2d6w+cfteWZWP0zMcoxr2JAO9lYekIlUafoZ+mhJCCqoC
+ENg4/K7BqpAlRzCf28gUiL53wOut2CadGIoSvj0UR/Mh2eM64jTgSQ==
+-----END RSA PRIVATE KEY-----
+NOWDOC;
+
+    // openssl req -new -x509 -key private.pem -out public1.pem -days 3650
+    private $certificate1 = <<<'NOWDOC'
+-----BEGIN CERTIFICATE-----
+MIIDXTCCAkWgAwIBAgIJAIonjtIRUcfJMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTcwNjE1MTcyMTI4WhcNMjcwNjEzMTcyMTI4WjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA5LoQYYPfKdHnSnuXI+SiHfUd648Ub0sn2YO81rmnwJ168Ol/FZODrGpm
+8tsRUTz5R9uXXSnwhnWwVJW4ckiZORcp1bEUGI0zXYR387yF3Ih87UFVKdqodrDX
+NN6Id7Xrw65AVa4gjwLN2DNBF3JnjbH7zKtnqhb7u2Qer7Lidhvw4WxYlC9t8c+K
+v3xoJOgDvlG1gRaYTZv7pxTpBA7W1YnJpOj3xiXetVmAxRcGyB0Jc8aBnc1WoUBG
+udSvjvuc01kJ+rurjgklGEFjVP9AjPfcVkdcFTXc+ECets++AmZc/kk4Y6RKCn3f
+OJlL5L0RxVSJ8obnBcS7H4rZYordfwIDAQABo1AwTjAdBgNVHQ4EFgQUZHjC+k2X
+pMchyKojQngj5zOsZacwHwYDVR0jBBgwFoAUZHjC+k2XpMchyKojQngj5zOsZacw
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAETjO0RltSYxFdxmIqVIg
+7N6yKptUr46YkWY877HWmCLExHwFLTvewUvbgx7ASYA0YMErnAaVrT9IqCDbOUF+
+RCBovVuiAwwKcvag0C8nKg7rfx7KDr2E8vVV+2WzSpDECtLrpTmrPaje8TlFv8NW
+hMk80osVxnGmI7UewiMzfpRuA4tEKFxHhoQG5LVinWRTMKw6EYmrSKGLdQt/27zj
+xDe0oOS2DDIYbU/oWCqLtlTlzVqrNM7ig9HKcT0Xxgf5rwTDDzNf/dpM/Nt8DWFY
+YmLDnUolf8d/M/kglX1x5IRSN+GxTCgV8i6dIF9EPtBW/AfMz99ojmW+WOgfOLnm
+vg==
+-----END CERTIFICATE-----
+NOWDOC;
+
+    // openssl req -new -x509 -key private.pem -out public2.pem -days 3650
+    private $certificate2 = <<<'NOWDOC'
+-----BEGIN CERTIFICATE-----
+MIIDXTCCAkWgAwIBAgIJAJ6gIIeYjdQSMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTcwNjE1MTcyMTM0WhcNMjcwNjEzMTcyMTM0WjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA5LoQYYPfKdHnSnuXI+SiHfUd648Ub0sn2YO81rmnwJ168Ol/FZODrGpm
+8tsRUTz5R9uXXSnwhnWwVJW4ckiZORcp1bEUGI0zXYR387yF3Ih87UFVKdqodrDX
+NN6Id7Xrw65AVa4gjwLN2DNBF3JnjbH7zKtnqhb7u2Qer7Lidhvw4WxYlC9t8c+K
+v3xoJOgDvlG1gRaYTZv7pxTpBA7W1YnJpOj3xiXetVmAxRcGyB0Jc8aBnc1WoUBG
+udSvjvuc01kJ+rurjgklGEFjVP9AjPfcVkdcFTXc+ECets++AmZc/kk4Y6RKCn3f
+OJlL5L0RxVSJ8obnBcS7H4rZYordfwIDAQABo1AwTjAdBgNVHQ4EFgQUZHjC+k2X
+pMchyKojQngj5zOsZacwHwYDVR0jBBgwFoAUZHjC+k2XpMchyKojQngj5zOsZacw
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEA1CqpKLeYLkgRym2qeMhU
+5lKlXAYX5b0eM2SOCCjfpEnRqp2PTU/E83H0MOY6i47OfHp3LKNUj4Kze2DD+S6A
+llpmLfuLXZ/CB19sByzMrcEyUQo4mfqvKyzLhUTgygGczyocwRRZgnw1e+VwMtpf
+mgXnldomDT8CUsM2v3Xb52+JPGSCs16lRYZkgDCQEpHU4+VQxwGAGpj13NM+sidR
+ymj443jgpF6XUviaGiaS292rXMO/tW7veA1UZ2/eTKu5PF9RqDmYLiGatY1qp4tr
+QjBeEjMtDCs9Rqaety/UIaL4ZfOKffLKsKb2mjM/ew+QTwTLDg9RVv5vv2jbZrw7
+Nw==
+-----END CERTIFICATE-----
+NOWDOC;
+
+    const ROOTDIRNAME = 'testdir';
+    const DEFAULTCERTDIR = 'certdir';
+    const PRIVATEKEY = 'privatekey.pem';
+    const CERTIFICATE1 = 'certificate1.pem';
+    const CERTIFICATE2 = 'certificate2.pem';
+
+    public function setUp()
+    {
+        $this->root = vfsStream::setup(
+            self::ROOTDIRNAME,
+            null,
+            array(
+                self::DEFAULTCERTDIR => array(
+                    self::PRIVATEKEY => $this->private_key,
+                    self::CERTIFICATE1 => $this->certificate1,
+                    self::CERTIFICATE2 => $this->certificate2,
+                ),
+            )
+        );
+        $this->root_directory = vfsStream::url(self::ROOTDIRNAME);
+
+        $this->certdir = $this->root_directory.DIRECTORY_SEPARATOR.self::DEFAULTCERTDIR;
+        $this->privatekey_file = $this->certdir.DIRECTORY_SEPARATOR.self::PRIVATEKEY;
+        $this->certificate_file1 = $this->certdir.DIRECTORY_SEPARATOR.self::CERTIFICATE1;
+        $this->certificate_file2 = $this->certdir.DIRECTORY_SEPARATOR.self::CERTIFICATE2;
+
+        $this->config = Configuration::loadFromArray(array(
+            'certdir' => $this->certdir,
+        ), '[ARRAY]', 'simplesaml');
+    }
+
+    public function tearDown()
+    {
+        $this->clearInstance($this->config, '\SimpleSAML_Configuration', array());
+    }
+
+    public function testSignerBasic()
+    {
+        $res = new Signer(array());
+
+        $this->assertNotNull($res);
+    }
+
+    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(array());
+        $signer->loadPrivateKey($this->privatekey_file, null, true);
+        $signer->sign($element, $insertInto);
+
+        $res = $doc->saveXML();
+
+        $this->assertContains('DigestValue', $res);
+        $this->assertContains('SignatureValue', $res);
+    }
+
+    private static function getCertificateValue($certificate)
+    {
+        $replacements = array(
+            "-----BEGIN CERTIFICATE-----",
+            "-----END CERTIFICATE-----",
+            "\n",
+        );
+
+        return str_replace($replacements, "", $certificate);
+    }
+
+    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(array());
+        $signer->loadPrivateKey($this->privatekey_file, null, true);
+        $signer->loadCertificate($this->certificate_file1, true);
+        $signer->sign($element, $insertInto);
+
+        $res = $doc->saveXML();
+
+        $expected = self::getCertificateValue($this->certificate1);
+
+        $this->assertContains('X509Certificate', $res);
+        $this->assertContains($expected, $res);
+    }
+
+    public function testSignWithMultiCertificate()
+    {
+        $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(array());
+        $signer->loadPrivateKey($this->privatekey_file, null, true);
+        $signer->loadCertificate($this->certificate_file1, true);
+        $signer->addCertificate($this->certificate_file2, true);
+        $signer->sign($element, $insertInto);
+
+        $res = $doc->saveXML();
+
+        $expected1 = self::getCertificateValue($this->certificate1);
+        $expected2 = self::getCertificateValue($this->certificate2);
+
+        $this->assertContains('X509Certificate', $res);
+        $this->assertContains($expected1, $res);
+        $this->assertContains($expected2, $res);
+    }
+
+    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(array());
+
+        $this->setExpectedException('\Exception');
+        $signer->sign($element, $insertInto);
+    }
+
+    protected function clearInstance($service, $className, $value = null)
+    {
+        $reflectedClass = new \ReflectionClass($className);
+        $reflectedInstance = $reflectedClass->getProperty('instance');
+        $reflectedInstance->setAccessible(true);
+        $reflectedInstance->setValue($service, $value);
+        $reflectedInstance->setAccessible(false);
+    }
+}
diff --git a/tests/modules/consent/lib/Auth/Process/ConsentTest.php b/tests/modules/consent/lib/Auth/Process/ConsentTest.php
index ce864179fa61a549feccf4d54f9b0962a99ce0ef..e83659d22e054db22ba453e60a5372ac2af2f56b 100644
--- a/tests/modules/consent/lib/Auth/Process/ConsentTest.php
+++ b/tests/modules/consent/lib/Auth/Process/ConsentTest.php
@@ -8,8 +8,14 @@
 
 namespace SimpleSAML\Test\Module\consent\Auth\Process;
 
+use \SimpleSAML_Configuration as Configuration;
+
 class ConsentTest extends \PHPUnit_Framework_TestCase
 {
+    public function setUp()
+    {
+        $this->config = Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
+    }
 
     /**
      * Helper function to run the filter with a given configuration.
diff --git a/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php b/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php
index c88def979a42701ebf2d72897652af67edad1058..bb3d065db979d757aa9a474c55706ade050578c3 100644
--- a/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php
+++ b/tests/modules/saml/lib/Auth/Source/Auth_Source_SP_Test.php
@@ -2,6 +2,8 @@
 
 namespace SimpleSAML\Test\Module\saml\Auth\Source;
 
+use \SimpleSAML_Configuration as Configuration;
+
 /**
  * Custom Exception to throw to terminate a TestCase.
  */
@@ -121,6 +123,8 @@ class SP_Test extends \PHPUnit_Framework_TestCase
                 ),
             ),
         );
+
+        $this->config = Configuration::loadFromArray(array(), '[ARRAY]', 'simplesaml');
     }