summaryrefslogtreecommitdiff
path: root/src/org/jboss/security/srp/SRPServerSession.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/jboss/security/srp/SRPServerSession.java')
-rw-r--r--src/org/jboss/security/srp/SRPServerSession.java285
1 files changed, 0 insertions, 285 deletions
diff --git a/src/org/jboss/security/srp/SRPServerSession.java b/src/org/jboss/security/srp/SRPServerSession.java
deleted file mode 100644
index 11dc6d4c..00000000
--- a/src/org/jboss/security/srp/SRPServerSession.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.security.srp;
-
-import java.io.Serializable;
-import java.math.BigInteger;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-
-import org.jboss.logging.Logger;
-import org.jboss.crypto.CryptoUtil;
-
-/** The server side logic to the SRP protocol. The class is the server side
- equivalent of the SRPClientSession object. An implementation of
- SRPServerInterface creates an SRPServerSession on the start of a login
- session.
-
- The client side algorithm using these classes consists of:
-
- 1. Get server, SRPServerInterface server = (SRPServerInterface) Naming.lookup(...);
- 2. Get SRP parameters, SRPParameters params = server.getSRPParameters(username);
- 3. Create a client session, SRPClientSession client = new SRPClientSession(username, password, params);
- 4. Exchange public keys, byte[] A = client.exponential();
- byte[] B = server.init(username, A);
- 5. Exchange challenges, byte[] M1 = client.response(B);
- byte[] M2 = server.verify(username, M1);
- 6. Verify the server response, if( client.verify(M2) == false )
- throw new SecurityException("Failed to validate server reply");
- 7. Validation complete
-
- Note that these steps are stateful. They must be performed in order and a
- step cannot be repeated to update the session state.
-
- This product uses the 'Secure Remote Password' cryptographic
- authentication system developed by Tom Wu (tjw@CS.Stanford.EDU).
-
- @author Scott.Stark@jboss.org
- @version $Revision: 81038 $
- */
-public class SRPServerSession implements Serializable
-{
- /** The serial version ID
- @since 1.6
- */
- static final long serialVersionUID = -2448005747721323704L;
- private static int B_LEN = 64; // 64 bits for 'b'
- private static Logger log = Logger.getLogger(SRPServerSession.class);
-
- private SRPParameters params;
- private BigInteger N;
- private BigInteger g;
- private BigInteger v;
- private BigInteger b;
- private BigInteger B;
- private byte[] K;
- /** The M1 = H(H(N) xor H(g) | H(U) | s | A | B | K) hash */
- private transient MessageDigest clientHash;
- private byte[] M1;
- /** The M2 = H(A | M | K) hash */
- private transient MessageDigest serverHash;
- private byte[] M2;
-
- /** Creates a new SRP server session object from the username, password
- verifier, and session parameters.
- @param username, the user ID
- @param vb, the password verifier byte sequence
- @param params, the SRP parameters for the session
- */
- public SRPServerSession(String username, byte[] vb, SRPParameters params)
- {
- this.params = params;
- this.v = new BigInteger(1, vb);
- this.g = new BigInteger(1, params.g);
- this.N = new BigInteger(1, params.N);
- if( log.isTraceEnabled() )
- log.trace("g: "+CryptoUtil.tob64(params.g));
- if( log.isTraceEnabled() )
- log.trace("v: "+CryptoUtil.tob64(vb));
- serverHash = CryptoUtil.newDigest();
- clientHash = CryptoUtil.newDigest();
- // H(N)
- byte[] hn = CryptoUtil.newDigest().digest(params.N);
- if( log.isTraceEnabled() )
- log.trace("H(N): "+CryptoUtil.tob64(hn));
- // H(g)
- byte[] hg = CryptoUtil.newDigest().digest(params.g);
- if( log.isTraceEnabled() )
- log.trace("H(g): "+CryptoUtil.tob64(hg));
- // clientHash = H(N) xor H(g)
- byte[] hxg = CryptoUtil.xor(hn, hg, 20);
- if( log.isTraceEnabled() )
- log.trace("H(N) xor H(g): "+CryptoUtil.tob64(hxg));
- clientHash.update(hxg);
- if( log.isTraceEnabled() )
- {
- MessageDigest tmp = CryptoUtil.copy(clientHash);
- log.trace("H[H(N) xor H(g)]: "+CryptoUtil.tob64(tmp.digest()));
- }
- // clientHash = H(N) xor H(g) | H(U)
- clientHash.update(CryptoUtil.newDigest().digest(username.getBytes()));
- if( log.isTraceEnabled() )
- {
- MessageDigest tmp = CryptoUtil.copy(clientHash);
- log.trace("H[H(N) xor H(g) | H(U)]: "+CryptoUtil.tob64(tmp.digest()));
- }
- // clientHash = H(N) xor H(g) | H(U) | s
- clientHash.update(params.s);
- if( log.isTraceEnabled() )
- {
- MessageDigest tmp = CryptoUtil.copy(clientHash);
- log.trace("H[H(N) xor H(g) | H(U) | s]: "+CryptoUtil.tob64(tmp.digest()));
- }
- K = null;
- }
-
- /**
- * @returns The user's password salt
- */
- public SRPParameters getParameters()
- {
- return params;
- }
-
- /**
- * @returns The exponential residue (parameter B) to be sent to the
- * client.
- */
- public byte[] exponential()
- {
- if(B == null)
- {
- BigInteger one = BigInteger.valueOf(1);
- do
- {
- b = new BigInteger(B_LEN, CryptoUtil.getPRNG());
- } while(b.compareTo(one) <= 0);
- B = v.add(g.modPow(b, N));
- if(B.compareTo(N) >= 0)
- B = B.subtract(N);
- }
- return CryptoUtil.trim(B.toByteArray());
- }
-
- /**
- @param ab The client's exponential (parameter A).
- @returns The secret shared session K between client and server
- @exception NoSuchAlgorithmException thrown if the session key
- MessageDigest algorithm cannot be found.
- */
- public void buildSessionKey(byte[] ab) throws NoSuchAlgorithmException
- {
- if( log.isTraceEnabled() )
- log.trace("A: "+CryptoUtil.tob64(ab));
- byte[] nb = CryptoUtil.trim(B.toByteArray());
- // clientHash = H(N) xor H(g) | H(U) | s | A
- clientHash.update(ab);
- if( log.isTraceEnabled() )
- {
- MessageDigest tmp = CryptoUtil.copy(clientHash);
- log.trace("H[H(N) xor H(g) | H(U) | s | A]: "+CryptoUtil.tob64(tmp.digest()));
- }
- // clientHash = H(N) xor H(g) | H(U) | A | B
- clientHash.update(nb);
- if( log.isTraceEnabled() )
- {
- MessageDigest tmp = CryptoUtil.copy(clientHash);
- log.trace("H[H(N) xor H(g) | H(U) | s | A | B]: "+CryptoUtil.tob64(tmp.digest()));
- }
- // serverHash = A
- serverHash.update(ab);
- // Calculate u as the first 32 bits of H(B)
- byte[] hB = CryptoUtil.newDigest().digest(nb);
- byte[] ub =
- {hB[0], hB[1], hB[2], hB[3]};
- // Calculate S = (A * v^u) ^ b % N
- BigInteger A = new BigInteger(1, ab);
- if( log.isTraceEnabled() )
- log.trace("A: "+CryptoUtil.tob64(A.toByteArray()));
- if( log.isTraceEnabled() )
- log.trace("B: "+CryptoUtil.tob64(B.toByteArray()));
- if( log.isTraceEnabled() )
- log.trace("v: "+CryptoUtil.tob64(v.toByteArray()));
- BigInteger u = new BigInteger(1, ub);
- if( log.isTraceEnabled() )
- log.trace("u: "+CryptoUtil.tob64(u.toByteArray()));
- BigInteger A_v2u = A.multiply(v.modPow(u, N)).mod(N);
- if( log.isTraceEnabled() )
- log.trace("A * v^u: "+CryptoUtil.tob64(A_v2u.toByteArray()));
- BigInteger S = A_v2u.modPow(b, N);
- if( log.isTraceEnabled() )
- log.trace("S: "+CryptoUtil.tob64(S.toByteArray()));
- // K = SessionHash(S)
- MessageDigest sessionDigest = MessageDigest.getInstance(params.hashAlgorithm);
- K = sessionDigest.digest(S.toByteArray());
- if( log.isTraceEnabled() )
- log.trace("K: "+CryptoUtil.tob64(K));
- // clientHash = H(N) xor H(g) | H(U) | A | B | K
- clientHash.update(K);
- if( log.isTraceEnabled() )
- {
- MessageDigest tmp = CryptoUtil.copy(clientHash);
- log.trace("H[H(N) xor H(g) | H(U) | s | A | B | K]: "+CryptoUtil.tob64(tmp.digest()));
- }
- }
-
- /** Returns the negotiated session K, K = SessionHash(S)
- @return the private session K byte[]
- @throws SecurityException - if the current thread does not have an
- getSessionKey SRPPermission.
- */
- public byte[] getSessionKey() throws SecurityException
- {
- SecurityManager sm = System.getSecurityManager();
- if( sm != null )
- {
- SRPPermission p = new SRPPermission("getSessionKey");
- sm.checkPermission(p);
- }
- return K;
- }
-
- /**
- @returns M2 = H(A | M | K)
- */
- public byte[] getServerResponse()
- {
- if( M2 == null )
- M2 = serverHash.digest();
- return M2;
- }
- public byte[] getClientResponse()
- {
- return M1;
- }
-
- /**
- * @param resp The client's response to the server's challenge
- * @returns True if and only if the client's response was correct.
- */
- public boolean verify(byte[] clientM1)
- {
- boolean valid = false;
- // M1 = H(H(N) xor H(g) | H(U) | A | B | K)
- M1 = clientHash.digest();
- if( log.isTraceEnabled() )
- {
- log.trace("verify M1: "+CryptoUtil.tob64(M1));
- log.trace("verify clientM1: "+CryptoUtil.tob64(clientM1));
- }
- if( Arrays.equals(clientM1, M1) )
- {
- // serverHash = A | M
- serverHash.update(M1);
- // serverHash = A | M | K
- serverHash.update(K);
- if( log.isTraceEnabled() )
- {
- MessageDigest tmp = CryptoUtil.copy(serverHash);
- log.trace("H(A | M1 | K)"+CryptoUtil.tob64(tmp.digest()));
- }
- valid = true;
- }
- return valid;
- }
-}