Skip to content

Commit

Permalink
first cut of SCRAM-SHA-1 authentication mechanism (kind of broken as …
Browse files Browse the repository at this point in the history
…of now)
  • Loading branch information
abhinavsingh committed Jul 22, 2012
1 parent fe869cf commit 0ea119d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
4 changes: 4 additions & 0 deletions core/jaxl_util.php
Expand Up @@ -58,6 +58,10 @@ public static function get_dns_srv($domain) {
} }
} }


public static function pbkdf2($data, $secret, $iteration, $dkLen=32, $algo='sha1') {
return '';
}

} }


?> ?>
56 changes: 56 additions & 0 deletions jaxl.php
Expand Up @@ -520,6 +520,59 @@ public function wait_for_cram_md5_response($event, $args) {
} }
} }


public function get_scram_sha1_response($pass, $challenge) {
// it contains users iteration count i and the user salt
// also server will append it's own nonce to the one we specified
$decoded = $this->explode_data(base64_decode($challenge));

// r=,s=,i=
$nonce = $decoded['r'];
$salt = base64_decode($decoded['s']);
$iteration = intval($decoded['i']);

// SaltedPassword := Hi(Normalize(password), salt, i)
$salted = JAXLUtil::pbkdf2($this->pass, $salt, $iteration);
// ClientKey := HMAC(SaltedPassword, "Client Key")
$client_key = hash_hmac('sha1', $salted, "Client Key", true);
// StoredKey := H(ClientKey)
$stored_key = hash('sha1', $client_key, true);
// AuthMessage := client-first-message-bare + "," + server-first-message + "," + client-final-message-without-proof
$auth_message = '';
// ClientSignature := HMAC(StoredKey, AuthMessage)
$signature = hash_hmac('sha1', $stored_key, $auth_message, true);
// ClientProof := ClientKey XOR ClientSignature
$client_proof = $client_key ^ $signature;

$proof = 'c=biws,r='.$nonce.',p='.base64_encode($client_proof);
return base64_encode($proof);
}

public function wait_for_scram_sha1_response($event, $args) {
switch($event) {
case "stanza_cb":
$stanza = $args[0];

if($stanza->name == 'challenge' && $stanza->ns == NS_SASL) {
$challenge = $stanza->text;

$resp = new JAXLXml('response', NS_SASL);
$resp->t($this->get_scram_sha1_response($this->pass, $challenge));
$this->send($resp);

return "wait_for_sasl_response";
}
else {
_debug("got unhandled sasl response, should never happen here");
exit;
}
break;
default:
_debug("not catched $event, should never happen here");
exit;
break;
}
}

public function handle_auth_mechs($stanza, $mechanisms) { public function handle_auth_mechs($stanza, $mechanisms) {
if($this->ev->exists('on_stream_features')) { if($this->ev->exists('on_stream_features')) {
return $this->ev->emit('on_stream_features', array($stanza)); return $this->ev->emit('on_stream_features', array($stanza));
Expand Down Expand Up @@ -558,6 +611,9 @@ public function handle_auth_mechs($stanza, $mechanisms) {
else if($pref_auth == 'CRAM-MD5') { else if($pref_auth == 'CRAM-MD5') {
return "wait_for_cram_md5_response"; return "wait_for_cram_md5_response";
} }
else if($pref_auth == 'SCRAM-SHA-1') {
return "wait_for_scram_sha1_response";
}
} }


public function handle_auth_success() { public function handle_auth_success() {
Expand Down
2 changes: 2 additions & 0 deletions xmpp/xmpp_stream.php
Expand Up @@ -159,6 +159,8 @@ public function get_auth_pkt($mechanism, $user, $pass) {
case 'CRAM-MD5': case 'CRAM-MD5':
break; break;
case 'SCRAM-SHA-1': case 'SCRAM-SHA-1':
// client first message always starts with n, y or p for GS2 extensibility
$stanza->t(base64_encode("n,,n=".$user.",r=".JAXLUtil::get_nonce(false)));
break; break;
case 'ANONYMOUS': case 'ANONYMOUS':
break; break;
Expand Down

0 comments on commit 0ea119d

Please sign in to comment.