1 23 24 29 30 package com.sun.enterprise.webservice; 31 32 import java.io.IOException ; 33 import java.math.BigInteger ; 34 import java.security.Key ; 35 import java.security.KeyStore ; 36 import java.security.KeyStore.PrivateKeyEntry; 37 import java.security.KeyStoreException ; 38 import java.security.InvalidAlgorithmParameterException ; 39 import java.security.NoSuchAlgorithmException ; 40 import java.security.PrivateKey ; 41 import java.security.cert.Certificate ; 42 import java.security.cert.CertStore ; 43 import java.security.cert.CollectionCertStoreParameters ; 44 import java.security.cert.X509Certificate ; 45 import java.util.ArrayList ; 46 import java.util.Arrays ; 47 import java.util.Enumeration ; 48 import java.util.List ; 49 import java.util.logging.Level ; 50 import java.util.logging.Logger ; 51 52 import javax.crypto.SecretKey; 53 import javax.security.auth.x500.X500Principal ; 54 import javax.security.auth.callback.Callback ; 55 import javax.security.auth.callback.CallbackHandler ; 56 import javax.security.auth.callback.UnsupportedCallbackException ; 57 58 import com.sun.enterprise.security.jauth.callback.CertStoreCallback; 59 import com.sun.enterprise.security.jauth.callback.PasswordValidationCallback; 60 import com.sun.enterprise.security.jauth.callback.PrivateKeyCallback; 61 import com.sun.enterprise.security.jauth.callback.SecretKeyCallback; 62 import com.sun.enterprise.security.jauth.callback.TrustStoreCallback; 63 64 import com.sun.enterprise.Switch; 65 import com.sun.enterprise.security.SecurityUtil; 66 import com.sun.enterprise.security.SSLUtils; 67 import com.sun.enterprise.security.auth.LoginContextDriver; 68 import com.sun.enterprise.security.LoginException; 69 import com.sun.enterprise.security.auth.realm.Realm; 70 import com.sun.enterprise.webservice.AppclientWSSCallbackHandler; 71 import com.sun.enterprise.webservice.EjbServletWSSCallbackHandler; 72 import com.sun.logging.LogDomains; 73 74 import sun.security.util.DerValue; 75 76 81 public abstract class WSSCallbackHandler implements CallbackHandler { 82 private static String SUBJECT_KEY_IDENTIFIER_OID = "2.5.29.14"; 83 84 protected static Logger _logger = LogDomains.getLogger(LogDomains.SECURITY_LOGGER); 85 86 89 static public CallbackHandler getInstance() { 90 if (Switch.getSwitch().getContainerType() == Switch.APPCLIENT_CONTAINER) { 91 return AppclientWSSCallbackHandler.newInstance(); 92 } else { 93 return EjbServletWSSCallbackHandler.newInstance(); 94 } 95 } 96 97 111 abstract boolean isSupportedCallback(Callback callback); 112 113 public void handle(Callback [] callbacks) 114 throws IOException , UnsupportedCallbackException {}; 115 116 120 protected void processCallback (Callback callback) 121 throws UnsupportedCallbackException { 122 if (callback instanceof PasswordValidationCallback) { 123 processPasswordValidation((PasswordValidationCallback)callback); 124 } else if (callback instanceof PrivateKeyCallback) { 125 processPrivateKey((PrivateKeyCallback)callback); 126 } else if (callback instanceof TrustStoreCallback) { 127 TrustStoreCallback tstoreCallback = (TrustStoreCallback)callback; 128 if (_logger.isLoggable(Level.FINE)) { 129 _logger.log(Level.FINE, 130 "container-auth: wss : In TrustStoreCallback Processor"); 131 } 132 tstoreCallback.setStore (SSLUtils.getMergedTrustStore()); 133 134 } else if (callback instanceof CertStoreCallback) { 135 processCertStore((CertStoreCallback)callback); 136 } else if (callback instanceof SecretKeyCallback) { 137 processSecretKey((SecretKeyCallback)callback); 138 } else { 139 _logger.log(Level.FINE,"wss-container-auth: UnsupportedCallback : "+ 142 callback.getClass().getName()); 143 throw new UnsupportedCallbackException (callback); 144 } 145 } 146 147 private void processPasswordValidation( 148 PasswordValidationCallback pwdCallback) { 149 150 if (Switch.getSwitch().getContainerType() == Switch.APPCLIENT_CONTAINER) { 151 if (_logger.isLoggable(Level.FINE)){ 152 _logger.log(Level.FINE, "container-auth: wss : In PasswordValidationCallback Processor for appclient - will do nothing"); 153 } 154 pwdCallback.setResult(true); 155 return; 156 } 157 String username = pwdCallback.getUsername(); 158 String password = new String (pwdCallback.getPassword()); 159 if (_logger.isLoggable(Level.FINE)) { 160 _logger.log(Level.FINE, "container-auth: wss : In PasswordValidationCallback Processor"); 161 } 162 try { 163 String defaultRealm = Realm.getDefaultRealm(); 164 LoginContextDriver.wssLoginUsernamePassword(username, password, 165 defaultRealm); 166 if(_logger.isLoggable(Level.FINE)){ 167 _logger.log(Level.FINE, 168 "container-auth wss: authentication succeeded for user = ", 169 username); 170 } 171 password = null; 173 pwdCallback.setResult(true); 174 } catch(LoginException le) { 175 _logger.log(Level.INFO, 177 "container-auth: wss : Login failed for user :", 178 username); 179 pwdCallback.setResult(false); 180 } 181 } 182 183 private void processPrivateKey(PrivateKeyCallback privKeyCallback) { 184 KeyStore [] kstores = SecurityUtil.getSecuritySupport().getKeyStores(); 185 if (_logger.isLoggable(Level.FINE)) { 186 _logger.log(Level.FINE, 187 "container-auth: wss : In PrivateKeyCallback Processor"); 188 } 189 190 if (kstores == null || kstores.length == 0) { 192 privKeyCallback.setKey(null, null); 194 return; 195 } 196 197 String [] passwords = 198 SecurityUtil.getSecuritySupport().getKeyStorePasswords(); 199 200 PrivateKeyCallback.Request req = privKeyCallback.getRequest(); 202 if (req == null) { 203 setDefaultKey(privKeyCallback, kstores, passwords); 205 passwords = null; 206 return; 207 } 208 209 PrivateKey privKey = null; 211 Certificate [] certs = null; 212 try { 213 if (req instanceof PrivateKeyCallback.AliasRequest) { 214 PrivateKeyCallback.AliasRequest aReq = 215 (PrivateKeyCallback.AliasRequest)req; 216 217 String alias = aReq.getAlias(); 218 PrivateKeyEntry privKeyEntry = null; 219 if (alias == null) { 220 setDefaultKey(privKeyCallback, kstores, passwords); 222 passwords = null; 223 return; 224 } else if ((privKeyEntry = SSLUtils.getPrivateKeyEntryFromTokenAlias(alias)) != null) { 225 privKey = privKeyEntry.getPrivateKey(); 226 certs = privKeyEntry.getCertificateChain(); 227 } 228 } else if (req instanceof PrivateKeyCallback.IssuerSerialNumRequest) { 229 PrivateKeyCallback.IssuerSerialNumRequest isReq = 230 (PrivateKeyCallback.IssuerSerialNumRequest)req; 231 X500Principal issuer = isReq.getIssuer(); 232 BigInteger serialNum = isReq.getSerialNum(); 233 if (issuer != null && serialNum != null) { 234 boolean found = false; 235 for (int i = 0; i < kstores.length && !found; i++) { 236 Enumeration aliases = kstores[i].aliases(); 237 while (aliases.hasMoreElements() && !found) { 238 String nextAlias = (String )aliases.nextElement(); 239 Key key = kstores[i].getKey(nextAlias, passwords[i].toCharArray()); 240 if (key != null && (key instanceof PrivateKey )) { 241 Certificate [] certificates = 242 kstores[i].getCertificateChain(nextAlias); 243 X509Certificate eeCert = (X509Certificate )certificates[0]; 245 if (eeCert.getIssuerX500Principal().equals(issuer) && 246 eeCert.getSerialNumber().equals(serialNum)) { 247 privKey = (PrivateKey )key; 248 certs = certificates; 249 found = true; 250 } 251 } 252 } 253 } 254 } 255 } else if (req instanceof PrivateKeyCallback.SubjectKeyIDRequest) { 256 PrivateKeyCallback.SubjectKeyIDRequest skReq = 257 (PrivateKeyCallback.SubjectKeyIDRequest)req; 258 byte[] subjectKeyID = skReq.getSubjectKeyID(); 259 if (subjectKeyID != null) { 260 boolean found = false; 261 DerValue derValue1 = new DerValue( 263 DerValue.tag_OctetString, subjectKeyID); 264 DerValue derValue2 = new DerValue( 265 DerValue.tag_OctetString, derValue1.toByteArray()); 266 byte[] derSubjectKeyID = derValue2.toByteArray(); 267 268 for (int i = 0; i < kstores.length && !found; i++) { 269 Enumeration aliases = kstores[i].aliases(); 270 while (aliases.hasMoreElements() && !found) { 271 String nextAlias = (String )aliases.nextElement(); 272 Key key = kstores[i].getKey(nextAlias, passwords[i].toCharArray()); 273 if (key != null && (key instanceof PrivateKey )) { 274 Certificate [] certificates = 275 kstores[i].getCertificateChain(nextAlias); 276 X509Certificate eeCert = (X509Certificate )certificates[0]; 277 byte[] derSubKeyID = eeCert.getExtensionValue(SUBJECT_KEY_IDENTIFIER_OID); 279 if (derSubKeyID != null && 280 Arrays.equals(derSubKeyID, derSubjectKeyID)) { 281 privKey = (PrivateKey )key; 282 certs = certificates; 283 found = true; 284 } 285 } 286 } 287 } 288 } 289 } else { 290 if (_logger.isLoggable(Level.FINE)) { 291 _logger.log(Level.FINE, 292 "invalid request type: " + req.getClass().getName()); 293 } 294 } 295 } catch (Exception e) { 296 if (_logger.isLoggable(Level.FINE)) { 300 _logger.log(Level.FINE, 301 "container-auth: wss : In PrivateKeyCallback Processor: " + 302 " Error reading key !", e); 303 } 304 } finally { 305 privKeyCallback.setKey(privKey, certs); 306 passwords = null; 307 } 308 } 309 310 314 private void setDefaultKey(PrivateKeyCallback privKeyCallback, 315 KeyStore [] kstores, String [] passwords) { 316 PrivateKey privKey = null; 317 Certificate [] certs = null; 318 try { 319 for (int i = 0; i < kstores.length && privKey == null; i++) { 320 Enumeration aliases = kstores[i].aliases(); 321 while (aliases.hasMoreElements() && privKey == null) { 323 String nextAlias = (String )aliases.nextElement(); 324 privKey = null; 325 certs = null; 326 Key key = kstores[i].getKey(nextAlias, passwords[i].toCharArray()); 327 if (key != null && (key instanceof PrivateKey )) { 328 privKey = (PrivateKey )key; 329 certs = kstores[i].getCertificateChain(nextAlias); 330 } 331 } 332 } 333 } catch (Exception e) { 334 } 338 339 privKeyCallback.setKey(privKey, certs); 340 } 341 342 private void processCertStore(CertStoreCallback certStoreCallback) { 343 if (_logger.isLoggable(Level.FINE)) { 344 _logger.log(Level.FINE, 345 "container-auth: wss : In CertStoreCallback Processor"); 346 } 347 348 KeyStore certStore = SSLUtils.getMergedTrustStore(); 349 if (certStore == null) { certStoreCallback.setStore((CertStore )null); 351 } 352 List list = new ArrayList (); 353 CollectionCertStoreParameters ccsp = null; 354 try{ 355 Enumeration enu = certStore.aliases(); 356 while (enu.hasMoreElements()) { 357 String alias = (String )enu.nextElement(); 358 if(certStore.isCertificateEntry(alias)){ 359 try{ 360 Certificate cert = certStore.getCertificate(alias); 361 list.add(cert); 362 }catch(KeyStoreException kse){ 363 _logger.log(Level.FINE, "container-auth : wss: Cannot retrieve" + 365 "certificate for alias "+alias); 366 } 367 } 368 } 369 ccsp = new CollectionCertStoreParameters (list); 370 CertStore certstore = CertStore.getInstance("Collection", ccsp); 371 certStoreCallback.setStore(certstore); 372 } catch(KeyStoreException kse){ 373 _logger.log(Level.FINE, 374 "container-auth: wss : Cannot determine truststore aliases", kse); 375 } catch(InvalidAlgorithmParameterException iape){ 376 _logger.log(Level.FINE, 377 "container-auth: wss : Cannot instantiate CertStore", iape); 378 } catch(NoSuchAlgorithmException nsape){ 379 _logger.log(Level.FINE, 380 "container-auth: wss : Cannot instantiate CertStore", nsape); 381 } 382 } 383 384 private void processSecretKey(SecretKeyCallback secretKeyCallback) { 385 if (_logger.isLoggable(Level.FINE)) { 386 _logger.log(Level.FINE, 387 "container-auth: wss : In SecretKeyCallback Processor"); 388 } 389 390 KeyStore secretStore = SecurityUtil.getSecuritySupport().getKeyStores()[0]; 391 if (secretStore == null) { 392 secretKeyCallback.setKey(null); 394 } 395 String alias = ((SecretKeyCallback.AliasRequest)secretKeyCallback.getRequest()).getAlias(); 396 if (alias != null) { 397 String pass = SSLUtils.getKeyStorePass(); 399 try { 400 Key key = secretStore.getKey(alias, pass.toCharArray()); 401 if (key instanceof SecretKey) { 402 secretKeyCallback.setKey((SecretKey)key); 403 } else { 404 secretKeyCallback.setKey(null); 405 } 406 } catch(Exception e) { 407 if (_logger.isLoggable(Level.FINE)) { 408 _logger.log(Level.FINE, 409 "container-auth: wss : In SecretKeyCallback Processor: "+ 410 " Error reading key ! for alias "+alias, e); 411 } 412 secretKeyCallback.setKey(null); 413 } finally { 414 pass = null; 415 } 416 } else { 417 secretKeyCallback.setKey(null); 422 if (_logger.isLoggable(Level.WARNING)) { 423 _logger.log(Level.WARNING, 424 "container-auth: wss : No support to read Principals in SecretKeyCallback"); 425 } 426 } 427 } 428 } 429 | Popular Tags |