1 22 package org.jboss.security.srp; 23 24 import java.io.Serializable ; 25 import java.math.BigInteger ; 26 import java.security.MessageDigest ; 27 import java.security.NoSuchAlgorithmException ; 28 import java.util.Arrays ; 29 30 import org.jboss.logging.Logger; 31 import org.jboss.security.Util; 32 33 60 public class SRPServerSession implements Serializable 61 { 62 65 static final long serialVersionUID = -2448005747721323704L; 66 private static int B_LEN = 64; private static Logger log = Logger.getLogger(SRPServerSession.class); 68 69 private SRPParameters params; 70 private BigInteger N; 71 private BigInteger g; 72 private BigInteger v; 73 private BigInteger b; 74 private BigInteger B; 75 private byte[] K; 76 77 private transient MessageDigest clientHash; 78 private byte[] M1; 79 80 private transient MessageDigest serverHash; 81 private byte[] M2; 82 83 89 public SRPServerSession(String username, byte[] vb, SRPParameters params) 90 { 91 this.params = params; 92 this.v = new BigInteger (1, vb); 93 this.g = new BigInteger (1, params.g); 94 this.N = new BigInteger (1, params.N); 95 if( log.isTraceEnabled() ) 96 log.trace("g: "+Util.tob64(params.g)); 97 if( log.isTraceEnabled() ) 98 log.trace("v: "+Util.tob64(vb)); 99 serverHash = Util.newDigest(); 100 clientHash = Util.newDigest(); 101 byte[] hn = Util.newDigest().digest(params.N); 103 if( log.isTraceEnabled() ) 104 log.trace("H(N): "+Util.tob64(hn)); 105 byte[] hg = Util.newDigest().digest(params.g); 107 if( log.isTraceEnabled() ) 108 log.trace("H(g): "+Util.tob64(hg)); 109 byte[] hxg = Util.xor(hn, hg, 20); 111 if( log.isTraceEnabled() ) 112 log.trace("H(N) xor H(g): "+Util.tob64(hxg)); 113 clientHash.update(hxg); 114 if( log.isTraceEnabled() ) 115 { 116 MessageDigest tmp = Util.copy(clientHash); 117 log.trace("H[H(N) xor H(g)]: "+Util.tob64(tmp.digest())); 118 } 119 clientHash.update(Util.newDigest().digest(username.getBytes())); 121 if( log.isTraceEnabled() ) 122 { 123 MessageDigest tmp = Util.copy(clientHash); 124 log.trace("H[H(N) xor H(g) | H(U)]: "+Util.tob64(tmp.digest())); 125 } 126 clientHash.update(params.s); 128 if( log.isTraceEnabled() ) 129 { 130 MessageDigest tmp = Util.copy(clientHash); 131 log.trace("H[H(N) xor H(g) | H(U) | s]: "+Util.tob64(tmp.digest())); 132 } 133 K = null; 134 } 135 136 139 public SRPParameters getParameters() 140 { 141 return params; 142 } 143 144 148 public byte[] exponential() 149 { 150 if(B == null) 151 { 152 BigInteger one = BigInteger.valueOf(1); 153 do 154 { 155 b = new BigInteger (B_LEN, Util.getPRNG()); 156 } while(b.compareTo(one) <= 0); 157 B = v.add(g.modPow(b, N)); 158 if(B.compareTo(N) >= 0) 159 B = B.subtract(N); 160 } 161 return Util.trim(B.toByteArray()); 162 } 163 164 170 public void buildSessionKey(byte[] ab) throws NoSuchAlgorithmException 171 { 172 if( log.isTraceEnabled() ) 173 log.trace("A: "+Util.tob64(ab)); 174 byte[] nb = Util.trim(B.toByteArray()); 175 clientHash.update(ab); 177 if( log.isTraceEnabled() ) 178 { 179 MessageDigest tmp = Util.copy(clientHash); 180 log.trace("H[H(N) xor H(g) | H(U) | s | A]: "+Util.tob64(tmp.digest())); 181 } 182 clientHash.update(nb); 184 if( log.isTraceEnabled() ) 185 { 186 MessageDigest tmp = Util.copy(clientHash); 187 log.trace("H[H(N) xor H(g) | H(U) | s | A | B]: "+Util.tob64(tmp.digest())); 188 } 189 serverHash.update(ab); 191 byte[] hB = Util.newDigest().digest(nb); 193 byte[] ub = 194 {hB[0], hB[1], hB[2], hB[3]}; 195 BigInteger A = new BigInteger (1, ab); 197 if( log.isTraceEnabled() ) 198 log.trace("A: "+Util.tob64(A.toByteArray())); 199 if( log.isTraceEnabled() ) 200 log.trace("B: "+Util.tob64(B.toByteArray())); 201 if( log.isTraceEnabled() ) 202 log.trace("v: "+Util.tob64(v.toByteArray())); 203 BigInteger u = new BigInteger (1, ub); 204 if( log.isTraceEnabled() ) 205 log.trace("u: "+Util.tob64(u.toByteArray())); 206 BigInteger A_v2u = A.multiply(v.modPow(u, N)).mod(N); 207 if( log.isTraceEnabled() ) 208 log.trace("A * v^u: "+Util.tob64(A_v2u.toByteArray())); 209 BigInteger S = A_v2u.modPow(b, N); 210 if( log.isTraceEnabled() ) 211 log.trace("S: "+Util.tob64(S.toByteArray())); 212 MessageDigest sessionDigest = MessageDigest.getInstance(params.hashAlgorithm); 214 K = sessionDigest.digest(S.toByteArray()); 215 if( log.isTraceEnabled() ) 216 log.trace("K: "+Util.tob64(K)); 217 clientHash.update(K); 219 if( log.isTraceEnabled() ) 220 { 221 MessageDigest tmp = Util.copy(clientHash); 222 log.trace("H[H(N) xor H(g) | H(U) | s | A | B | K]: "+Util.tob64(tmp.digest())); 223 } 224 } 225 226 231 public byte[] getSessionKey() throws SecurityException 232 { 233 SecurityManager sm = System.getSecurityManager(); 234 if( sm != null ) 235 { 236 SRPPermission p = new SRPPermission("getSessionKey"); 237 sm.checkPermission(p); 238 } 239 return K; 240 } 241 242 245 public byte[] getServerResponse() 246 { 247 if( M2 == null ) 248 M2 = serverHash.digest(); 249 return M2; 250 } 251 public byte[] getClientResponse() 252 { 253 return M1; 254 } 255 256 260 public boolean verify(byte[] clientM1) 261 { 262 boolean valid = false; 263 M1 = clientHash.digest(); 265 if( log.isTraceEnabled() ) 266 { 267 log.trace("verify M1: "+Util.tob64(M1)); 268 log.trace("verify clientM1: "+Util.tob64(clientM1)); 269 } 270 if( Arrays.equals(clientM1, M1) ) 271 { 272 serverHash.update(M1); 274 serverHash.update(K); 276 if( log.isTraceEnabled() ) 277 { 278 MessageDigest tmp = Util.copy(serverHash); 279 log.trace("H(A | M1 | K)"+Util.tob64(tmp.digest())); 280 } 281 valid = true; 282 } 283 return valid; 284 } 285 } 286 | Popular Tags |