Permalink
Browse files

first cut of SCRAM-SHA-1 authentication mechanism (kind of broken as …

…of now)
  • Loading branch information...
1 parent fe869cf commit 0ea119dd830336aa0a890038777794c0b4a5d76c @abhinavsingh abhinavsingh committed Jul 22, 2012
Showing with 62 additions and 0 deletions.
  1. +4 −0 core/jaxl_util.php
  2. +56 −0 jaxl.php
  3. +2 −0 xmpp/xmpp_stream.php
View
@@ -58,6 +58,10 @@ public static function get_dns_srv($domain) {
}
}
+ public static function pbkdf2($data, $secret, $iteration, $dkLen=32, $algo='sha1') {
+ return '';
+ }
+
}
?>
View
@@ -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) {
if($this->ev->exists('on_stream_features')) {
return $this->ev->emit('on_stream_features', array($stanza));
@@ -558,6 +611,9 @@ public function handle_auth_mechs($stanza, $mechanisms) {
else if($pref_auth == 'CRAM-MD5') {
return "wait_for_cram_md5_response";
}
+ else if($pref_auth == 'SCRAM-SHA-1') {
+ return "wait_for_scram_sha1_response";
+ }
}
public function handle_auth_success() {
View
@@ -159,6 +159,8 @@ public function get_auth_pkt($mechanism, $user, $pass) {
case 'CRAM-MD5':
break;
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;
case 'ANONYMOUS':
break;

0 comments on commit 0ea119d

Please sign in to comment.