src/com/isode/stroke/sasl/SCRAMSHA1ClientAuthenticator.java
author Da Risk <da_risk@beem-project.com>
Sun, 15 Mar 2015 17:28:04 +0100
changeset 1043 7d6f2526244a
parent 1018 8daca77fabc1
permissions -rw-r--r--
Use latest gradle
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1015
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
     1
/*
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
     2
 * Copyright (c) 2010, Isode Limited, London, England.
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
     3
 * All rights reserved.
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
     4
 */
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
     5
/*
1018
8daca77fabc1 fix Remko's currly part of name
Jiří Pinkava <j-pi@seznam.cz>
parents: 1015
diff changeset
     6
 * Copyright (c) 2010, Remko Tronçon.
1015
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
     7
 * All rights reserved.
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
     8
 */
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
     9
package com.isode.stroke.sasl;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    10
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    11
import com.isode.stroke.base.ByteArray;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    12
import com.isode.stroke.stringcodecs.Base64;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    13
import com.isode.stroke.stringcodecs.HMACSHA1;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    14
import com.isode.stroke.stringcodecs.PBKDF2;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    15
import com.isode.stroke.stringcodecs.SHA1;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    16
import java.text.Normalizer;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    17
import java.text.Normalizer.Form;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    18
import java.util.HashMap;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    19
import java.util.Map;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    20
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    21
public class SCRAMSHA1ClientAuthenticator extends ClientAuthenticator {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    22
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    23
    static String escape(String s) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    24
        String result = "";
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    25
        for (int i = 0; i < s.length(); ++i) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    26
            if (s.charAt(i) == ',') {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    27
                result += "=2C";
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    28
            } else if (s.charAt(i) == '=') {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    29
                result += "=3D";
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    30
            } else {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    31
                result += s.charAt(i);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    32
            }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    33
        }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    34
        return result;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    35
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    36
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    37
    public SCRAMSHA1ClientAuthenticator(String nonce) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    38
        this(nonce, false);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    39
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    40
    public SCRAMSHA1ClientAuthenticator(String nonce, boolean useChannelBinding) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    41
        super(useChannelBinding ? "SCRAM-SHA-1-PLUS" : "SCRAM-SHA-1");
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    42
        step = Step.Initial;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    43
        clientnonce = nonce;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    44
        this.useChannelBinding = useChannelBinding;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    45
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    46
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    47
    public void setTLSChannelBindingData(ByteArray channelBindingData) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    48
        tlsChannelBindingData = channelBindingData;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    49
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    50
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    51
    public ByteArray getResponse() {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    52
        if (step.equals(Step.Initial)) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    53
            return ByteArray.plus(getGS2Header(), getInitialBareClientMessage());
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    54
        } else if (step.equals(Step.Proof)) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    55
            ByteArray clientKey = HMACSHA1.getResult(saltedPassword, new ByteArray("Client Key"));
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    56
            ByteArray storedKey = SHA1.getHash(clientKey);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    57
            ByteArray clientSignature = HMACSHA1.getResult(storedKey, authMessage);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    58
            ByteArray clientProof = clientKey;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    59
            byte[] clientProofData = clientProof.getData();
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    60
            for (int i = 0; i < clientProofData.length; ++i) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    61
                clientProofData[i] ^= clientSignature.getData()[i];
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    62
            }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    63
            ByteArray result = getFinalMessageWithoutProof().append(",p=").append(Base64.encode(clientProof));
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    64
            return result;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    65
        } else {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    66
            return null;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    67
        }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    68
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    69
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    70
    public boolean setChallenge(ByteArray challenge) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    71
        if (step.equals(Step.Initial)) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    72
            if (challenge == null) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    73
                return false;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    74
            }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    75
            initialServerMessage = challenge;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    76
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    77
            Map<Character, String> keys = parseMap(initialServerMessage.toString());
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    78
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    79
            // Extract the salt
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    80
            ByteArray salt = Base64.decode(keys.get('s'));
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    81
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    82
            // Extract the server nonce
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    83
            String clientServerNonce = keys.get('r');
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    84
            if (clientServerNonce.length() <= clientnonce.length()) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    85
                return false;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    86
            }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    87
            String receivedClientNonce = clientServerNonce.substring(0, clientnonce.length());
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    88
            if (!receivedClientNonce.equals(clientnonce)) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    89
                return false;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    90
            }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    91
            serverNonce = new ByteArray(clientServerNonce.substring(clientnonce.length()));
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    92
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    93
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    94
            // Extract the number of iterations
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    95
            int iterations = 0;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    96
            try {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    97
                iterations = Integer.parseInt(keys.get('i'));
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    98
            } catch (NumberFormatException e) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
    99
                return false;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   100
            }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   101
            if (iterations <= 0) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   102
                return false;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   103
            }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   104
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   105
            ByteArray channelBindData = new ByteArray();
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   106
            if (useChannelBinding && tlsChannelBindingData != null) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   107
                channelBindData = tlsChannelBindingData;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   108
            }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   109
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   110
            // Compute all the values needed for the server signature
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   111
            saltedPassword = PBKDF2.encode(new ByteArray(SASLPrep(getPassword())), salt, iterations);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   112
            authMessage = getInitialBareClientMessage().append(",").append(initialServerMessage).append(",").append(getFinalMessageWithoutProof());
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   113
            ByteArray serverKey = HMACSHA1.getResult(saltedPassword, new ByteArray("Server Key"));
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   114
            serverSignature = HMACSHA1.getResult(serverKey, authMessage);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   115
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   116
            step = Step.Proof;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   117
            return true;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   118
        } else if (step.equals(step.Proof)) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   119
            ByteArray result = new ByteArray("v=").append(new ByteArray(Base64.encode(serverSignature)));
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   120
            step = Step.Final;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   121
            return challenge != null && challenge.equals(result);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   122
        } else {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   123
            return true;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   124
        }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   125
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   126
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   127
    private String SASLPrep(String source) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   128
        return Normalizer.normalize(source, Form.NFKC); /* FIXME: Implement real SASLPrep */
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   129
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   130
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   131
    private Map<Character, String> parseMap(String s) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   132
        HashMap<Character, String> result = new HashMap<Character, String>();
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   133
        if (s.length() > 0) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   134
            char key = '~'; /* initialise so it'll compile */
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   135
            String value = "";
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   136
            int i = 0;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   137
            boolean expectKey = true;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   138
            while (i < s.length()) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   139
                if (expectKey) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   140
                    key = s.charAt(i);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   141
                    expectKey = false;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   142
                    i++;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   143
                } else if (s.charAt(i) == ',') {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   144
                    result.put(key, value);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   145
                    value = "";
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   146
                    expectKey = true;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   147
                } else {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   148
                    value += s.charAt(i);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   149
                }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   150
                i++;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   151
            }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   152
            result.put(key, value);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   153
        }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   154
        return result;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   155
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   156
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   157
    private ByteArray getInitialBareClientMessage() {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   158
        String authenticationID = SASLPrep(getAuthenticationID());
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   159
        return new ByteArray("n=" + escape(authenticationID) + ",r=" + clientnonce);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   160
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   161
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   162
    private ByteArray getGS2Header() {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   163
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   164
        ByteArray channelBindingHeader = new ByteArray("n");
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   165
	if (tlsChannelBindingData != null) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   166
		if (useChannelBinding) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   167
			channelBindingHeader = new ByteArray("p=tls-unique");
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   168
		}
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   169
		else {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   170
			channelBindingHeader = new ByteArray("y");
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   171
		}
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   172
	}
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   173
	return new ByteArray().append(channelBindingHeader).append(",").append(getAuthorizationID().isEmpty() ? new ByteArray() : new ByteArray("a=" + escape(getAuthorizationID()))).append(",");
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   174
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   175
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   176
    private ByteArray getFinalMessageWithoutProof() {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   177
        ByteArray channelBindData = new ByteArray();
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   178
	if (useChannelBinding && tlsChannelBindingData != null) {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   179
		channelBindData = tlsChannelBindingData;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   180
	}
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   181
	return new ByteArray("c=" + Base64.encode(new ByteArray(getGS2Header()).append(channelBindData)) + ",r=" + clientnonce).append(serverNonce);
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   182
    }
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   183
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   184
    private enum Step {
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   185
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   186
        Initial,
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   187
        Proof,
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   188
        Final
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   189
    };
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   190
    private Step step;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   191
    private String clientnonce = "";
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   192
    private ByteArray initialServerMessage = new ByteArray();
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   193
    private ByteArray serverNonce = new ByteArray();
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   194
    private ByteArray authMessage = new ByteArray();
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   195
    private ByteArray saltedPassword = new ByteArray();
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   196
    private ByteArray serverSignature = new ByteArray();
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   197
    private boolean useChannelBinding;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   198
    private ByteArray tlsChannelBindingData;
63669480c941 Add an implementation of the SCRAM-SHA-! SASL mechanism.
Da Risk <da_risk@beem-project.com>
parents:
diff changeset
   199
}