public function sign(DOMDocument $data) { if (null === $this->privateKey) { throw new RuntimeException('Missing private key. Use setPrivateKey to set one.'); } $objKey = new XMLSecurityKey($this->keyAlgorithm, ['type' => 'private']); $objKey->loadKey($this->privateKey); $objXMLSecDSig = new XMLSecurityDSig(); $objXMLSecDSig->setCanonicalMethod($this->canonicalMethod); $objXMLSecDSig->addReference($data, $this->digestAlgorithm, $this->transforms, ['force_uri' => true]); $objXMLSecDSig->sign($objKey, $data->documentElement); /* Add associated public key */ if ($this->getPublicKey()) { $objXMLSecDSig->add509Cert($this->getPublicKey()); } }
public function signSoapDoc($objKey, $options = null) { $objDSig = new XMLSecurityDSig(); $objDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N); $arNodes = array(); foreach ($this->secNode->childNodes as $node) { if ($node->nodeType == XML_ELEMENT_NODE) { $arNodes[] = $node; } } if ($this->signAllHeaders) { foreach ($this->secNode->parentNode->childNodes as $node) { if ($node->nodeType == XML_ELEMENT_NODE && $node->namespaceURI != self::WSSENS) { $arNodes[] = $node; } } } if ($this->signBody) { foreach ($this->envelope->childNodes as $node) { if ($node->namespaceURI == $this->soapNS && $node->localName == 'Body') { $arNodes[] = $node; break; } } } $algorithm = XMLSecurityDSig::SHA1; if (is_array($options) && isset($options['algorithm'])) { $algorithm = $options['algorithm']; } $arOptions = array('prefix' => self::WSUPFX, 'prefix_ns' => self::WSUNS); $objDSig->addReferenceList($arNodes, $algorithm, null, $arOptions); $objDSig->sign($objKey); $insertTop = true; if (is_array($options) && isset($options['insertBefore'])) { $insertTop = (bool) $options['insertBefore']; } $objDSig->appendSignature($this->secNode, $insertTop); /* New suff */ if (is_array($options)) { if (!empty($options['KeyInfo'])) { if (!empty($options['KeyInfo']['X509SubjectKeyIdentifier'])) { $sigNode = $this->secNode->firstChild->nextSibling; $objDoc = $sigNode->ownerDocument; $keyInfo = $sigNode->ownerDocument->createElementNS(XMLSecurityDSig::XMLDSIGNS, 'ds:KeyInfo'); $sigNode->appendChild($keyInfo); $tokenRef = $objDoc->createElementNS(self::WSSENS, self::WSSEPFX . ':SecurityTokenReference'); $keyInfo->appendChild($tokenRef); $reference = $objDoc->createElementNS(self::WSSENS, self::WSSEPFX . ':KeyIdentifier'); $reference->setAttribute('ValueType', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier'); $reference->setAttribute('EncodingType', 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary'); $tokenRef->appendChild($reference); $x509 = openssl_x509_parse($objKey->getX509Certificate()); $keyid = $x509['extensions']['subjectKeyIdentifier']; $arkeyid = split(':', $keyid); $data = ''; foreach ($arkeyid as $hexchar) { $data .= chr(hexdec($hexchar)); } $dataNode = new DOMText(base64_encode($data)); $reference->appendChild($dataNode); } } } }
public function signDocument() { if (strlen($this->content2SignIdentifier) == 0) { return; } // get content to sign // get content to sign $doc = new DOMDocument('1.0', 'UTF-8'); $doc->loadXML($this->xmlMessage); $xpath = new DOMXPath($doc); $nodeset = $xpath->query("//{$this->content2SignIdentifier}")->item(0); // sign // sign $objXMLSecDSig = new XMLSecurityDSig(''); $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::C14N); $objXMLSecDSig->addReference($nodeset, XMLSecurityDSig::SHA256, array('http://www.w3.org/2000/09/xmldsig#enveloped-signature'), array('id_name' => 'Id', 'uri' => $this->msgIdentifier, 'overwrite' => false)); openssl_pkcs12_read(file_get_contents($this->myCertificatePathP12), $raw, $this->myCertificatePassword); $objKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, array('type' => 'private')); $objKey->loadKey($raw['pkey']); $objXMLSecDSig->sign($objKey, $nodeset); $objXMLSecDSig->add509Cert($raw['cert'], true, false, array('issuerSerial' => true, 'subjectName' => true, 'issuerCertificate' => false)); $this->xmlMessage = $doc->saveXML(); }
/** * 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); }
/** * @param \DOMNode $parent * @param SerializationContext $context */ public function serialize(\DOMNode $parent, SerializationContext $context) { if ($this->signingOptions && false === $this->signingOptions->isEnabled()) { return; } $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(SamlConstants::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, $this->signingOptions ? $this->signingOptions->getCertificateOptions()->all() : null); $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); }