1 22 package org.jboss.security.srp; 23 24 import java.io.IOException ; 25 import java.rmi.RemoteException ; 26 import java.rmi.server.RMIClientSocketFactory ; 27 import java.rmi.server.RMIServerSocketFactory ; 28 import java.rmi.server.UnicastRemoteObject ; 29 import java.security.GeneralSecurityException ; 30 import java.security.KeyException ; 31 import java.security.NoSuchAlgorithmException ; 32 import java.util.Collections ; 33 import java.util.HashMap ; 34 import java.util.Map ; 35 import javax.crypto.SealedObject; 36 37 import org.jboss.logging.Logger; 38 import org.jboss.security.Util; 39 import org.jboss.security.srp.SRPVerifierStore.VerifierInfo; 40 41 46 public class SRPRemoteServer extends UnicastRemoteObject implements SRPRemoteServerInterface 47 { 48 private static Logger log = Logger.getLogger(SRPRemoteServer.class); 49 50 private static int userSessionCount = 0; 51 52 private Map sessionMap = Collections.synchronizedMap(new HashMap ()); 53 54 55 private SRPVerifierStore verifierStore; 56 57 private SRPServerListener listener; 58 59 private boolean requireAuxChallenge; 60 61 public SRPRemoteServer(SRPVerifierStore verifierStore) throws RemoteException 62 { 63 setVerifierStore(verifierStore); 64 } 65 66 public SRPRemoteServer(SRPVerifierStore verifierStore, int port) throws RemoteException 67 { 68 super(port); 69 setVerifierStore(verifierStore); 70 } 71 72 public SRPRemoteServer(SRPVerifierStore verifierStore, int port, RMIClientSocketFactory csf, 73 RMIServerSocketFactory ssf) throws RemoteException 74 { 75 super(port, csf, ssf); 76 setVerifierStore(verifierStore); 77 } 78 79 81 public void setVerifierStore(SRPVerifierStore verifierStore) 82 { 83 this.verifierStore = verifierStore; 84 log.info("setVerifierStore, " + verifierStore); 85 } 86 87 public void addSRPServerListener(SRPServerListener listener) 88 { 89 this.listener = listener; 90 } 91 92 public void removeSRPServerListener(SRPServerListener listener) 93 { 94 if (this.listener == listener) 95 this.listener = null; 96 } 97 98 public boolean getRequireAuxChallenge() 99 { 100 return this.requireAuxChallenge; 101 } 102 public void setRequireAuxChallenge(boolean flag) 103 { 104 this.requireAuxChallenge = flag; 105 } 106 107 109 public SRPParameters getSRPParameters(String username) 110 throws KeyException , RemoteException 111 { 112 Object [] params = this.getSRPParameters(username,false); 113 SRPParameters srpParams = (SRPParameters) params[0]; 114 return srpParams; 115 } 116 117 public Object [] getSRPParameters(String username, boolean multipleSessions) 118 throws KeyException , RemoteException 119 { 120 boolean trace = log.isTraceEnabled(); 121 if( trace ) 122 log.trace("getSRPParameters, " + username); 123 SRPParameters params = null; 124 VerifierInfo info = null; 125 try 126 { 127 info = verifierStore.getUserVerifier(username); 128 if (info == null) 129 throw new KeyException ("Unknown username: " + username); 130 params = new SRPParameters(info.N, info.g, info.salt, 131 info.hashAlgorithm, info.cipherAlgorithm, info.cipherIV); 132 if (log.isTraceEnabled()) 133 { 134 log.trace("Params: " + params); 135 byte[] hn = Util.newDigest().digest(params.N); 136 log.trace("H(N): " + Util.tob64(hn)); 137 byte[] hg = Util.newDigest().digest(params.g); 138 log.trace("H(g): " + Util.tob64(hg)); 139 } 140 } 141 catch (IOException e) 142 { 143 throw new RemoteException ("Error during user info retrieval", e); 144 } 145 catch (KeyException e) 146 { 147 throw e; 148 } 149 catch (Throwable t) 150 { 151 log.error("Unexpected exception in getSRPParameters", t); 152 throw new RemoteException ("Unexpected exception in getSRPParameters", t); 153 } 154 155 Integer sessionID = SRPSessionKey.NO_SESSION_ID; 157 if( multipleSessions == true ) 158 sessionID = nextSessionID(); 159 Object [] sessionInfo = {params, sessionID}; 160 SRPSessionKey key = new SRPSessionKey(username, sessionID); 162 SRPServerSession session = new SRPServerSession(username, info.verifier, 163 params); 164 sessionMap.put(key, session); 165 if( trace ) 166 log.trace("getSRPParameters, completed " + key); 167 168 return sessionInfo; 169 } 170 171 public byte[] init(String username, byte[] A) throws SecurityException , 172 NoSuchAlgorithmException , RemoteException 173 { 174 return this.init(username, A, 0); 175 } 176 public byte[] init(String username, byte[] A, int sessionID) throws SecurityException , 177 NoSuchAlgorithmException , RemoteException 178 { 179 SRPSessionKey key = new SRPSessionKey(username, sessionID); 180 boolean trace = log.isTraceEnabled(); 181 if( trace ) 182 log.trace("init, " + key); 183 SRPServerSession session = (SRPServerSession) sessionMap.get(key); 184 if (session == null) 185 throw new SecurityException ("Failed to find active session for username: " + username); 186 187 byte[] B = session.exponential(); 188 session.buildSessionKey(A); 189 if( trace ) 190 log.trace("init, completed "+key); 191 return B; 192 } 193 194 public byte[] verify(String username, byte[] M1) 195 throws SecurityException , RemoteException 196 { 197 return this.verify(username, M1, null, 0); 198 } 199 public byte[] verify(String username, byte[] M1, int sessionID) 200 throws SecurityException , RemoteException 201 { 202 return this.verify(username, M1, null, sessionID); 203 } 204 205 218 public byte[] verify(String username, byte[] M1, Object auxChallenge) 219 throws SecurityException , RemoteException 220 { 221 return this.verify(username, M1, auxChallenge, 0); 222 } 223 public byte[] verify(String username, byte[] M1, Object auxChallenge, int sessionID) 224 throws SecurityException , RemoteException 225 { 226 SRPSessionKey key = new SRPSessionKey(username, sessionID); 227 boolean trace = log.isTraceEnabled(); 228 if( trace ) 229 log.trace("verify, " + key); 230 SRPServerSession session = (SRPServerSession) sessionMap.get(key); 231 if (session == null) 232 throw new SecurityException ("Failed to find active session for username: " + username); 233 234 if (session.verify(M1) == false) 235 throw new SecurityException ("Failed to verify M1"); 236 237 239 if( auxChallenge != null ) 240 { 241 if( auxChallenge instanceof SealedObject ) 243 { 244 if( trace ) 245 log.trace("Decrypting sealed object"); 246 SRPParameters params = session.getParameters(); 247 Object challenge = null; 248 try 249 { 250 byte[] skey = session.getSessionKey(); 251 Object tmpKey = Util.createSecretKey(params.cipherAlgorithm, skey); 252 challenge = Util.accessSealedObject(params.cipherAlgorithm, tmpKey, 253 params.cipherIV, auxChallenge); 254 } 255 catch (GeneralSecurityException e) 256 { 257 throw new RemoteException ("Failed to access SealedObject", e); 258 } 259 auxChallenge = challenge; 260 } 261 if( trace ) 262 log.trace("Verifing aux challenge"); 263 this.verifierStore.verifyUserChallenge(username, auxChallenge); 264 } 265 else if( requireAuxChallenge == true ) 266 { 267 throw new RemoteException ("A non-null auxChallenge is required for verification"); 268 } 269 270 if (listener != null) 272 listener.verifiedUser(key, session); 273 if( trace ) 274 log.trace("verify, completed " + key); 275 276 return session.getServerResponse(); 277 } 278 279 281 public void close(String username) throws SecurityException , RemoteException 282 { 283 this.close(username, 0); 284 } 285 public void close(String username, int sessionID) throws SecurityException , RemoteException 286 { 287 SRPSessionKey key = new SRPSessionKey(username, sessionID); 288 boolean trace = log.isTraceEnabled(); 289 if( trace ) 290 log.trace("close, " + key); 291 SRPServerSession session = (SRPServerSession) sessionMap.remove(key); 292 if (session == null) 293 throw new SecurityException ("Failed to find active session for username: " + username); 294 if (listener != null) 295 listener.closedUserSession(key); 296 if( trace ) 297 log.trace("close, completed " + key); 298 } 299 300 private static synchronized Integer nextSessionID() 301 { 302 return new Integer (userSessionCount ++); 303 } 304 } 305 | Popular Tags |