public function test__signed_serialize_deserialize() { $certificate = new X509Certificate(); $certificate->loadFromFile(__DIR__ . '/../../../../../../web/sp/saml.crt'); $privateKey = KeyHelper::createPrivateKey(__DIR__ . '/../../../../../../web/sp/saml.key', null, true); $authnRequest = new AuthnRequest(); $authnRequest->setID('_894da3368874d2dd637983b6812f66c444f100f205'); $authnRequest->setIssueInstant('2015-09-13T11:47:33Z'); $authnRequest->setDestination('https://idp.testshib.org/idp/profile/SAML2/POST/SSO'); $authnRequest->setIssuer((new Issuer())->setValue('https://mt.evo.loc/sp')->setFormat('urn:oasis:names:tc:SAML:2.0:nameid-format:entity')); $authnRequest->setSignature(new SignatureWriter($certificate, $privateKey)); $serializationContext = new SerializationContext(); $authnRequest->serialize($serializationContext->getDocument(), $serializationContext); $temporaryFilename = tempnam(sys_get_temp_dir(), 'lightsaml-'); $serializationContext->getDocument()->save($temporaryFilename); $xml = file_get_contents($temporaryFilename); $deserializationContext = new DeserializationContext(); $deserializationContext->getDocument()->loadXML($xml); $authnRequest = new AuthnRequest(); $authnRequest->deserialize($deserializationContext->getDocument()->firstChild, $deserializationContext); $signatureReader = $authnRequest->getSignature(); if ($signatureReader instanceof SignatureXmlReader) { $certificate = new X509Certificate(); $certificate->loadFromFile(__DIR__ . '/../../../../../../web/sp/saml.crt'); $key = KeyHelper::createPublicKey($certificate); $ok = $signatureReader->validate($key); $this->assertTrue($ok); } else { throw new \LogicException('Expected Signature Xml Reader'); } }
public function test_deserialize_response01() { $context = new DeserializationContext(); $context->getDocument()->load(__DIR__ . '/../../../../../../resources/sample/Response/response01.xml'); $response = new Response(); $response->deserialize($context->getDocument(), $context); $this->assertEquals('_c34b38b9-5da6-4ee8-af49-2af20423d8f5', $response->getID()); $this->assertEquals('2.0', $response->getVersion()); $this->assertEquals('2013-10-27T11:55:37Z', $response->getIssueInstantString()); $this->assertEquals('https://mt.evo.team/simplesaml/module.php/saml/sp/saml2-acs.php/b1', $response->getDestination()); $this->assertEquals(SamlConstants::CONSENT_UNSPECIFIED, $response->getConsent()); $this->assertEquals('_513cb532f91881ffdcf054a573826f831cc1603241', $response->getInResponseTo()); $this->assertNotNull($response->getIssuer()); $this->assertEquals('https://B1.bead.loc/adfs/services/trust', $response->getIssuer()->getValue()); $this->assertNotNull($response->getStatus()); $this->assertEquals(SamlConstants::STATUS_SUCCESS, $response->getStatus()->getStatusCode()->getValue()); $this->assertCount(1, $response->getAllAssertions()); $as = $response->getFirstAssertion(); $this->assertNotNull($as); $this->assertEquals('_3ba23925-e43d-4c98-ac99-a05dce99d505', $as->getId()); $this->assertEquals('2013-10-27T11:55:37Z', $as->getIssueInstantString()); $this->assertEquals('2.0', $as->getVersion()); $this->assertNotNull($as->getIssuer()); $this->assertEquals('https://B1.bead.loc/adfs/services/trust', $as->getIssuer()->getValue()); $this->assertNotNull($as->getSubject()); $this->assertEquals(SamlConstants::NAME_ID_FORMAT_TRANSIENT, $as->getSubject()->getNameID()->getFormat()); $this->assertEquals('*****@*****.**', $as->getSubject()->getNameID()->getValue()); $this->assertCount(1, $as->getSubject()->getAllSubjectConfirmations()); $sc = $as->getSubject()->getFirstSubjectConfirmation(); $this->assertEquals(SamlConstants::CONFIRMATION_METHOD_BEARER, $sc->getMethod()); $this->assertEquals('_513cb532f91881ffdcf054a573826f831cc1603241', $sc->getSubjectConfirmationData()->getInResponseTo()); $this->assertEquals('2013-10-27T12:00:37Z', $sc->getSubjectConfirmationData()->getNotOnOrAfterString()); $this->assertEquals('https://mt.evo.team/simplesaml/module.php/saml/sp/saml2-acs.php/b1', $sc->getSubjectConfirmationData()->getRecipient()); $this->assertNotNull($as->getConditions()); $this->assertEquals('2013-10-27T11:55:37Z', $as->getConditions()->getNotBeforeString()); $this->assertEquals('2013-10-27T12:55:37Z', $as->getConditions()->getNotOnOrAfterString()); $this->assertCount(1, $as->getConditions()->getFirstAudienceRestriction()->getAllAudience()); $this->assertTrue($as->getConditions()->getFirstAudienceRestriction()->hasAudience('https://mt.evo.team/simplesaml/module.php/saml/sp/metadata.php/b1')); $this->assertCount(1, $as->getFirstAttributeStatement()->getAllAttributes()); $attr = $as->getFirstAttributeStatement()->getFirstAttributeByName(ClaimTypes::COMMON_NAME); $this->assertNotNull($attr); $this->assertEquals(ClaimTypes::COMMON_NAME, $attr->getName()); $this->assertCount(1, $attr->getAllAttributeValues()); $this->assertEquals('*****@*****.**', $attr->getFirstAttributeValue()); $this->assertEquals('2013-10-27T11:55:36Z', $as->getFirstAuthnStatement()->getAuthnInstantString()); $this->assertEquals('_3ba23925-e43d-4c98-ac99-a05dce99d505', $as->getFirstAuthnStatement()->getSessionIndex()); $this->assertEquals(SamlConstants::AUTHN_CONTEXT_WINDOWS, $as->getFirstAuthnStatement()->getAuthnContext()->getAuthnContextClassRef()); $this->assertNotNull($as->getSignature()); /** @var SignatureXmlReader $sig */ $sig = $as->getSignature(); $this->assertInstanceOf('LightSaml\\Model\\XmlDSig\\SignatureXmlReader', $sig); $arrCertificates = $sig->getAllCertificates(); $this->assertCount(1, $arrCertificates); $certificate = (new X509Certificate())->setData($arrCertificates[0]); $sig->validate(KeyHelper::createPublicKey($certificate)); }
/** * @param X509Certificate $certificate * @param XMLSecurityKey $privateKey */ public function __construct(X509Certificate $certificate, XMLSecurityKey $privateKey = null) { parent::__construct(); $this->certificate = $certificate; $this->setPublicKey(KeyHelper::createPublicKey($certificate)); $this->setKeyNames(array($this->getCertificate()->getName())); if ($privateKey) { $this->setPrivateKey($privateKey); } }
public function test_validate_correct_signature() { $publicKey = KeyHelper::createPublicKey(X509Certificate::fromFile(__DIR__ . '/../../../../../resources/sample/Certificate/saml.crt')); $privateKey = KeyHelper::createPrivateKey(__DIR__ . '/../../../../../resources/sample/Certificate/saml.pem', '', true); $data = 'Some message data'; $signature = base64_encode($privateKey->signData($data)); $reader = new SignatureStringReader($signature, $publicKey->type, $data); $result = $reader->validate($publicKey); $this->assertTrue($result); }
/** * @param AuthnRequest $message * @throws Exception */ private function validateSignature(AuthnRequest $message) { $key = KeyHelper::createPublicKey(X509Certificate::fromFile($this->saml_crt)); /** @var SignatureStringReader $signature_reader */ $signature_reader = $message->getSignature(); try { if ($signature_reader->validate($key)) { return; } throw new Exception('Signature not validated'); } catch (Exception $e) { if ($this->logger) { $this->logger->error("AuthnRequest validation failed with message {$e->getMessage()}.", ['exception' => $e]); } throw $e; } }
/** * @param string $xml * @param string $class */ private function deserializeAndVerify($xml, $class) { $deserializationContext = new DeserializationContext(); $deserializationContext->getDocument()->loadXML($xml); /** @var SamlMessage $samlMessage */ $samlMessage = new $class(); $samlMessage->deserialize($deserializationContext->getDocument(), $deserializationContext); /** @var AbstractSignatureReader $signatureReader */ $signatureReader = $samlMessage->getSignature(); $ok = $signatureReader->validate(KeyHelper::createPublicKey($this->getCertificate())); $this->assertTrue($ok); }
<?php require_once __DIR__ . '/../autoload.php'; $xml = <<<EOT <?xml version="1.0"?> <AuthnRequest xmlns="urn:oasis:names:tc:SAML:2.0:protocol" ID="_894da3368874d2dd637983b6812f66c444f100f205" Version="2.0" IssueInstant="2015-09-13T11:47:33Z" Destination="https://idp.testshib.org/idp/profile/SAML2/POST/SSO"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">https://mt.evo.loc/sp</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/> <ds:Reference URI="#_894da3368874d2dd637983b6812f66c444f100f205"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>94dChUrRo35DfipIGNBVil4Qip8=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>rjtDDEZN4T2L4Xw5W5ijALoambKl85HsBGy/pFlmk6b7JqSVq8wJJkrq6D5nxUPzNf7B+L2wju1M98stmUhvYCtU2cHRE6wjKwa7tsumYDxuOBQ4ufBt09TJtjogny5ikzCtb2csOoQjosExmVw3f2J+FkLl4rjY6Ngwlsnpn0AttqNdtykAdwuIE3BmXKhMTxelPhxMZ9bCOoODlgU568E+3KuOxmcf85e+uGIApuxnzTZX62MlnVtsveMQdb0VT4AKJhVbFIb7sW+UwMQWhznWhjdnhIz65CHTnBUMzLyOilugwE5Rvk79fPqeGDNrNyeh+3Fhko+GAj0lNluyWA==</ds:SignatureValue> <ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIDyjCCArKgAwIBAgIJANZLMiMszO+tMA0GCSqGSIb3DQEBBQUAMEwxCzAJBgNVBAYTAlJTMREwDwYDVQQIEwhCZWxncmFkZTESMBAGA1UEChMJTGlnaHRTQU1MMRYwFAYDVQQDEw1saWdodHNhbWwuY29tMB4XDTE1MDkxMzE4MzU0NloXDTI1MDkxMDE4MzU0NlowTDELMAkGA1UEBhMCUlMxETAPBgNVBAgTCEJlbGdyYWRlMRIwEAYDVQQKEwlMaWdodFNBTUwxFjAUBgNVBAMTDWxpZ2h0c2FtbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7pUKOPMyE2oScHLPGJFTepK9j1H03e/s/WnONw8ZwYBaBIYIQuX6uE8jFPdD0uQSaYpOw5h5Tgq6xBV7m2kPO53hs8gEGWRbCdCtxi9EMJwIOYr+isG0N+DvV9KybJf6tqcM50PiFjVNtfx8IubMpAKCbquaqdLaHH0rgP1hbgnGm5YZkyEK4s8xuLUDS6qL7N7a/ez2Zk45u3L3qFcuncPI5BTnJg6fqlypDhCDOBI5Ljw10HmgZHPIXzOhEPVV+rX2iHhF4V9vzEoeIUABYXQVNRRNHpPdVsK6iTTkyvbrGJ/tv3oFZhNOSL0Kuy+Q9nlE9fEFqyUydJ67vsXqZAgMBAAGjga4wgaswHQYDVR0OBBYEFHPT6Ey1qgxMzMIt2d3OWuwzfPSUMHwGA1UdIwR1MHOAFHPT6Ey1qgxMzMIt2d3OWuwzfPSUoVCkTjBMMQswCQYDVQQGEwJSUzERMA8GA1UECBMIQmVsZ3JhZGUxEjAQBgNVBAoTCUxpZ2h0U0FNTDEWMBQGA1UEAxMNbGlnaHRzYW1sLmNvbYIJANZLMiMszO+tMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAE0HxNZpi/gSVrkhQ756AgIC25l6A4C6xZ8iAZiBApJcVdUZytBgpzypFSd8yg7Yh5P3ftlDjYEMB/uIvBsKe6HQyUy90VrSi4aaGC/7ilj6DTCX3jeuuH1JnU6sBxhN9IiJRY3DbMzY5KAdtK/1fYlKa6PugXruJWrB3bC1VaFWLjMytnvaEQxjam4bsj1sF0+v6jL3RIQzdW9jJ7Udoul5fGR56A0Uhi0lqObPKI2lIK1psWXLwksdvO9NNt9Vm27QLlklvpYuIh086wLmbiVmO+VQxDYwPmL8NEiLSA4Po/q7n+qV7Vx/EtIKr7lwZ2Micv5Xm0sequAbt3dnqPI=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature></AuthnRequest> EOT; $deserializationContext = new \LightSaml\Model\Context\DeserializationContext(); $deserializationContext->getDocument()->loadXML($xml); $authnRequest = new \LightSaml\Model\Protocol\AuthnRequest(); $authnRequest->deserialize($deserializationContext->getDocument()->firstChild, $deserializationContext); $key = \LightSaml\Credential\KeyHelper::createPublicKey(\LightSaml\Credential\X509Certificate::fromFile(__DIR__ . '/../web/sp/saml.crt')); /** @var \LightSaml\Model\XmlDSig\SignatureXmlReader $signatureReader */ $signatureReader = $authnRequest->getSignature(); try { $ok = $signatureReader->validate($key); if ($ok) { print "Signaure OK\n"; } else { print "Signature not validated"; } } catch (\Exception $ex) { print "Signature validation failed\n"; }