Hallo Community
ich möchte als Service Provider SD ein SAML 2.0 basiertes Single Sign On POST validieren.
Ich benutze dazu das MDSignature.php von wayf
MDSignature.php - wayf - Modules for SimleSAMLphp - Google Project Hosting
Der Identity Provider IdP schickt mir folgendes POST SAML XML
(Daten wurden hier zur Demo geändert)
das ist mein parsing und validation Script
Leider erhalte ich eine Fehlermeldung:
error:04077077:rsa routines:RSA_verify:wrong signature length
hervorgerufen durch openssl_verify($signedInfo, $signatureValue, $publicKey)
auch habe ich festgestellt, dass
(sha1($canonicalXml, true) == $digestValue) nicht zutrifft!
Bin für jede Hilfe dankbar.
ich möchte als Service Provider SD ein SAML 2.0 basiertes Single Sign On POST validieren.
Ich benutze dazu das MDSignature.php von wayf
MDSignature.php - wayf - Modules for SimleSAMLphp - Google Project Hosting
Der Identity Provider IdP schickt mir folgendes POST SAML XML
(Daten wurden hier zur Demo geändert)
Code:
<urn:Response Version="2.0" ID="GHyqorU1JNJOvvhdoG5uG0y.GfP" IssueInstant="2013-11-27T06:48:22.737Z" Destination="[URL]http://www.mydomain.com/saml_login.php[/URL]" xmlns:urn="urn:oasis:names:tc:SAML:2.0:protocol"> <urn1:Issuer xmlns:urn1="urn:oasis:names:tc:SAML:2.0:assertion">ehi:SAML2:SULTest</urn1:Issuer> <ds:Signature xmlns:ds="[URL]http://www.w3.org/2000/09/xmldsig#[/URL]"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="[URL="http://www.w3.org/2001/10/xml-exc-c14n#"]Exclusive XML Canonicalization Version 1.0[/URL]"/> <ds:SignatureMethod Algorithm="[URL]http://www.w3.org/2000/09/xmldsig#rsa-sha1[/URL]"/> <ds:Reference URI="#OHyqorU1SZZHvvhdoG3uG0x.GfP"> <ds:Transforms> <ds:Transform Algorithm="[URL]http://www.w3.org/2000/09/xmldsig#enveloped-signature[/URL]"/> <ds:Transform Algorithm="[URL="http://www.w3.org/2001/10/xml-exc-c14n#"]Exclusive XML Canonicalization Version 1.0[/URL]"/> </ds:Transforms> <ds:DigestMethod Algorithm="[URL]http://www.w3.org/2000/09/xmldsig#sha1[/URL]"/> <ds:DigestValue>i4r2MWuclHc1Qfdeu5y2dxcEZ5A=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue> X50S98UvtKZsiHN+YLbWA4Meuecvdana+Kcqu5f9YhnWaGkvjeIv3cx49zOSdjUKh8W+iQ3VoZkW u6to8r/Tzmryd22LkFdzgNnaoX0ecW+vvBLQ6ueOESZ+OVCYZQ4tA/DhNkI48212brBndanUQjr5 9W6S4ncRsphFBzNcZOtyJo+54WxhVbdfsKYYkCy9maEKjgErLnh+q6UO64X0/TuqrhevD8zQvop8 tQNoT47FUUV/zdO15tSDabRxgruWf3W0zrisFvbPPkXg2hEMjy77VcWDvEl0HE7jEa6fBz2VK4wR DHl3fJHsOK3vZubcAqF3RnfiigB8F6rPpz1ZiQ== </ds:SignatureValue> </ds:Signature> <urn:Status> <urn:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></urn:Status> <saml:Assertion ID="wsCAE-fOQ_JKs8HuyLFFdFZEXfQ" IssueInstant="2013-11-27T06:48:23.034Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"> <saml:Issuer>ehi:SAML2:SULTest</saml:Issuer> <saml:Subject> <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">e454k3</saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData Recipient="[URL]http://www.mydomain.com/saml_login.php[/URL]" NotOnOrAfter="2013-11-27T06:53:23.065Z"/></saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2013-11-27T06:43:23.065Z" NotOnOrAfter="2013-11-27T06:53:23.065Z"> <saml:AudienceRestriction><saml:Audience>VendorDemo</saml:Audience></saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement SessionIndex="pqCER-fOQ_QLd8HuyLFFdFZEXfQ" AuthnInstant="2013-11-27T06:48:23.018Z"> <saml:AuthnContext> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> </saml:Assertion> </urn:Response>
PHP-Code:
class MDSignature
{
public static function verifySignature($xml, $certificate)
{
$dom = new \DOMDocument();
$dom->preserveWhiteSpace = true;
$dom->loadXML($xml);
$context = $dom->documentElement;
// Register XPath object
$xpath = new \DOMXPath($dom);
// Register namespaces
$namespaces = array(
'md' => 'urn:oasis:names:tc:SAML:2.0:metadata',
'ds' => 'http://www.w3.org/2000/09/xmldsig#',
'shibmd' => 'urn:mace:shibboleth:metadata:1.0',
'ec' => 'http://www.w3.org/2001/10/xml-exc-c14n#',
);
foreach ($namespaces AS $key => $value) {
$xpath->registerNamespace($key, $value);
}
// Get signature and digest value
$signatureValue = base64_decode($xpath->query('ds:Signature[1]/ds:SignatureValue[1]', $context)->item(0)->textContent);
$digestValue = base64_decode($xpath->query('ds:Signature[1]/ds:SignedInfo[1]/ds:Reference[1]/ds:DigestValue[1]', $context)->item(0)->textContent);
$id = $xpath->query('@ID', $context)->item(0)->value;
$signedElement = $context;
$signature = $xpath->query("ds:Signature[1]", $signedElement)->item(0);
$signedInfo = $xpath->query("ds:SignedInfo[1]", $signature)->item(0)->C14N(true, false);
$signature->parentNode->removeChild($signature);
// Include namespaces in canonicalization
if ($xpath->query("ds:SignedInfo[1]/ds:Reference[1]/ds:Transforms[1]/ds:Transform/ec:InclusiveNamespaces[1]", $signature)->length == 1) {
$canonicalXml = $signedElement->C14N(false, false);
} else {
$canonicalXml = $signedElement->C14N(true, false);
};
// Get IdP certificate
$publicKey = openssl_pkey_get_public($certificate);
if (!$publicKey) {
throw new \Exception('Invalid public key used');
}
// Verify signature
if (!((sha1($canonicalXml, true) == $digestValue) && openssl_verify($signedInfo, $signatureValue, $publicKey) == 1)) {
throw new \Exception('Error verifying signature' . PHP_EOL . openssl_error_string() . PHP_EOL . 'Metadata: ' . print_r(htmlspecialchars($canonicalXml), 1));
}
return true;
}
}
$encxml = $_POST['SAMLResponse'];
$xml = urldecode(base64_decode($encxml));
$certificate = file_get_contents("/var/www/vhosts/mydomain.com/cert/server.crt");
if(MDSignature::verifySignature($xml, $certificate)) {
echo "Validation ok";
} else {
echo "ERROR Validate Certification!";
}
error:04077077:rsa routines:RSA_verify:wrong signature length
hervorgerufen durch openssl_verify($signedInfo, $signatureValue, $publicKey)
auch habe ich festgestellt, dass
(sha1($canonicalXml, true) == $digestValue) nicht zutrifft!
Bin für jede Hilfe dankbar.