diff --git a/mnet/xmlrpc/server.php b/mnet/xmlrpc/server.php index b101ff028b0..a7cce24e644 100644 --- a/mnet/xmlrpc/server.php +++ b/mnet/xmlrpc/server.php @@ -206,20 +206,27 @@ function mnet_server_strip_wrappers($HTTP_RAW_POST_DATA) { // Does the signature match the data and the public cert? $signature_verified = openssl_verify($payload, base64_decode($sig_parser->signature), $certificate); - if ($signature_verified == 1) { - $MNET_REMOTE_CLIENT->touch(); - // Parse the XML - } elseif ($signature_verified == 0) { + + if ($signature_verified == 0) { + // $signature was not generated for $payload using $certificate + // Get the key the remote peer is currently publishing: $currkey = mnet_get_public_key($MNET_REMOTE_CLIENT->wwwroot, $MNET_REMOTE_CLIENT->application->xmlrpc_server_url); + // If the key the remote peer is currently publishing is different to $certificate if($currkey != $certificate) { - // Has the server updated its certificate since our last - // handshake? - if(!$MNET_REMOTE_CLIENT->refresh_key()) { + // If we can't get the server's new key through trusted means, exit. + if(!$MNET_REMOTE_CLIENT->refresh_key()){ exit(mnet_server_fault(7026, 'verifysignature-invalid')); } - } else { - exit(mnet_server_fault(710, 'verifysignature-invalid')); + // If we did manage to re-key, try to verify the signature again against the new public key. + $certificate = $MNET_REMOTE_CLIENT->public_key; + $signature_verified = openssl_verify($payload, base64_decode($sig_parser->signature), $certificate); } + } + + if ($signature_verified == 1) { + $MNET_REMOTE_CLIENT->touch(); + } elseif ($signature_verified == 0) { + exit(mnet_server_fault(710, 'verifysignature-invalid')); } else { exit(mnet_server_fault(711, 'verifysignature-error')); }