Skip to content

Instantly share code, notes, and snippets.

@brankoajzele
Created January 22, 2013 13:57
Show Gist options
  • Save brankoajzele/4594831 to your computer and use it in GitHub Desktop.
Save brankoajzele/4594831 to your computer and use it in GitHub Desktop.
<?php
$XMLRequestDOMDoc = new DOMDocument();
$XMLRequestDOMDoc->loadXML($XMLRequest);
$canonical = $XMLRequestDOMDoc->C14N();
$DigestValue = base64_encode(hash('sha1', $canonical, true));
$rootElem = $XMLRequestDOMDoc->documentElement;
$SignatureNode = $rootElem->appendChild(new DOMElement('Signature'));
$SignatureNode->setAttribute('xmlns','http://www.w3.org/2000/09/xmldsig#');
$SignedInfoNode = $SignatureNode->appendChild(new DOMElement('SignedInfo'));
$SignedInfoNode->setAttribute('xmlns','http://www.w3.org/2000/09/xmldsig#');
$CanonicalizationMethodNode = $SignedInfoNode->appendChild(new DOMElement('CanonicalizationMethod'));
$CanonicalizationMethodNode->setAttribute('Algorithm','http://www.w3.org/2001/10/xml-exc-c14n#');
$SignatureMethodNode = $SignedInfoNode->appendChild(new DOMElement('SignatureMethod'));
$SignatureMethodNode->setAttribute('Algorithm','http://www.w3.org/2000/09/xmldsig#rsa-sha1');
$ReferenceNode = $SignedInfoNode->appendChild(new DOMElement('Reference'));
$ReferenceNode->setAttribute('URI', sprintf('#%s', $UriId));
$TransformsNode = $ReferenceNode->appendChild(new DOMElement('Transforms'));
$Transform1Node = $TransformsNode->appendChild(new DOMElement('Transform'));
$Transform1Node->setAttribute('Algorithm','http://www.w3.org/2000/09/xmldsig#enveloped-signature');
$Transform2Node = $TransformsNode->appendChild(new DOMElement('Transform'));
$Transform2Node->setAttribute('Algorithm', 'http://www.w3.org/2001/10/xml-exc-c14n#');
$DigestMethodNode = $ReferenceNode->appendChild(new DOMElement('DigestMethod'));
$DigestMethodNode->setAttribute('Algorithm','http://www.w3.org/2000/09/xmldsig#sha1');
$ReferenceNode->appendChild(new DOMElement('DigestValue', $DigestValue));
$SignedInfoNode = $XMLRequestDOMDoc->getElementsByTagName('SignedInfo')->item(0);
$X509Issuer = $publicCertificateData['issuer'];
$X509IssuerName = sprintf('OU=%s,O=%s,C=%s', $X509Issuer['OU'], $X509Issuer['O'], $X509Issuer['C']);
$X509IssuerSerial = $publicCertificateData['serialNumber'];
$publicCertificatePureString = str_replace('-----BEGIN CERTIFICATE-----', '', $publicCertificate);
$publicCertificatePureString = str_replace('-----END CERTIFICATE-----', '', $publicCertificatePureString);
$SignedInfoSignature = null;
if (!openssl_sign($SignedInfoNode->C14N(true), $SignedInfoSignature, $privateKeyResource, OPENSSL_ALGO_SHA1)) {
throw new Exception('Unable to sign the request');
}
$SignatureNode = $XMLRequestDOMDoc->getElementsByTagName('Signature')->item(0);
$SignatureValueNode = new DOMElement('SignatureValue', base64_encode($SignedInfoSignature));
$SignatureNode->appendChild($SignatureValueNode);
$KeyInfoNode = $SignatureNode->appendChild(new DOMElement('KeyInfo'));
$X509DataNode = $KeyInfoNode->appendChild(new DOMElement('X509Data'));
$X509CertificateNode = new DOMElement('X509Certificate', $publicCertificatePureString);
$X509DataNode->appendChild($X509CertificateNode);
$X509IssuerSerialNode = $X509DataNode->appendChild(new DOMElement('X509IssuerSerial'));
$X509IssuerNameNode = new DOMElement('X509IssuerName',$X509IssuerName);
$X509IssuerSerialNode->appendChild($X509IssuerNameNode);
$X509SerialNumberNode = new DOMElement('X509SerialNumber',$X509IssuerSerial);
$X509IssuerSerialNode->appendChild($X509SerialNumberNode);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment