return false;
}
+
+ function refresh_key() {
+ // set up an RPC request
+ $mnetrequest = new mnet_xmlrpc_client();
+ // Use any method - listServices is pretty lightweight.
+ $mnetrequest->set_method('system/listServices');
+
+ // Do RPC call and store response
+ if ($mnetrequest->send($this) === true) {
+ // Ok - we actually don't care about the result
+ $temp = new mnet_peer();
+ $temp->set_id($this->id);
+ if($this->public_key != $temp->public_key) {
+ $newkey = param_clean($temp->public_key, PARAM_PEM);
+ if(!empty($newkey)) {
+ $this->public_key = $newkey;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
?>
\ No newline at end of file
$isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $MNET->get_private_key());
if (!$isOpen) {
+ // Decryption failed... let's try our archived keys
+ $result = get_config('mnet', 'openssl_history');
+ if(empty($result)) {
+ set_config('openssl_history', serialize(array()), 'mnet');
+ $result = get_config('mnet', 'openssl_history');
+ }
+ $openssl_history = unserialize($result->value);
+ foreach($openssl_history as $keyset) {
+ $keyresource = openssl_pkey_get_private($keyset['keypair_PEM']);
+ $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $keyresource);
+ if ($isOpen) {
+ // It's an older code, sir, but it checks out
+ break;
+ }
+ }
+ }
+
+ if (!$isOpen) {
+ trigger_error("None of our keys could open the payload from host {$mnet_peer->wwwroot} with id {$mnet_peer->id}.");
return false;
}
if($this->response['faultCode'] == 7025 && empty($mnet_peer->re_key)) {
$record = new stdClass();
$record->id = $mnet_peer->id;
- $record->public_key = $this->response['faultString'];
- $details = openssl_x509_parse($record->public_key);
- $record->public_key_expires = $details['validTo_time_t'];
- update_record('mnet_host', $record);
- $mnet_peer2 = new mnet_peer();
- $mnet_peer2->set_id($record->id);
- $mnet_peer2->re_key = true;
- $this->send($mnet_peer2);
+ if($this->response['faultString'] == clean_param($this->response['faultString'], PARAM_PEM)) {
+ $record->public_key = $this->response['faultString'];
+ $details = openssl_x509_parse($record->public_key);
+ if(is_array($details) && isset($details['validTo_time_t'])) {
+ $record->public_key_expires = $details['validTo_time_t'];
+ update_record('mnet_host', $record);
+ $mnet_peer2 = new mnet_peer();
+ $mnet_peer2->set_id($record->id);
+ $mnet_peer2->re_key = true;
+ $this->send($mnet_peer2);
+ } else {
+ $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'];
+ }
+ } else {
+ $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'];
+ }
} else {
$this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'];
}
$crypt_parser = new mnet_encxml_parser();
$crypt_parser->parse($HTTP_RAW_POST_DATA);
+ // Make sure we know who we're talking to
+ $host_record_exists = $MNET_REMOTE_CLIENT->set_wwwroot($crypt_parser->remote_wwwroot);
+
+ if (false == $host_record_exists) {
+ exit(mnet_server_fault(7020, 'wrong-wwwroot', $crypt_parser->remote_wwwroot));
+ } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != $MNET_REMOTE_CLIENT->ip_address) {
+ exit(mnet_server_fault(7017, 'wrong-ip'));
+ }
+
if ($crypt_parser->payload_encrypted) {
$key = array_pop($crypt_parser->cipher); // This key is Symmetric
$crypt_parser->free_resource();
- // Initialize payload var
- $payload = '';
+ $payload = ''; // Initialize payload var
+ $push_current_key = false; // True if we need to push a fresh key to the peer
// &$payload
$isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $MNET->get_private_key());
$isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $keyresource);
if ($isOpen) {
// It's an older code, sir, but it checks out
- exit(mnet_server_fault(7025, $MNET->public_key));
+ $push_current_key = true;
}
}
}
unset($payload);
- $host_record_exists = $MNET_REMOTE_CLIENT->set_wwwroot($sig_parser->remote_wwwroot);
-
- if (false == $host_record_exists) {
- exit(mnet_server_fault(7020, 'wrong-wwwroot', $sig_parser->remote_wwwroot));
- } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != $MNET_REMOTE_CLIENT->ip_address) {
- exit(mnet_server_fault(7017, 'wrong-ip'));
+ // if the peer used one of our public keys that have expired, we will
+ // return a signed/encrypted error message with our new public key
+ if($push_current_key) {
+ // NOTE: Here, we use the 'mnet_server_fault_xml' to avoid
+ // get_string being called on our public_key
+ exit(mnet_server_fault_xml(7025, $MNET->public_key));
}
/**
if ($signature_verified == 1) {
// Parse the XML
} elseif ($signature_verified == 0) {
- exit(mnet_server_fault(710, 'verifysignature-invalid'));
+ $currkey = mnet_get_public_key($MNET_REMOTE_CLIENT->wwwroot);
+ if($currkey != $certificate) {
+ // Has the server updated its certificate since our last
+ // handshake?
+ if(!$MNET_REMOTE_CLIENT->refresh_key()) {
+ exit(mnet_server_fault(7026, 'verifysignature-invalid'));
+ }
+ } else {
+ exit(mnet_server_fault(710, 'verifysignature-invalid'));
+ }
} else {
exit(mnet_server_fault(711, 'verifysignature-error'));
}