I want to verify a signature for a soap request on a soap server implemented in php.
The server code:
$Server = new SoapServer();
$d = new DOMDocument();
$d->load('php://input');
$s = new WSSESoapServer($d);
try {
if($s->process()) {
// Valid signature
$Server->handle($s->saveXML());
} else {
throw new Exception('Invalid signature');
}
} catch (Exception $e) {
echo "server exception: " . $e;
}
The error:
exception 'Exception' with message 'Error loading key to handle Signature' in /<path>/wse/src/WSSESoapServer.php:146
I have implemented a Client to sign SOAP requests using this library: https://github.com/robrichards/wse-php. There are no examples of how to implement the server...
How do I load the public key to check the signature?
[Edit] I have now been able to load the supplied key using
$key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'public'));
$key->loadKey(CERT, true);
I am no longer getting an error message when validating the signature:
$x = new XMLSecurityDSig();
$d = $x->locateSignature($soapDoc);
$valid = $x->verify($key);
However, $valid is always false. I have no idea if it's because the key is loaded wrong or is actually invalid. I can find very little information on implementing a SOAP server with PHP and no information on implementing a SOAP server that relies on checking a signed request.
CLARIFICATION
My client talks to a remote web service and gets an acknowledgement.
Then the remote server takes some time to process my request.
A remote client (that I have no control over) then makes a request to my service.
The last step is where I have trouble verifying the signature
Well anyways, your first approach looks fine to me, my server has the same structure. Unfortunately,
WSSESoapServer
does not inherit from SoapServer, thus is not really an SoapServer, but rather a SoapSignatureValidator and should be called like that. It would be easily possible to correct that behaviour, that one would not need a separateSoapServer
instance (should be transparent and automatically).