/** * Construct an authnresponse and send it. * Also test setting a relaystate and destination for the response. */ public function testSendAuthnResponse() { $response = new Response(); $response->setIssuer('testIssuer'); $response->setRelayState('http://example.org'); $response->setDestination('http://example.org/login?success=yes'); $response->setSignatureKey(CertificatesMock::getPrivateKey()); $hr = new HTTPPost(); $hr->send($response); }
/** * @group Message */ public function testCorrectSignatureMethodCanBeExtractedFromResponse() { $response = new \DOMDocument(); $response->load(__DIR__ . '/Response/response.xml'); $privateKey = CertificatesMock::getPrivateKey(); $unsignedMessage = Message::fromXML($response->documentElement); $unsignedMessage->setSignatureKey($privateKey); $unsignedMessage->setCertificates(array(CertificatesMock::PUBLIC_KEY_PEM)); $signedMessage = Message::fromXML($unsignedMessage->toSignedXML()); $this->assertEquals($privateKey->getAlgorith(), $signedMessage->getSignatureMethod()); }
/** * @test * @group signature */ public function signed_message_with_valid_signature_is_validated_correctly() { $pattern = Certificate::CERTIFICATE_PATTERN; preg_match($pattern, CertificatesMock::PUBLIC_KEY_PEM, $matches); $config = new IdentityProvider(array('certificateData' => $matches[1])); $validator = new PublicKeyValidator(new SimpleTestLogger(), new KeyLoader()); $doc = DOMDocumentFactory::fromFile(__DIR__ . '/response.xml'); $response = new Response($doc->firstChild); $response->setSignatureKey(CertificatesMock::getPrivateKey()); $response->setCertificates(array(CertificatesMock::PUBLIC_KEY_PEM)); // convert to signed response $response = new Response($response->toSignedXML()); $this->assertTrue($validator->canValidate($response, $config), 'Cannot validate the element'); $this->assertTrue($validator->hasValidSignature($response, $config), 'The signature is not valid'); }
/** * @test * @group signature */ public function signed_message_with_valid_signature_is_validated_correctly() { $pattern = Certificate::CERTIFICATE_PATTERN; preg_match($pattern, CertificatesMock::PUBLIC_KEY_PEM, $matches); $certdata = X509::createFromCertificateData($matches[1]); $fingerprint = $certdata->getFingerprint(); $fingerprint_retry = $certdata->getFingerprint(); $this->assertTrue($fingerprint->equals($fingerprint_retry), 'Cached fingerprint does not match original'); $config = new IdentityProvider(array('certificateFingerprints' => array($fingerprint->getRaw()))); $validator = new FingerprintValidator(new SimpleTestLogger(), new FingerprintLoader()); $doc = DOMDocumentFactory::fromFile(__DIR__ . '/response.xml'); $response = new Response($doc->firstChild); $response->setSignatureKey(CertificatesMock::getPrivateKey()); $response->setCertificates(array(CertificatesMock::PUBLIC_KEY_PEM)); // convert to signed response $response = new Response($response->toSignedXML()); $this->assertTrue($validator->canValidate($response, $config), 'Cannot validate the element'); $this->assertTrue($validator->hasValidSignature($response, $config), 'The signature is not valid'); }
/** * Due to the fact that the symmetric key is generated each time, we cannot test whether or not the resulting XML * matches a specific XML, but we can test whether or not the resulting structure is actually correct, conveying * all information required to decrypt the NameId. */ public function testThatAnEncryptedNameIdResultsInTheCorrectXmlStructure() { // the NameID we're going to encrypt $nameId = array('Value' => md5('Arthur Dent'), 'Format' => Constants::NAMEID_ENCRYPTED); // basic AuthnRequest $request = new AuthnRequest(); $request->setIssuer('https://gateway.stepup.org/saml20/sp/metadata'); $request->setDestination('https://tiqr.stepup.org/idp/profile/saml2/Redirect/SSO'); $request->setNameId($nameId); // encrypt the NameID $key = CertificatesMock::getPublicKey(); $request->encryptNameId($key); $expectedXml = <<<AUTHNREQUEST <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="" Version="" IssueInstant="" Destination=""> <saml:Issuer></saml:Issuer> <saml:Subject> <saml:EncryptedID xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Type="http://www.w3.org/2001/04/xmlenc#Element"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> <dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <xenc:EncryptedKey> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/> <xenc:CipherData> <xenc:CipherValue></xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedKey> </dsig:KeyInfo> <xenc:CipherData> <xenc:CipherValue></xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </saml:EncryptedID> </saml:Subject> </samlp:AuthnRequest> AUTHNREQUEST; $expectedStructure = DOMDocumentFactory::fromString($expectedXml)->documentElement; $requestStructure = $request->toUnsignedXML(); $this->assertEqualXMLStructure($expectedStructure, $requestStructure); }
/** * @return \SAML2\Response */ private function getSignedResponseWithSignedAssertion() { $doc = new \DOMDocument(); $doc->load(__DIR__ . '/response.xml'); $response = new Response($doc->firstChild); $response->setSignatureKey(CertificatesMock::getPrivateKey()); $response->setCertificates(array(CertificatesMock::PUBLIC_KEY_PEM)); $assertions = $response->getAssertions(); $assertion = $assertions[0]; $assertion->setSignatureKey(CertificatesMock::getPrivateKey()); $assertion->setCertificates(array(CertificatesMock::PUBLIC_KEY_PEM)); return new Response($response->toSignedXML()); }
/** * @group Assertion */ public function testCorrectSignatureMethodCanBeExtracted() { $document = new \DOMDocument(); $document->loadXML(<<<XML <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="_93af655219464fb403b34436cfb0c5cb1d9a5502" IssueInstant="1970-01-01T01:33:31Z"> <saml:Issuer>Provider</saml:Issuer> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">s00000000:123456789</saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData NotOnOrAfter="2011-08-31T08:51:05Z" Recipient="https://sp.example.com/assertion_consumer" InResponseTo="_13603a6565a69297e9809175b052d115965121c8" /> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotOnOrAfter="2011-08-31T08:51:05Z" NotBefore="2011-08-31T08:51:05Z"> <saml:AudienceRestriction> <saml:Audience>ServiceProvider</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2011-08-31T08:51:05Z" SessionIndex="_93af655219464fb403b34436cfb0c5cb1d9a5502"> <saml:AuthnContext> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef> </saml:AuthnContext> <saml:SubjectLocality Address="127.0.0.1"/> </saml:AuthnStatement> <saml:AttributeStatement> <saml:Attribute Name="urn:ServiceID"> <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="urn:EntityConcernedID"> <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="urn:EntityConcernedSubID"> <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">1</saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> </saml:Assertion> XML ); $privateKey = CertificatesMock::getPrivateKey(); $unsignedAssertion = new Assertion($document->firstChild); $unsignedAssertion->setSignatureKey($privateKey); $unsignedAssertion->setCertificates(array(CertificatesMock::PUBLIC_KEY_PEM)); $signedAssertion = new Assertion($unsignedAssertion->toXML()); $signatureMethod = $signedAssertion->getSignatureMethod(); $this->assertEquals($privateKey->getAlgorith(), $signatureMethod); }
/** * @group certificate * * @test * @expectedException \SAML2\Exception\InvalidArgumentException */ public function test_create_with_nonstring_password_throws_exception() { $key = \SAML2\CertificatesMock::getPlainPrivateKey(); PrivateKey::create($key, 1); }
/** * @group utilities * @test */ public function testConvertToCertificate() { $result = Certificate::convertToCertificate(\SAML2\CertificatesMock::getPlainPublicKeyContents()); // the formatted public key in CertificatesMock is stored with unix newlines $this->assertEquals(\SAML2\CertificatesMock::getPlainPublicKey() . "\n", str_replace("\r", "", $result)); }
/** * Test that signatures contain the corresponding public keys. */ public function testGetValidatingCertificates() { $certData = XMLSecurityDSig::staticGet509XCerts(CertificatesMock::PUBLIC_KEY_PEM); $certData = $certData[0]; $signedMockElementCopy = Utils::copyElement($this->signedMockElement); $signedMockElementCopy->ownerDocument->appendChild($signedMockElementCopy); $tmp = new SignedElementHelperMock($signedMockElementCopy); $certs = $tmp->getValidatingCertificates(); $this->assertCount(1, $certs); $this->assertEquals($certData, $certs[0]); // Test with two certificates. $tmpCert = '-----BEGIN CERTIFICATE----- MIICsDCCAhmgAwIBAgIJALU2mjA9ULI2MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTAwODAzMDYzNTQ4WhcNMjAwODAyMDYzNTQ4WjBF MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB gQDG6q53nl3Gn/9JE+ZiCgEB+EPcGbvzi0NrBDkKz9SKBNflxKQ+De/OAVQ9RQZO tEm/j0hoSCGO7maemOm1PVNtDuMchSroPs0L4szLhh6m1uMhw9RXqq34C+Cr7Wee ZNPQTFnQhBYqnYM03/e3SeUawiZ7rGeAMJ/8BSk0CB1GAQIDAQABo4GnMIGkMB0G A1UdDgQWBBRnHHPiQ/pV/xDZg3EBmU3ik64ORDB1BgNVHSMEbjBsgBRnHHPiQ/pV /xDZg3EBmU3ik64ORKFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUt U3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJALU2mjA9 ULI2MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAScv7ee6QajoSM4c4 +fX+eYdjHFsvtqHD0ng987viS8eGjIrRfKAMHVzzs1jSU0TxMM7WUFDf6FpjW+Do r+X+X2Al/n6aDn7qAxXbl0RZuB+saxn+yFR6HFKggwkR1L2pimCuD0gTr6LlrNgf edF1YfJgq35hcMMLY9RE/0C0bCI= -----END CERTIFICATE-----'; $mock = new SignedElementHelperMock(); $mock->setSignatureKey(CertificatesMock::getPrivateKey()); $mock->setCertificates(array($tmpCert, CertificatesMock::PUBLIC_KEY_PEM)); $this->signedMockElement = $mock->toSignedXML(); $tmp = new SignedElementHelperMock($this->signedMockElement); $certs = $tmp->getValidatingCertificates(); $this->assertCount(1, $certs); $this->assertEquals($certData, $certs[0]); }
public function testTypedEncryptedAttributeValuesAreParsedCorrectly() { $xml = <<<XML <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="2.0" ID="_93af655219464fb403b34436cfb0c5cb1d9a5502" IssueInstant="1970-01-01T01:33:31Z"> <saml:Issuer>Provider</saml:Issuer> <saml:Conditions/> <saml:AttributeStatement> <saml:Attribute Name="urn:some:string"> <saml:AttributeValue xsi:type="xs:string">string</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="urn:some:integer"> <saml:AttributeValue xsi:type="xs:integer">42</saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> </saml:Assertion> XML; $privateKey = CertificatesMock::getPublicKey(); $assertion = new Assertion(DOMDocumentFactory::fromString($xml)->firstChild); $assertion->setEncryptionKey($privateKey); $assertion->setEncryptedAttributes(true); $encryptedAssertion = $assertion->toXML()->ownerDocument->saveXML(); $assertionToVerify = new Assertion(DOMDocumentFactory::fromString($encryptedAssertion)->firstChild); $this->assertTrue($assertionToVerify->hasEncryptedAttributes()); $assertionToVerify->decryptAttributes(CertificatesMock::getPrivateKey()); $attributes = $assertionToVerify->getAttributes(); $this->assertInternalType('int', $attributes['urn:some:integer'][0]); $this->assertInternalType('string', $attributes['urn:some:string'][0]); $this->assertXmlStringEqualsXmlString($xml, $assertionToVerify->toXML()->ownerDocument->saveXML()); }
/** * Test NameID Encryption and Decryption. */ public function testNameIdEncryption() { // Create an assertion $assertion = new Assertion(); $assertion->setIssuer('testIssuer'); $assertion->setValidAudiences(array('audience1', 'audience2')); $assertion->setAuthnContext('someAuthnContext'); $assertion->setNameId(array("Value" => "just_a_basic_identifier", "Format" => "urn:oasis:names:tc:SAML:2.0:nameid-format:transient")); $this->assertFalse($assertion->isNameIdEncrypted()); $publicKey = CertificatesMock::getPublicKey(); $assertion->encryptNameId($publicKey); $this->assertTrue($assertion->isNameIdEncrypted()); // Marshall it to a \DOMElement $assertionElement = $assertion->toXML()->ownerDocument->saveXML(); $assertionToVerify = new Assertion(DOMDocumentFactory::fromString($assertionElement)->firstChild); $this->assertTrue($assertionToVerify->isNameIdEncrypted()); $privateKey = CertificatesMock::getPrivateKey(); $assertionToVerify->decryptNameId($privateKey); $this->assertFalse($assertionToVerify->isNameIdEncrypted()); $nameID = $assertionToVerify->getNameID(); $this->assertEquals('just_a_basic_identifier', $nameID['Value']); $this->assertEquals('urn:oasis:names:tc:SAML:2.0:nameid-format:transient', $nameID['Format']); }