/** * @return bool * @throws Exception */ public function isValid() { $singleAssertion = $this->validateNumAssertions(); if (!$singleAssertion) { throw new Exception('Multiple assertions are not supported'); } $validTimestamps = $this->validateTimestamps(); if (!$validTimestamps) { throw new Exception('Timing issues (please check your clock settings)'); } $objXMLSecDSig = new XMLSecurityDSig(); $objDSig = $objXMLSecDSig->locateSignature($this->_document); if (!$objDSig) { throw new Exception('Cannot locate Signature Node'); } $objXMLSecDSig->canonicalizeSignedInfo(); $objXMLSecDSig->idKeys = array('ID'); $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { throw new Exception('We have no idea about the key'); } try { $retVal = $objXMLSecDSig->validateReference(); } catch (Exception $e) { throw new Exception('Reference Validation Failed'); } XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); $objKey->loadKey($this->_settings->idpPublicCertificate, false, true); return $objXMLSecDSig->verify($objKey) === 1; }
/** * @param \DOMNode $parent * @param \AerialShip\LightSaml\Meta\SerializationContext $context * @return \DOMNode */ function getXml(\DOMNode $parent, SerializationContext $context) { $objXMLSecDSig = new \XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod($this->getCanonicalMethod()); $key = $this->getXmlSecurityKey(); switch ($key->type) { case \XMLSecurityKey::RSA_SHA256: $type = \XMLSecurityDSig::SHA256; break; case \XMLSecurityKey::RSA_SHA384: $type = \XMLSecurityDSig::SHA384; break; case \XMLSecurityKey::RSA_SHA512: $type = \XMLSecurityDSig::SHA512; break; default: $type = \XMLSecurityDSig::SHA1; } $objXMLSecDSig->addReferenceList(array($parent), $type, array(Protocol::XMLSEC_TRANSFORM_ALGORITHM_ENVELOPED_SIGNATURE, \XMLSecurityDSig::EXC_C14N), array('id_name' => $this->getIDName(), 'overwrite' => FALSE)); $objXMLSecDSig->sign($key); $objXMLSecDSig->add509Cert($this->getCertificate()->getData(), false, false); $firstChild = $parent->hasChildNodes() ? $parent->firstChild : null; if ($firstChild && $firstChild->localName == 'Issuer') { // The signature node should come after the issuer node $firstChild = $firstChild->nextSibling; } $objXMLSecDSig->insertSignature($parent, $firstChild); }
function processDocument() { global $src_file, $target_file, $user_pubkey_file_path, $user_cert_file_path; require dirname(__FILE__) . '/xmlseclibs.php'; if (file_exists($target_file)) { unlink($target_file); } $doc = new DOMDocument(); $doc->load($src_file); $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objDSig->addReference($doc, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature')); /* gako pribatu bat behar dugu prozesua burutzeko. orain edozein erabiliko dugu. gero txartelekoarekin ordezkatzeko */ $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); /* if key has Passphrase, set it using $objKey->passphrase = <passphrase> " */ $objKey->loadKey(dirname(__FILE__) . '/privkey.pem', TRUE); $objDSig->sign($objKey); /* Add associated public key */ // $objDSig->add509Cert(file_get_contents(dirname(__FILE__) . '/mycert.pem')); // $objDSig->add509Cert(file_get_contents($user_cert_file_path)); if (!file_exists($user_cert_file_path)) { debug('File not found', $user_cert_file_path); } else { $objDSig->add509Cert($user_cert_file_path); } $objDSig->appendSignature($doc->documentElement); $doc->save($target_file); }
public function is_valid() { $objXMLSecDSig = new XMLSecurityDSig(); $objDSig = $objXMLSecDSig->locateSignature($this->document); if (!$objDSig) { throw new Exception("Cannot locate Signature Node"); } $objXMLSecDSig->canonicalizeSignedInfo(); $objXMLSecDSig->idKeys = array('ID'); $retVal = $objXMLSecDSig->validateReference(); if (!$retVal) { throw new Exception("Reference Validation Failed"); } $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { throw new Exception("We have no idea about the key"); } $key = null; $singleAssertion = $this->validateNumAssertions(); if (!$singleAssertion) { throw new Exception("Only one SAMLAssertion allowed"); } $validTimestamps = $this->validateTimestamps(); if (!$validTimestamps) { throw new Exception("SAMLAssertion conditions not met"); } $objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); $objKey->loadKey($this->settings->x509certificate, false, true); $result = $objXMLSecDSig->verify($objKey); return $result; }
/** * @param \XMLSecurityKey $key * @return bool * @throws \AerialShip\LightSaml\Error\SecurityException */ public function validate(\XMLSecurityKey $key) { if ($this->signature == null) { return false; } if ($key->type != \XMLSecurityKey::RSA_SHA1) { throw new SecurityException('Key type must be RSA_SHA1 but got ' . $key->type); } $key = $this->castKeyIfNecessary($key); $ok = $this->signature->verify($key); if (!$ok) { throw new SecurityException('Unable to verify Signature'); } return true; }
function ADFS_SignResponse($response, $key, $cert) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys = array('AssertionID'); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $responsedom = new DOMDocument(); $responsedom->loadXML(str_replace("\r", "", $response)); $firstassertionroot = $responsedom->getElementsByTagName('Assertion')->item(0); $objXMLSecDSig->addReferenceList(array($firstassertionroot), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'AssertionID')); $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); $objKey->loadKey($key, TRUE); $objXMLSecDSig->sign($objKey); if ($cert) { $public_cert = file_get_contents($cert); $objXMLSecDSig->add509Cert($public_cert, TRUE); } $newSig = $responsedom->importNode($objXMLSecDSig->sigNode, TRUE); $firstassertionroot->appendChild($newSig); return $responsedom->saveXML(); }
public function addReference($name, $node, $type) { if (!$node instanceof \DOMNode) { throw new \Exception('$node is not of type \\DOMNode'); } $curencdoc = $this->encdoc; $this->_resetTemplate(); $encdoc = $this->encdoc; $this->encdoc = $curencdoc; $refuri = XMLSecurityDSig::generate_GUID(); $element = $encdoc->documentElement; $element->setAttribute("Id", $refuri); $this->references[$name] = array("node" => $node, "type" => $type, "encnode" => $encdoc, "refuri" => $refuri); }
/** * This function initializes the validator. * * @param $xmlNode The XML node which contains the Signature element. * @param $idAttribute The ID attribute which is used in node references. If this attribute is * NULL (the default), then we will use whatever is the default ID. */ public function __construct($xmlNode, $idAttribute = NULL, $publickey = FALSE) { assert('$xmlNode instanceof DOMNode'); /* Create an XML security object. */ $objXMLSecDSig = new XMLSecurityDSig(); /* Add the id attribute if the user passed in an id attribute. */ if ($idAttribute !== NULL) { assert('is_string($idAttribute)'); $objXMLSecDSig->idKeys[] = $idAttribute; } /* Locate the XMLDSig Signature element to be used. */ $signatureElement = $objXMLSecDSig->locateSignature($xmlNode); if (!$signatureElement) { throw new Exception('Could not locate XML Signature element.'); } /* Canonicalize the XMLDSig SignedInfo element in the message. */ $objXMLSecDSig->canonicalizeSignedInfo(); /* Validate referenced xml nodes. */ if (!$objXMLSecDSig->validateReference()) { throw new Exception('XMLsec: digest validation failed'); } /* Find the key used to sign the document. */ $objKey = $objXMLSecDSig->locateKey(); if (empty($objKey)) { throw new Exception('Error loading key to handle XML signature'); } /* Load the key data. */ if ($publickey) { $objKey->loadKey($publickey); } else { if (!XMLSecEnc::staticLocateKeyInfo($objKey, $signatureElement)) { throw new Exception('Error finding key data for XML signature validation.'); } } /* Check the signature. */ if (!$objXMLSecDSig->verify($objKey)) { throw new Exception("Unable to validate Signature"); } /* Extract the certificate fingerprint. */ $this->x509Fingerprint = $objKey->getX509Fingerprint(); /* Find the list of validated nodes. */ $this->validNodes = $objXMLSecDSig->getValidatedNodes(); }
function is_valid() { $objXMLSecDSig = new XMLSecurityDSig(); $objDSig = $objXMLSecDSig->locateSignature($this->doc); if (!$objDSig) { throw new Exception("Cannot locate Signature Node"); //, 'error', FALSE return false; } $objXMLSecDSig->canonicalizeSignedInfo(); $objXMLSecDSig->idKeys = array('ID'); $retVal = $objXMLSecDSig->validateReference(); if (!$retVal) { throw new Exception("SAML Assertion Error: Reference Validation Failed"); //, 'error', FALSE return false; // throw new Exception("Reference Validation Failed"); } $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { throw new Exception("SAML Assertion Error: We have no idea about the key"); //, 'error', FALSE return false; // throw new Exception("We have no idea about the key"); } $key = NULL; $singleAssertion = $this->validateNumAssertions(); if (!$singleAssertion) { throw new Exception("SAML Assertion Error: Only ONE SAML Assertion Allowed"); //, 'error', FALSE return false; // throw new Exception("Only ONE SamlAssertion allowed"); } $validTimestamps = $this->validateTimestamps(); if (!$validTimestamps) { throw new Exception("SAML Assertion Error: Check your timestamp conditions"); //, 'error', FALSE return false; // throw new Exception("Check your timestamp conditions"); } $objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); $objKey->loadKey($this->x509certificate, FALSE, true); $result = $objXMLSecDSig->verify($objKey); return $result; }
/** * Test that signatures contain the corresponding public keys. */ public function testGetValidatingCertificates() { $certData = XMLSecurityDSig::staticGet509XCerts(SAML2_CertificatesMock::PUBLIC_KEY_PEM); $certData = $certData[0]; $signedMockElementCopy = SAML2_Utils::copyElement($this->signedMockElement); $signedMockElementCopy->ownerDocument->appendChild($signedMockElementCopy); $tmp = new SAML2_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 SAML2_SignedElementHelperMock(); $mock->setSignatureKey(SAML2_CertificatesMock::getPrivateKey()); $mock->setCertificates(array($tmpCert, SAML2_CertificatesMock::PUBLIC_KEY_PEM)); $this->signedMockElement = $mock->toSignedXML(); $tmp = new SAML2_SignedElementHelperMock($this->signedMockElement); $certs = $tmp->getValidatingCertificates(); $this->assertCount(1, $certs); $this->assertEquals($certData, $certs[0]); }
function is_valid() { $objXMLSecDSig = new XMLSecurityDSig(); $objDSig = $objXMLSecDSig->locateSignature($this->doc); if (!$objDSig) { throw new Exception("Cannot locate Signature Node"); } $objXMLSecDSig->canonicalizeSignedInfo(); $objXMLSecDSig->idKeys = array('ID'); $retVal = $objXMLSecDSig->validateReference(); if (!$retVal) { throw new Exception("Reference Validation Failed"); } $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { throw new Exception("We have no idea about the key"); } $key = NULL; $objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); $objKey->loadKey($this->x509certificate, FALSE, true); $result = $objXMLSecDSig->verify($objKey); return $result; }
static function staticAdd509Cert($parentRef, $cert, $isPEMFormat = TRUE, $isURL = False, $xpath = NULL) { if ($isURL) { $cert = file_get_contents($cert); } if (!$parentRef instanceof DOMElement) { throw new Exception('Invalid parent Node parameter'); } $baseDoc = $parentRef->ownerDocument; if (empty($xpath)) { $xpath = new DOMXPath($parentRef->ownerDocument); $xpath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS); } $query = "./secdsig:KeyInfo"; $nodeset = $xpath->query($query, $parentRef); $keyInfo = $nodeset->item(0); if (!$keyInfo) { $inserted = FALSE; $keyInfo = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:KeyInfo'); $query = "./secdsig:Object"; $nodeset = $xpath->query($query, $parentRef); if ($sObject = $nodeset->item(0)) { $sObject->parentNode->insertBefore($keyInfo, $sObject); $inserted = TRUE; } if (!$inserted) { $parentRef->appendChild($keyInfo); } } // Add all certs if there are more than one $certs = XMLSecurityDSig::staticGet509XCerts($cert, $isPEMFormat); // Atach X509 data node $x509DataNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509Data'); $keyInfo->appendChild($x509DataNode); // Atach all certificate nodes foreach ($certs as $X509Cert) { $x509CertNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509Certificate', $X509Cert); $x509DataNode->appendChild($x509CertNode); } }
/** * This function initializes the validator. * * This function accepts an optional parameter $publickey, which is the public key * or certificate which should be used to validate the signature. This parameter can * take the following values: * - NULL/FALSE: No validation will be performed. This is the default. * - A string: Assumed to be a PEM-encoded certificate / public key. * - An array: Assumed to be an array returned by SimpleSAML_Utilities::loadPublicKey. * * @param DOMNode $xmlNode The XML node which contains the Signature element. * @param string|array $idAttribute The ID attribute which is used in node references. If * this attribute is NULL (the default), then we will use whatever is the default * ID. Can be eigther a string with one value, or an array with multiple ID * attrbute names. * @param array $publickey The public key / certificate which should be used to validate the XML node. */ public function __construct($xmlNode, $idAttribute = NULL, $publickey = FALSE) { assert('$xmlNode instanceof DOMNode'); if ($publickey === NULL) { $publickey = FALSE; } elseif (is_string($publickey)) { $publickey = array('PEM' => $publickey); } else { assert('$publickey === FALSE || is_array($publickey)'); } /* Create an XML security object. */ $objXMLSecDSig = new XMLSecurityDSig(); /* Add the id attribute if the user passed in an id attribute. */ if ($idAttribute !== NULL) { if (is_string($idAttribute)) { $objXMLSecDSig->idKeys[] = $idAttribute; } elseif (is_array($idAttribute)) { foreach ($idAttribute as $ida) { $objXMLSecDSig->idKeys[] = $ida; } } } /* Locate the XMLDSig Signature element to be used. */ $signatureElement = $objXMLSecDSig->locateSignature($xmlNode); if (!$signatureElement) { throw new Exception('Could not locate XML Signature element.'); } /* Canonicalize the XMLDSig SignedInfo element in the message. */ $objXMLSecDSig->canonicalizeSignedInfo(); /* Validate referenced xml nodes. */ if (!$objXMLSecDSig->validateReference()) { throw new Exception('XMLsec: digest validation failed'); } /* Find the key used to sign the document. */ $objKey = $objXMLSecDSig->locateKey(); if (empty($objKey)) { throw new Exception('Error loading key to handle XML signature'); } /* Load the key data. */ if ($publickey !== FALSE && array_key_exists('PEM', $publickey)) { /* We have PEM data for the public key / certificate. */ $objKey->loadKey($publickey['PEM']); } else { /* No PEM data. Search for key in signature. */ if (!XMLSecEnc::staticLocateKeyInfo($objKey, $signatureElement)) { throw new Exception('Error finding key data for XML signature validation.'); } if ($publickey !== FALSE) { /* $publickey is set, and should therefore contain one or more fingerprints. * Check that the response contains a certificate with a matching * fingerprint. */ assert('is_array($publickey["certFingerprint"])'); $certificate = $objKey->getX509Certificate(); if ($certificate === NULL) { /* Wasn't signed with an X509 certificate. */ throw new Exception('Message wasn\'t signed with an X509 certificate,' . ' and no public key was provided in the metadata.'); } self::validateCertificateFingerprint($certificate, $publickey['certFingerprint']); /* Key OK. */ } } /* Check the signature. */ if (!$objXMLSecDSig->verify($objKey)) { throw new Exception("Unable to validate Signature"); } /* Extract the certificate. */ $this->x509Certificate = $objKey->getX509Certificate(); /* Find the list of validated nodes. */ $this->validNodes = $objXMLSecDSig->getValidatedNodes(); }
public function processSignature($refNode) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys[] = 'wswsu:Id'; $objXMLSecDSig->idNS['wswsu'] = WSSESoapServer::WSUNS; $objXMLSecDSig->sigNode = $refNode; /* Canonicalize the signed info */ $objXMLSecDSig->canonicalizeSignedInfo(); $retVal = $objXMLSecDSig->validateReference(); if (!$retVal) { throw new Exception("Validation Failed"); } $key = NULL; $objKey = $objXMLSecDSig->locateKey(); if ($objKey) { if ($objKeyInfo = XMLSecEnc::staticLocateKeyInfo($objKey, $refNode)) { /* Handle any additional key processing such as encrypted keys here */ } } if (empty($objKey)) { throw new Exception("Error loading key to handle Signature"); } do { if (empty($objKey->key)) { $this->SOAPXPath->registerNamespace('xmlsecdsig', XMLSecurityDSig::XMLDSIGNS); $query = "./xmlsecdsig:KeyInfo/wswsse:SecurityTokenReference/wswsse:Reference"; $nodeset = $this->SOAPXPath->query($query, $refNode); if ($encmeth = $nodeset->item(0)) { if ($uri = $encmeth->getAttribute("URI")) { $arUrl = parse_url($uri); if (empty($arUrl['path']) && ($identifier = $arUrl['fragment'])) { $query = '//wswsse:BinarySecurityToken[@wswsu:Id="' . $identifier . '"]'; $nodeset = $this->SOAPXPath->query($query); if ($encmeth = $nodeset->item(0)) { $x509cert = $encmeth->textContent; $x509cert = str_replace(array("\r", "\n"), "", $x509cert); $x509cert = "-----BEGIN CERTIFICATE-----\n" . chunk_split($x509cert, 64, "\n") . "-----END CERTIFICATE-----\n"; $objKey->loadKey($x509cert); break; } } } } throw new Exception("Error loading key to handle Signature"); } } while (0); if (!$objXMLSecDSig->verify($objKey)) { throw new Exception("Unable to validate Signature"); } return TRUE; }
/** * Insert a Signature-node. * * @param XMLSecurityKey $key The key we should use to sign the message. * @param array $certificates The certificates we should add to the signature node. * @param DOMElement $root The XML node we should sign. * @param DomElement $insertBefore The XML element we should insert the signature element before. */ public static function insertSignature(XMLSecurityKey $key, array $certificates, DOMElement $root, DOMNode $insertBefore = NULL) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList(array($root), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID')); $objXMLSecDSig->sign($key); foreach ($certificates as $certificate) { $objXMLSecDSig->add509Cert($certificate, TRUE); } $objXMLSecDSig->insertSignature($root, $insertBefore); }
static function staticAddBes($parentRef, $cert, $isPEMFormat = TRUE, $isURL = False, $xpath = NULL, $digest = NULL) { if ($isURL) { $cert = file_get_contents($cert); } if (!$parentRef instanceof DOMElement) { throw new Exception('Invalid parent Node parameter'); } $baseDoc = $parentRef->ownerDocument; // Add all certs if there are more than one $certs = XMLSecurityDSig::staticGet509XCerts($cert, $isPEMFormat); // Attach X509 data node //$objectNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:Object'); $objectNode = $baseDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:Object'); $parentRef->appendChild($objectNode); $qProps = $baseDoc->createElement('QualifyingProperties'); $qProps->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); $qProps->setAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema'); $qProps->setAttribute('xmlns', 'http://uri.etsi.org/01903/v1.1.1#'); $qProps->setAttribute('Target', '#SignatureId'); $objectNode->appendChild($qProps); $SignedProps = $baseDoc->createElement('SignedProperties'); $SignedProps->setAttribute('Id', 'SignedPropertiesId'); $qProps->appendChild($SignedProps); $SignedSignatureProperties = $baseDoc->createElement('SignedSignatureProperties'); $SignedProps->appendChild($SignedSignatureProperties); $SigningTime = $baseDoc->createElement('SigningTime', date('c', strtotime('2014-01-27'))); $SignedSignatureProperties->appendChild($SigningTime); $SigningCertificate = $baseDoc->createElement('SigningCertificate'); $SignedSignatureProperties->appendChild($SigningCertificate); $Cert = $baseDoc->createElement('Cert'); $SigningCertificate->appendChild($Cert); $CertDigest = $baseDoc->createElement('CertDigest'); $Cert->appendChild($CertDigest); $DigestMethod = $baseDoc->createElement('DigestMethod'); $DigestMethodAttrAlgorithm = $baseDoc->createAttribute('Algorithm'); $DigestMethodAttrAlgorithm->value = self::SHA1; $DigestMethod->appendChild($DigestMethodAttrAlgorithm); $CertDigest->appendChild($DigestMethod); $DigestValue = $baseDoc->createElement('DigestValue', $digest); $CertDigest->appendChild($DigestValue); // ADD CERS foreach ($certs as $X509Cert) { if ($certData = openssl_x509_parse("-----BEGIN CERTIFICATE-----\n" . chunk_split($X509Cert, 64, "\n") . "-----END CERTIFICATE-----\n")) { if (!empty($certData['issuer']) && !empty($certData['serialNumber'])) { if (is_array($certData['issuer'])) { $parts = array(); foreach ($certData['issuer'] as $key => $value) { array_unshift($parts, "{$key}={$value}"); } $issuerName = implode(', ', $parts); } else { $issuerName = $certData['issuer']; } $IssuerSerial = $baseDoc->createElement('IssuerSerial'); $Cert->appendChild($IssuerSerial); $x509Node = $baseDoc->createElement('X509IssuerName', $issuerName); $x509NodeAttr = $baseDoc->createAttribute('xmlns'); $x509NodeAttr->value = 'http://www.w3.org/2000/09/xmldsig#'; $x509Node->appendChild($x509NodeAttr); $IssuerSerial->appendChild($x509Node); $x509Node = $baseDoc->createElement('X509SerialNumber', $certData['serialNumber']); $x509NodeAttr = $baseDoc->createAttribute('xmlns'); $x509NodeAttr->value = 'http://www.w3.org/2000/09/xmldsig#'; $x509Node->appendChild($x509NodeAttr); $IssuerSerial->appendChild($x509Node); } } } $SignaturePolicyIdentifier = $baseDoc->createElement('SignaturePolicyIdentifier'); $SignedSignatureProperties->appendChild($SignaturePolicyIdentifier); $SignaturePolicyImplied = $baseDoc->createElement('SignaturePolicyImplied'); $SignaturePolicyIdentifier->appendChild($SignaturePolicyImplied); return $SignedProps; }
/** * Signs the given metadata if metadata signing is enabled. * * @param string $metadataString A string with the metadata. * @param array $entityMetadata The metadata of the entity. * @param string $type A string which describes the type entity this is, e.g. 'SAML 2 IdP' or 'Shib 1.3 SP'. * * @return string The $metadataString with the signature embedded. * @throws Exception If the certificate or private key cannot be loaded, or the metadata doesn't parse properly. */ public static function sign($metadataString, $entityMetadata, $type) { $config = SimpleSAML_Configuration::getInstance(); // check if metadata signing is enabled if (!self::isMetadataSigningEnabled($config, $entityMetadata, $type)) { return $metadataString; } // find the key & certificate which should be used to sign the metadata $keyCertFiles = self::findKeyCert($config, $entityMetadata, $type); $keyFile = \SimpleSAML\Utils\Config::getCertPath($keyCertFiles['privatekey']); if (!file_exists($keyFile)) { throw new Exception('Could not find private key file [' . $keyFile . '], which is needed to sign the metadata'); } $keyData = file_get_contents($keyFile); $certFile = \SimpleSAML\Utils\Config::getCertPath($keyCertFiles['certificate']); if (!file_exists($certFile)) { throw new Exception('Could not find certificate file [' . $certFile . '], which is needed to sign the metadata'); } $certData = file_get_contents($certFile); // convert the metadata to a DOM tree try { $xml = SAML2_DOMDocumentFactory::fromString($metadataString); } catch (Exception $e) { throw new Exception('Error parsing self-generated metadata.'); } // load the private key $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); if (array_key_exists('privatekey_pass', $keyCertFiles)) { $objKey->passphrase = $keyCertFiles['privatekey_pass']; } $objKey->loadKey($keyData, false); // get the EntityDescriptor node we should sign $rootNode = $xml->firstChild; // sign the metadata with our private key if ($type == 'ADFS IdP') { $objXMLSecDSig = new sspmod_adfs_XMLSecurityDSig($metadataString); } else { $objXMLSecDSig = new XMLSecurityDSig(); } $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList(array($rootNode), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID')); $objXMLSecDSig->sign($objKey); // add the certificate to the signature $objXMLSecDSig->add509Cert($certData, true); // add the signature to the metadata $objXMLSecDSig->insertSignature($rootNode, $rootNode->firstChild); // return the DOM tree as a string return $xml->saveXML(); }
public function mPayAttachCertificateInfo($cert, $isPEMFormat = TRUE) { $data = XMLSecurityDSig::get509XCert($cert, $isPEMFormat); $certData = openssl_x509_parse("-----BEGIN CERTIFICATE-----\n" . chunk_split($data, 64, "\n") . "-----END CERTIFICATE-----\n"); $objXMLSecDSig = new XMLSecurityDSig(); if ($objDSig = $objXMLSecDSig->locateSignature($this->soapDoc)) { $this->SOAPXPath->registerNamespace('secdsig', XMLSecurityDSig::XMLDSIGNS); $query = "./secdsig:KeyInfo"; $nodeset = $this->SOAPXPath->query($query, $objDSig); $keyInfo = $nodeset->item(0); if (!$keyInfo) { $keyInfo = $objXMLSecDSig->createNewSignNode('KeyInfo'); $objDSig->appendChild($keyInfo); } $tokenRef = $this->soapDoc->createElementNS(WSSESoap::WSSENS, WSSESoap::WSSEPFX . ':SecurityTokenReference'); $keyInfo->appendChild($tokenRef); $xdata = $this->soapDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509Data'); $tokenRef->appendChild($xdata); $serial = $this->soapDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509IssuerSerial'); $xdata->appendChild($serial); if (!empty($certData['issuer']) && !empty($certData['serialNumber'])) { if (is_array($certData['issuer'])) { $parts = array(); foreach ($certData['issuer'] as $key => $value) { array_unshift($parts, "{$key}={$value}"); } $issuerName = implode(',', $parts); } else { $issuerName = $certData['issuer']; } $issuer_name_x = $this->soapDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509IssuerName', $issuerName); $serial->appendChild($issuer_name_x); $serial_number = $this->soapDoc->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:X509SerialNumber', $certData['serialNumber']); $serial->appendChild($serial_number); } } else { throw new Exception('Unable to locate digital signature'); } }
/** * Sign the specified DOMDocument * * @see https://github.com/Maks3w/xmlseclibs/blob/v1.3.0/tests/xml-sign.phpt * * @param DOMDocument $document * @return DOMDocument */ private function sign_document(DOMDocument $document) { $result = false; try { $dsig = new XMLSecurityDSig(); // For canonicalization purposes the exclusive (9) algorithm must be used. // @see http://pronamic.nl/wp-content/uploads/2012/12/iDEAL-Merchant-Integration-Guide-ENG-v3.3.1.pdf #page 30 $dsig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); // For hashing purposes the SHA-256 (11) algorithm must be used. // @see http://pronamic.nl/wp-content/uploads/2012/12/iDEAL-Merchant-Integration-Guide-ENG-v3.3.1.pdf #page 30 $dsig->addReference($document, XMLSecurityDSig::SHA256, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature'), array('force_uri' => true)); // For signature purposes the RSAWithSHA 256 (12) algorithm must be used. // @see http://pronamic.nl/wp-content/uploads/2012/12/iDEAL-Merchant-Integration-Guide-ENG-v3.3.1.pdf #page 31 $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'private')); $key->passphrase = $this->private_key_password; $key->loadKey($this->private_key); // Test if we can get an private key object, to prefent the following errors: // Warning: openssl_sign() [function.openssl-sign]: supplied key param cannot be coerced into a private key $result = openssl_get_privatekey($this->private_key, $this->private_key_password); if (false !== $result) { // Sign $dsig->sign($key); // The public key must be referenced using a fingerprint of an X.509 // certificate. The fingerprint must be calculated according // to the following formula HEX(SHA-1(DER certificate)) (13) // @see http://pronamic.nl/wp-content/uploads/2012/12/iDEAL-Merchant-Integration-Guide-ENG-v3.3.1.pdf #page 31 $fingerprint = Pronamic_WP_Pay_Gateways_IDealAdvanced_Security::getShaFingerprint($this->private_certificate); $dsig->addKeyInfoAndName($fingerprint); // Add the signature $dsig->appendSignature($document->documentElement); $result = $document; } else { throw new Exception('Can not load private key'); } } catch (Exception $e) { $this->error = new WP_Error('xml_security', $e->getMessage(), $e); } return $result; }
public function findCertificate($refNode) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys[] = 'wswsu:Id'; $objXMLSecDSig->idNS['wswsu'] = WSSESoapServer::WSUNS; $objXMLSecDSig->sigNode = $refNode; /* Canonicalize the signed info */ $objXMLSecDSig->canonicalizeSignedInfo(); $key = NULL; $objKey = $objXMLSecDSig->locateKey(); if (empty($objKey)) { throw new Exception("Error loading key to handle Signature"); } do { if (empty($objKey->key)) { $this->SOAPXPath->registerNamespace('xmlsecdsig', XMLSecurityDSig::XMLDSIGNS); $query = "./xmlsecdsig:KeyInfo/wswsse:SecurityTokenReference/wswsse:Reference"; $nodeset = $this->SOAPXPath->query($query, $refNode); if ($encmeth = $nodeset->item(0)) { if ($uri = $encmeth->getAttribute("URI")) { $arUrl = parse_url($uri); if (empty($arUrl['path']) && ($identifier = $arUrl['fragment'])) { $query = '//wswsse:BinarySecurityToken[@wswsu:Id="' . $identifier . '"]'; $nodeset = $this->SOAPXPath->query($query); if ($encmeth = $nodeset->item(0)) { $x509cert = $encmeth->textContent; if (!$x509cert) { return FALSE; } $x509cert = str_replace(array("\r", "\n"), "", $x509cert); $x509cert = "-----BEGIN CERTIFICATE-----\n" . chunk_split($x509cert, 64, "\n") . "-----END CERTIFICATE-----\n"; return $x509cert; } } } } throw new Exception("Error loading key to handle Signature"); } } while (0); return FALSE; }
public static function PrepSAMLAssertion(&$saml_xml_request) { // // Gather inputs needed during assembly of SAML Assertion (e.g., keys, certs, timestamps, IDs_ // $DateTimeNow = new DateTime(null, new DateTimeZone("UTC")); $DateTimeNowString = $DateTimeNow->format("Y-m-d\\TH:i:s.B\\Z"); $DateTime15Min = new DateTime(null, new DateTimeZone("UTC")); $DateTime15Min->modify('+900 sec'); $DateTime15MinString = $DateTime15Min->format("Y-m-d\\TH:i:s.B\\Z"); $SAMLParams = array(); $SAMLParams['IssueInstant'] = $DateTimeNowString; $SAMLParams['Issuer'] = SAML_IDENTITY_PROVIDER_ID; $SAMLParams['ID'] = SimpleSAML_Utilities::generateID(); $SAMLParams['NameID'] = SAML_NAME_ID; $SAMLParams['NotBefore'] = $DateTimeNowString; $SAMLParams['NotOnOrAfter'] = $DateTime15MinString; $SAMLParams['AuthnInstant'] = $DateTimeNowString; $SAMLParams['Audience'] = SAML_IDENTITY_PROVIDER_ID; $SAMLParams['x509'] = file_get_contents(SAML_X509_CERT_PATH); $SAMLParams['private_key'] = file_get_contents(SAML_X509_PRIVATE_KEY_PATH); // // Assemble DOM containing correct SAML assertion // $xml = new DOMDocument('1.0', 'utf-8'); // Assertion $assertion = $xml->createElementNS('urn:oasis:names:tc:SAML:2.0:assertion', 'saml2:Assertion'); $assertion->setAttribute('ID', $SAMLParams['ID']); $assertion->setAttribute('Version', '2.0'); $assertion->setAttribute('IssueInstant', $SAMLParams['IssueInstant']); $xml->appendChild($assertion); // Issuer $issuer = $xml->createElement('saml2:Issuer', $SAMLParams['Issuer']); $assertion->appendChild($issuer); // Subject + NameID + SubjectConfirmation $subject = $xml->createElement('saml2:Subject'); $assertion->appendChild($subject); // NameID $nameid = $xml->createElement('saml2:NameID', $SAMLParams['NameID']); $nameid->setAttribute('Format', 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'); $subject->appendChild($nameid); // SubjectConfirmation $confirmation = $xml->createElement('saml2:SubjectConfirmation'); $confirmation->setAttribute('Method', 'urn:oasis:names:tc:SAML:2.0:cm:bearer'); $subject->appendChild($confirmation); // Conditions + AudienceRestriction + Audience $condition = $xml->createElement('saml2:Conditions'); $condition->setAttribute('NotBefore', $SAMLParams['NotBefore']); $condition->setAttribute('NotOnOrAfter', $SAMLParams['NotOnOrAfter']); $assertion->appendChild($condition); // AudienceRestriction $audiencer = $xml->createElement('saml2:AudienceRestriction'); $condition->appendChild($audiencer); // Audience $audience = $xml->createElement('saml2:Audience', $SAMLParams['Audience']); $audiencer->appendChild($audience); // AuthnStatement + AuthnContext + AuthnContextClassRef $authnstat = $xml->createElement('saml2:AuthnStatement'); $authnstat->setAttribute('AuthnInstant', $SAMLParams['AuthnInstant']); $authnstat->setAttribute('SessionIndex', $SAMLParams['ID']); $assertion->appendChild($authnstat); // AuthnContext $authncontext = $xml->createElement('saml2:AuthnContext'); $authnstat->appendChild($authncontext); // AuthnContextClassRef $authncontext_ref = $xml->createElement('saml2:AuthnContextClassRef', 'urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified'); $authncontext->appendChild($authncontext_ref); //Private KEY $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); $objKey->loadKey($SAMLParams['private_key']); //Sign the Assertion $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objXMLSecDSig->addReferenceList(array($assertion), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('URI' => 'ID', 'overwrite' => false, 'id_name' => 'ID')); $objXMLSecDSig->sign($objKey); $objXMLSecDSig->add509Cert($SAMLParams['x509']); $objXMLSecDSig->insertSignature($assertion, $subject); $saml = $xml->saveXML(); // // Change Reference URI locally (considered changing 'xmlseclibs.php', but // that seemed inappropriate) // preg_match("/<ds:Reference URI=\"#(.+?)\">/is", $saml, $URI); $saml = str_replace("Id=\"" . $URI[1] . "\"", "", $saml); $saml = str_replace($URI[1], $SAMLParams["ID"], $saml); // // Prepare Base64-Encoded SAML Assertion request body based on DOM // $saml = str_replace('<?xml version="1.0" encoding="utf-8"?>', '', $saml); $saml_xml_request = base64_encode(stripslashes($saml)); }
$target_file = dirname(__FILE__) . '/temp/dokumentu-sinatua.xml'; $openssl = sfConfig::get("app_bin_openssl", "openssl"); file_put_contents($user_cert_file_path, $_SERVER['SSL_CLIENT_CERT']); $output = shell_exec($openssl . ' x509 -inform pem -in ' . $user_cert_file_path . ' -pubkey -noout > ' . $user_pubkey_file_path); if ($yafirmado) { $src = file_get_contents($target_file); $src = preg_replace('/<ds:SignatureValue>[^<]*<\\/ds:SignatureValue>/i', '<ds:SignatureValue>' . $sinatuta . '</ds:SignatureValue>', $src); file_put_contents($target_file, $src); $xml = file_get_contents($target_file); } else { if (file_exists($target_file)) { unlink($target_file); } $doc = new DOMDocument(); $doc->load($dir); $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objDSig->addReference($doc, XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature')); /* gako pribatu bat behar dugu prozesua burutzeko. orain edozein erabiliko dugu. gero txartelekoarekin ordezkatzeko */ $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private')); /* if key has Passphrase, set it using $objKey->passphrase = <passphrase> " */ $objKey->loadKey(dirname(__FILE__) . '/privkey.pem', TRUE); $objDSig->sign($objKey); /* Add associated public key */ // $objDSig->add509Cert(file_get_contents(dirname(__FILE__) . '/mycert.pem')); // $objDSig->add509Cert(file_get_contents($user_cert_file_path)); if (!file_exists($user_cert_file_path)) { die('File not found : ' . $user_cert_file_path); } else { $objDSig->add509Cert($user_cert_file_path); }
/** * @dataProvider testXmlSignProvider * @throws \Exception */ public function testXmlSign($dsigAlgorithm, $keyType, $expectedFileName) { $doc = new \DOMDocument(); $doc->load(dirname(__FILE__) . '/../basic-doc.xml'); $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $objDSig->addReference($doc, $dsigAlgorithm, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature')); $objKey = new XMLSecurityKey($keyType, array('type' => 'private')); /* load private key */ $objKey->loadKey(dirname(__FILE__) . '/../privkey.pem', true); /* if key has Passphrase, set it using $objKey->passphrase = <passphrase> " */ $objDSig->sign($objKey); /* Add associated public key */ $objDSig->add509Cert(file_get_contents(dirname(__FILE__) . '/../mycert.pem')); $objDSig->appendSignature($doc->documentElement); $sign_output = $doc->saveXML(); $sign_output_def = file_get_contents($expectedFileName); $this->assertEquals($sign_output_def, $sign_output, "Signature doesn't match"); }
public function add509Cert($cert, $isPEMFormat = TRUE) { $data = XMLSecurityDSig::get509XCert($cert, $isPEMFormat); if ($xpath = $this->getXPathObj()) { $query = "./secdsig:KeyInfo"; $nodeset = $xpath->query($query, $this->sigNode); $keyInfo = $nodeset->item(0); if (!$keyInfo) { $inserted = FALSE; $keyInfo = $this->createNewSignNode('KeyInfo'); if ($xpath = $this->getXPathObj()) { $query = "./secdsig:Object"; $nodeset = $xpath->query($query, $this->sigNode); if ($sObject = $nodeset->item(0)) { $sObject->parentNode->insertBefore($keyInfo, $sObject); $inserted = TRUE; } } if (!$inserted) { $this->sigNode->appendChild($keyInfo); } } $x509DataNode = $this->createNewSignNode('X509Data'); $keyInfo->appendChild($x509DataNode); $x509CertNode = $this->createNewSignNode('X509Certificate', $data); $x509DataNode->appendChild($x509CertNode); } }
/** * Validates a signature (Message or Assertion). * * @param string|DomDocument $xml The element we should validate * @param string|null $cert The pubic cert * @param string|null $fingerprint The fingerprint of the public cert */ public static function validateSign($xml, $cert = null, $fingerprint = null) { if ($xml instanceof DOMDocument) { $dom = clone $xml; } else { if ($xml instanceof DOMElement) { $dom = clone $xml->ownerDocument; } else { $dom = new DOMDocument(); $dom = self::loadXML($dom, $xml); } } $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys = array('ID'); $objDSig = $objXMLSecDSig->locateSignature($dom); if (!$objDSig) { throw new Exception('Cannot locate Signature Node'); } $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { throw new Exception('We have no idea about the key'); } $objXMLSecDSig->canonicalizeSignedInfo(); try { $retVal = $objXMLSecDSig->validateReference(); } catch (Exception $e) { throw $e; } XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); if (!empty($cert)) { $objKey->loadKey($cert, false, true); return $objXMLSecDSig->verify($objKey) === 1; } else { $domCert = $objKey->getX509Certificate(); $domCertFingerprint = OneLogin_Saml2_Utils::calculateX509Fingerprint($domCert); if (OneLogin_Saml2_Utils::formatFingerPrint($fingerprint) !== $domCertFingerprint) { return false; } else { $objKey->loadKey($domCert, false, true); return $objXMLSecDSig->verify($objKey) === 1; } } }
/** * Insert a Signature-node. * * @param XMLSecurityKey $key The key we should use to sign the message. * @param array $certificates The certificates we should add to the signature node. * @param DOMElement $root The XML node we should sign. * @param DOMNode $insertBefore The XML element we should insert the signature element before. */ public static function insertSignature(XMLSecurityKey $key, array $certificates, DOMElement $root, DOMNode $insertBefore = NULL) { $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); switch ($key->type) { case XMLSecurityKey::RSA_SHA256: $type = XMLSecurityDSig::SHA256; break; case XMLSecurityKey::RSA_SHA384: $type = XMLSecurityDSig::SHA384; break; case XMLSecurityKey::RSA_SHA512: $type = XMLSecurityDSig::SHA512; break; default: $type = XMLSecurityDSig::SHA1; } $objXMLSecDSig->addReferenceList(array($root), $type, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), array('id_name' => 'ID', 'overwrite' => FALSE)); $objXMLSecDSig->sign($key); foreach ($certificates as $certificate) { $objXMLSecDSig->add509Cert($certificate, TRUE); } $objXMLSecDSig->insertSignature($root, $insertBefore); }
public function EncryptBody($siteKey, $objKey, $token) { $enc = new XMLSecEnc(); foreach ($this->envelope->childNodes as $node) { if ($node->namespaceURI == $this->soapNS && $node->localName == 'Body') { break; } } $enc->setNode($node); /* encrypt the symmetric key */ $enc->encryptKey($siteKey, $objKey, false); $enc->type = XMLSecEnc::Content; /* Using the symmetric key to actually encrypt the data */ $encNode = $enc->encryptNode($objKey); $guid = XMLSecurityDSig::generate_GUID(); $encNode->setAttribute('Id', $guid); $refNode = $encNode->firstChild; while ($refNode && $refNode->nodeType != XML_ELEMENT_NODE) { $refNode = $refNode->nextSibling; } if ($refNode) { $refNode = $refNode->nextSibling; } if ($this->addEncryptedKey($encNode, $enc, $token)) { $this->AddReference($enc->encKey, $guid); } }
public function signSOAPDoc($objKey) { $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $arNodes = array(); foreach ($this->SecNode->childNodes as $node) { if ($node->nodeType == XML_ELEMENT_NODE) { $arNodes[] = $node; } } foreach ($this->Envelope->childNodes as $node) { if ($node->namespaceURI == $this->SOAPNS && $node->localName == 'Body') { $arNodes[] = $node; break; } } $arOptions = array('prefix' => WSSESoap::WSUPFX, 'prefix_ns' => WSSESoap::WSUNS); $objDSig->addReferenceList($arNodes, XMLSecurityDSig::SHA1, NULL, $arOptions); $objDSig->sign($objKey); $objDSig->appendSignature($this->SecNode, TRUE); }
/** * Validates a signature (Message or Assertion). * * @param string|DomDocument $xml The element we should validate * @param string|null $cert The pubic cert * @param string|null $fingerprint The fingerprint of the public cert * @param string|null $fingerprintalg The algorithm used to get the fingerprint */ public static function validateSign($xml, $cert = null, $fingerprint = null, $fingerprintalg = 'sha1') { if ($xml instanceof DOMDocument) { $dom = clone $xml; } else { if ($xml instanceof DOMElement) { $dom = clone $xml->ownerDocument; } else { $dom = new DOMDocument(); $dom = self::loadXML($dom, $xml); } } # Check if Reference URI is empty try { $signatureElems = $dom->getElementsByTagName('Signature'); foreach ($signatureElems as $signatureElem) { $referenceElems = $dom->getElementsByTagName('Reference'); if (count($referenceElems) > 0) { $referenceElem = $referenceElems->item(0); if ($referenceElem->getAttribute('URI') == '') { $referenceElem->setAttribute('URI', '#' . $signatureElem->parentNode->getAttribute('ID')); } } } } catch (Exception $e) { continue; } $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->idKeys = array('ID'); $objDSig = $objXMLSecDSig->locateSignature($dom); if (!$objDSig) { throw new Exception('Cannot locate Signature Node'); } $objKey = $objXMLSecDSig->locateKey(); if (!$objKey) { throw new Exception('We have no idea about the key'); } $objXMLSecDSig->canonicalizeSignedInfo(); try { $retVal = $objXMLSecDSig->validateReference(); } catch (Exception $e) { throw $e; } XMLSecEnc::staticLocateKeyInfo($objKey, $objDSig); if (!empty($cert)) { $objKey->loadKey($cert, false, true); return $objXMLSecDSig->verify($objKey) === 1; } else { $domCert = $objKey->getX509Certificate(); $domCertFingerprint = OneLogin_Saml2_Utils::calculateX509Fingerprint($domCert, $fingerprintalg); if (OneLogin_Saml2_Utils::formatFingerPrint($fingerprint) !== $domCertFingerprint) { return false; } else { $objKey->loadKey($domCert, false, true); return $objXMLSecDSig->verify($objKey) === 1; } } }
/** * Signs the given DOMElement and inserts the signature at the given position. * * The private key must be set before calling this function. * * @param $node The DOMElement we should generate a signature for. * @param $insertInto The DOMElement we should insert the signature element into. * @param $insertBefore The element we should insert the signature element before. Defaults to NULL, * in which case the signature will be appended to the element spesified in * $insertInto. */ public function sign($node, $insertInto, $insertBefore = NULL) { assert('$node instanceof DOMElement'); assert('$insertInto instanceof DOMElement'); assert('is_null($insertBefore) || $insertBefore instanceof DOMElement ' . '|| $insertBefore instanceof DOMComment || $insertBefore instanceof DOMText'); if ($this->privateKey === FALSE) { throw new Exception('Private key not set.'); } $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $options = array(); if ($this->idAttrName !== FALSE) { $options['id_name'] = $this->idAttrName; } $objXMLSecDSig->addReferenceList(array($node), XMLSecurityDSig::SHA1, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N), $options); $objXMLSecDSig->sign($this->privateKey); if ($this->certificate !== FALSE) { // Add the certificate to the signature $objXMLSecDSig->add509Cert($this->certificate, TRUE); } // Add extra certificates foreach ($this->extraCertificates as $certificate) { $objXMLSecDSig->add509Cert($certificate, TRUE); } $objXMLSecDSig->insertSignature($insertInto, $insertBefore); }