001package com.bitbucket.thinbus.srp6.js;
002
003import com.nimbusds.srp6.XRoutine;
004
005import java.math.BigInteger;
006import java.security.MessageDigest;
007
008import static com.nimbusds.srp6.BigIntegerUtils.fromHex;
009import static com.nimbusds.srp6.BigIntegerUtils.toHex;
010
011public class HexHashedXRoutine implements XRoutine {
012
013        final BigInteger N;
014
015        public HexHashedXRoutine(BigInteger N){
016                this.N = N;
017        }
018
019        /**
020         * Computes the password key 'x'.
021         *
022         * @param digest
023         *            The hash function 'H'.
024         * @param salt
025         *            The salt 's'. This is considered a mandatory argument in
026         *            computation of 'x'. Must not be {@code null} or empty.
027         * @param username
028         *            The user identity 'I'. Must not be {@code null} or empty.
029         * @param password
030         *            The user password 'P'. This is considered a mandatory argument
031         *            in the computation of 'x'. Must not be {@code null} or empty.
032         *
033         * @return The resulting 'x' value.
034         */
035        @Override
036        public BigInteger computeX(MessageDigest digest, byte[] salt,
037                        byte[] username, byte[] password) {
038                final String i = new String(username, HexHashedRoutines.utf8);
039                final String p = new String(password, HexHashedRoutines.utf8);
040                final String s = toHex(new BigInteger(1, salt));
041
042                if (i == null || i.trim().isEmpty())
043                        throw new IllegalArgumentException(
044                                        "The user identity 'I' must not be null or empty");
045
046                if (p == null || p.trim().isEmpty())
047                        throw new IllegalArgumentException(
048                                        "The user password 'P' must not be null or empty");
049
050                if (s == null || s.trim().isEmpty())
051                        throw new IllegalArgumentException(
052                                        "The user salt 's' must not be null or empty");
053
054                final String hash = HexHashedRoutines.hashCredentials(digest, s, i, p);
055                final BigInteger X = fromHex(hash).mod(N);
056                return X;
057        }
058
059}