Skip to content

Commit

Permalink
Mnet: Key rotation: A more robust changeover for fresh keys
Browse files Browse the repository at this point in the history
  • Loading branch information
donal72 committed Jan 15, 2007
1 parent 82b29ea commit 9dd0e61
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 18 deletions.
22 changes: 22 additions & 0 deletions mnet/remote_client.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,27 @@ function plaintext_is_ok() {

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;
}
}
?>
43 changes: 35 additions & 8 deletions mnet/xmlrpc/client.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,25 @@ function send($mnet_peer) {
$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;
}

Expand Down Expand Up @@ -256,14 +275,22 @@ function send($mnet_peer) {
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'];
}
Expand Down
38 changes: 28 additions & 10 deletions mnet/xmlrpc/server.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,24 @@ function mnet_server_strip_wrappers($HTTP_RAW_POST_DATA) {
$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
$data = array_pop($crypt_parser->cipher);

$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());
Expand All @@ -147,7 +156,7 @@ function mnet_server_strip_wrappers($HTTP_RAW_POST_DATA) {
$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;
}
}
}
Expand All @@ -170,12 +179,12 @@ function mnet_server_strip_wrappers($HTTP_RAW_POST_DATA) {

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));
}

/**
Expand All @@ -194,7 +203,16 @@ function mnet_server_strip_wrappers($HTTP_RAW_POST_DATA) {
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'));
}
Expand Down

0 comments on commit 9dd0e61

Please sign in to comment.