BaseContainerCallbackHandlerpublic abstract class BaseContainerCallbackHandler extends Object implements CallbackHandler, com.sun.enterprise.security.jmac.config.CallbackHandlerConfigBase Callback Handler for JSR 196 |
Fields Summary |
---|
private static final String | SUBJECT_KEY_IDENTIFIER_OID | private static final String | DEFAULT_DIGEST_ALGORITHM | private static final String | CLIENT_SECRET_KEYSTORE | private static final String | CLIENT_SECRET_KEYSTORE_PASSWORD | private static final String | DEFAULT_CLIENT_SECRET_KEYSTORE_PASSWORD | protected static Logger | _logger | protected com.sun.enterprise.security.jmac.config.HandlerContext | handlerContext |
Methods Summary |
---|
private java.security.KeyStore.PrivateKeyEntry | getDefaultPrivateKeyEntry(java.security.KeyStore[] kstores, java.lang.String[] passwords)Return the first key/chain that we can successfully
get out of the keystore
PrivateKey privKey = null;
Certificate[] certs = null;
try {
for (int i = 0; i < kstores.length && privKey == null; i++) {
Enumeration aliases = kstores[i].aliases();
// loop thru aliases and try to get the key/chain
while (aliases.hasMoreElements() && privKey == null) {
String nextAlias = (String)aliases.nextElement();
privKey = null;
certs = null;
Key key = kstores[i].getKey(nextAlias, passwords[i].toCharArray());
if (key != null && (key instanceof PrivateKey)) {
privKey = (PrivateKey)key;
certs = kstores[i].getCertificateChain(nextAlias);
}
}
}
} catch (Exception e) {
// UnrecoverableKeyException
// NoSuchAlgorithmException
// KeyStoreException
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"Exception in getDefaultPrivateKeyEntry", e);
}
}
return new PrivateKeyEntry(privKey, certs);
| private java.security.KeyStore.PrivateKeyEntry | getPrivateKeyEntry(java.security.KeyStore[] kstores, java.lang.String[] passwords, java.security.MessageDigest md, byte[] digest)
PrivateKey privKey = null;
Certificate[] certs = null;
try {
for (int i = 0; i < kstores.length && privKey == null; i++) {
Enumeration aliases = kstores[i].aliases();
// loop thru aliases and try to get the key/chain
while (aliases.hasMoreElements() && privKey == null) {
String nextAlias = (String)aliases.nextElement();
privKey = null;
certs = null;
Key key = kstores[i].getKey(nextAlias, passwords[i].toCharArray());
if (key != null && (key instanceof PrivateKey)) {
certs = kstores[i].getCertificateChain(nextAlias);
md.reset();
byte[] cDigest = md.digest(certs[0].getEncoded());
if (Arrays.equals(digest, cDigest)) {
privKey = (PrivateKey)key;
}
}
}
}
} catch (Exception e) {
// UnrecoverableKeyException
// NoSuchAlgorithmException
// KeyStoreException
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"Exception in getPrivateKeyEntry for Digest", e);
}
}
return new PrivateKeyEntry(privKey, certs);
| public void | handle(javax.security.auth.callback.Callback[] callbacks)
if (callbacks == null) {
return;
}
boolean continueProcessing = true;
for (int i=0; i < callbacks.length; i++){
if (!isSupportedCallback(callbacks[i])) {
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: UnsupportedCallback : "+
callbacks[i].getClass().getName());
}
throw new UnsupportedCallbackException(callbacks[i]);
}
}
handleSupportedCallbacks(callbacks);
| protected abstract void | handleSupportedCallbacks(javax.security.auth.callback.Callback[] callbacks)
| protected abstract boolean | isSupportedCallback(javax.security.auth.callback.Callback callback)
| protected void | processCallback(javax.security.auth.callback.Callback callback)gets the appropriate callback processor and hands the callback to
processor to process the callback.
if (callback instanceof CallerPrincipalCallback) {
processCallerPrincipal((CallerPrincipalCallback)callback);
} else if (callback instanceof GroupPrincipalCallback) {
processGroupPrincipal((GroupPrincipalCallback)callback);
} else if (callback instanceof PasswordValidationCallback) {
processPasswordValidation((PasswordValidationCallback)callback);
} else if (callback instanceof PrivateKeyCallback) {
processPrivateKey((PrivateKeyCallback)callback);
} else if (callback instanceof TrustStoreCallback) {
TrustStoreCallback tstoreCallback = (TrustStoreCallback)callback;
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: In TrustStoreCallback Processor");
}
tstoreCallback.setTrustStore (SSLUtils.getMergedTrustStore());
} else if (callback instanceof CertStoreCallback) {
processCertStore((CertStoreCallback)callback);
} else if (callback instanceof SecretKeyCallback) {
processSecretKey((SecretKeyCallback)callback);
} else {
// sanity check =- should never come here.
// the isSupportedCallback method already takes care of this case
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,"JMAC: UnsupportedCallback : "+
callback.getClass().getName());
}
throw new UnsupportedCallbackException(callback);
}
| private void | processCallerPrincipal(javax.security.auth.message.callback.CallerPrincipalCallback cpCallback)
final Subject fs = cpCallback.getSubject();
Principal principal = cpCallback.getPrincipal();
String realmName = null;
if (handlerContext != null) {
realmName = handlerContext.getRealmName();
}
boolean isCertRealm = CertificateRealm.AUTH_TYPE.equals(realmName);
if (principal == null) {
if (cpCallback.getName() != null) {
if (isCertRealm) {
principal = new X500Principal(cpCallback.getName());
} else {
principal = new PrincipalImpl(cpCallback.getName());
}
} else {
// 196 unauthenticated caller principal
principal = SecurityContext.getDefaultCallerPrincipal();
}
}
if (isCertRealm) {
LoginContextDriver.jmacLogin(fs, (X500Principal)principal);
}
final Principal fprin = principal;
final DistinguishedPrincipalCredential fdpc =
new DistinguishedPrincipalCredential(principal);
AppservAccessController.doPrivileged(new PrivilegedAction(){
public java.lang.Object run() {
fs.getPrincipals().add(fprin);
Iterator iter = fs.getPublicCredentials().iterator();
while (iter.hasNext()) {
Object obj = iter.next();
if (obj instanceof DistinguishedPrincipalCredential) {
iter.remove();
}
}
fs.getPublicCredentials().add(fdpc);
return fs;
}
});
| private void | processCertStore(javax.security.auth.message.callback.CertStoreCallback certStoreCallback)
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: In CertStoreCallback Processor");
}
KeyStore certStore = SSLUtils.getMergedTrustStore();
if (certStore == null) {// should never happen
certStoreCallback.setCertStore((CertStore)null);
}
List list = new ArrayList();
CollectionCertStoreParameters ccsp = null;
try{
Enumeration enu = certStore.aliases();
while (enu.hasMoreElements()) {
String alias = (String)enu.nextElement();
if(certStore.isCertificateEntry(alias)){
try{
Certificate cert = certStore.getCertificate(alias);
list.add(cert);
}catch(KeyStoreException kse){
// ignore and move to next
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "JAMAC: Cannot retrieve" +
"certificate for alias "+alias);
}
}
}
}
ccsp = new CollectionCertStoreParameters(list);
CertStore certstore = CertStore.getInstance("Collection", ccsp);
certStoreCallback.setCertStore(certstore);
} catch(KeyStoreException kse){
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: Cannot determine truststore aliases", kse);
}
} catch(InvalidAlgorithmParameterException iape){
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: Cannot instantiate CertStore", iape);
}
} catch(NoSuchAlgorithmException nsape){
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: Cannot instantiate CertStore", nsape);
}
}
| private void | processGroupPrincipal(javax.security.auth.message.callback.GroupPrincipalCallback gpCallback)
final Subject fs = gpCallback.getSubject();
final String[] groups = gpCallback.getGroups();
if (groups != null && groups.length > 0) {
AppservAccessController.doPrivileged(new PrivilegedAction(){
public java.lang.Object run() {
for (String group : groups) {
fs.getPrincipals().add(new Group(group));
}
return fs;
}
});
} else if (groups == null) {
AppservAccessController.doPrivileged(new PrivilegedAction(){
public java.lang.Object run() {
fs.getPrincipals(Group.class).clear();
return fs;
}
});
}
| private void | processPasswordValidation(javax.security.auth.message.callback.PasswordValidationCallback pwdCallback)
if (Switch.getSwitch().getContainerType() == Switch.APPCLIENT_CONTAINER) {
if (_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE, "JMAC: In PasswordValidationCallback Processor for appclient - will do nothing");
}
pwdCallback.setResult(true);
return;
}
String username = pwdCallback.getUsername();
String password = new String(pwdCallback.getPassword());
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE, "JMAC: In PasswordValidationCallback Processor");
}
try {
String realmName = null;
if (handlerContext != null) {
realmName = handlerContext.getRealmName();
}
Subject s = LoginContextDriver.jmacLogin(pwdCallback.getSubject(),
username, password, realmName);
GFServerConfigProvider.setValidateRequestSubject(s);
if(_logger.isLoggable(Level.FINE)){
_logger.log(Level.FINE,
"JMAC: authentication succeeded for user = ",
username);
}
// explicitly ditch the password
password = null;
pwdCallback.setResult(true);
} catch(LoginException le) {
// login failed
if (_logger.isLoggable(Level.INFO)) {
_logger.log(Level.INFO, "jmac.loginfail", username);
}
pwdCallback.setResult(false);
}
| private void | processPrivateKey(javax.security.auth.message.callback.PrivateKeyCallback privKeyCallback)
KeyStore[] kstores = SecurityUtil.getSecuritySupport().getKeyStores();
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: In PrivateKeyCallback Processor");
}
// make sure we have a keystore
if (kstores == null || kstores.length == 0) {
// cannot get any information
privKeyCallback.setKey(null, null);
return;
}
String[] passwords =
SecurityUtil.getSecuritySupport().getKeyStorePasswords();
// get the request type
PrivateKeyCallback.Request req = privKeyCallback.getRequest();
PrivateKey privKey = null;
Certificate[] certs = null;
if (req == null) {
// no request type - set default key
PrivateKeyEntry pke = getDefaultPrivateKeyEntry(
kstores, passwords);
if (pke != null) {
privKey = pke.getPrivateKey();
certs = pke.getCertificateChain();
}
privKeyCallback.setKey(privKey, certs);
passwords = null;
return;
}
// find key based on request type
try {
if (req instanceof PrivateKeyCallback.AliasRequest) {
PrivateKeyCallback.AliasRequest aReq =
(PrivateKeyCallback.AliasRequest)req;
String alias = aReq.getAlias();
PrivateKeyEntry privKeyEntry = null;
if (alias == null) {
// use default key
privKeyEntry = getDefaultPrivateKeyEntry(kstores, passwords);
} else {
privKeyEntry = SSLUtils.getPrivateKeyEntryFromTokenAlias(alias);
}
if (privKeyEntry != null) {
privKey = privKeyEntry.getPrivateKey();
certs = privKeyEntry.getCertificateChain();
}
} else if (req instanceof PrivateKeyCallback.IssuerSerialNumRequest) {
PrivateKeyCallback.IssuerSerialNumRequest isReq =
(PrivateKeyCallback.IssuerSerialNumRequest)req;
X500Principal issuer = isReq.getIssuer();
BigInteger serialNum = isReq.getSerialNum();
if (issuer != null && serialNum != null) {
boolean found = false;
for (int i = 0; i < kstores.length && !found; i++) {
Enumeration aliases = kstores[i].aliases();
while (aliases.hasMoreElements() && !found) {
String nextAlias = (String)aliases.nextElement();
Key key = kstores[i].getKey(nextAlias, passwords[i].toCharArray());
if (key != null && (key instanceof PrivateKey)) {
Certificate[] certificates =
kstores[i].getCertificateChain(nextAlias);
// check issuer/serial
X509Certificate eeCert = (X509Certificate)certificates[0];
if (eeCert.getIssuerX500Principal().equals(issuer) &&
eeCert.getSerialNumber().equals(serialNum)) {
privKey = (PrivateKey)key;
certs = certificates;
found = true;
}
}
}
}
}
} else if (req instanceof PrivateKeyCallback.SubjectKeyIDRequest) {
PrivateKeyCallback.SubjectKeyIDRequest skReq =
(PrivateKeyCallback.SubjectKeyIDRequest)req;
byte[] subjectKeyID = skReq.getSubjectKeyID();
if (subjectKeyID != null) {
boolean found = false;
// In DER, subjectKeyID will be an OCTET STRING of OCTET STRING
DerValue derValue1 = new DerValue(
DerValue.tag_OctetString, subjectKeyID);
DerValue derValue2 = new DerValue(
DerValue.tag_OctetString, derValue1.toByteArray());
byte[] derSubjectKeyID = derValue2.toByteArray();
for (int i = 0; i < kstores.length && !found; i++) {
Enumeration aliases = kstores[i].aliases();
while (aliases.hasMoreElements() && !found) {
String nextAlias = (String)aliases.nextElement();
Key key = kstores[i].getKey(nextAlias, passwords[i].toCharArray());
if (key != null && (key instanceof PrivateKey)) {
Certificate[] certificates =
kstores[i].getCertificateChain(nextAlias);
X509Certificate eeCert = (X509Certificate)certificates[0];
// Extension: SubjectKeyIdentifier
byte[] derSubKeyID = eeCert.getExtensionValue(SUBJECT_KEY_IDENTIFIER_OID);
if (derSubKeyID != null &&
Arrays.equals(derSubKeyID, derSubjectKeyID)) {
privKey = (PrivateKey)key;
certs = certificates;
found = true;
}
}
}
}
}
} else if (req instanceof PrivateKeyCallback.DigestRequest) {
PrivateKeyCallback.DigestRequest dReq =
(PrivateKeyCallback.DigestRequest)req;
byte[] digest = dReq.getDigest();
String algorithm = dReq.getAlgorithm();
PrivateKeyEntry privKeyEntry = null;
if (digest == null) {
// get default key
privKeyEntry = getDefaultPrivateKeyEntry(kstores, passwords);
} else {
if (algorithm == null) {
algorithm = DEFAULT_DIGEST_ALGORITHM;
}
MessageDigest md = MessageDigest.getInstance(algorithm);
privKeyEntry = getPrivateKeyEntry(kstores, passwords, md, digest);
}
if (privKeyEntry != null) {
privKey = privKeyEntry.getPrivateKey();
certs = privKeyEntry.getCertificateChain();
}
} else {
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"invalid request type: " + req.getClass().getName());
}
}
} catch (Exception e) {
// UnrecoverableKeyException
// NoSuchAlgorithmException
// KeyStoreException
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: In PrivateKeyCallback Processor: " +
" Error reading key !", e);
}
} finally {
privKeyCallback.setKey(privKey, certs);
passwords = null;
}
| private void | processSecretKey(javax.security.auth.message.callback.SecretKeyCallback secretKeyCallback)
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: In SecretKeyCallback Processor");
}
String alias = ((SecretKeyCallback.AliasRequest)secretKeyCallback.getRequest()).getAlias();
if (alias != null) {
try {
PasswordAdapter passwordAdapter = null;
if (Switch.getSwitch().getContainerType() ==
Switch.APPCLIENT_CONTAINER) {
passwordAdapter = new PasswordAdapter(
System.getProperty(CLIENT_SECRET_KEYSTORE),
System.getProperty(CLIENT_SECRET_KEYSTORE_PASSWORD,
DEFAULT_CLIENT_SECRET_KEYSTORE_PASSWORD).toCharArray());
} else {
passwordAdapter = new PasswordAdapter(
IdentityManager.getMasterPassword().toCharArray());
}
secretKeyCallback.setKey(
passwordAdapter.getPasswordSecretKeyForAlias(alias));
} catch(Exception e) {
if (_logger.isLoggable(Level.FINE)) {
_logger.log(Level.FINE,
"JMAC: In SecretKeyCallback Processor: "+
" Error reading key ! for alias "+alias, e);
}
secretKeyCallback.setKey(null);
}
} else {
// Dont bother about checking for principal
// we dont support that feature - typically
// used in an environment with kerberos
// Principal p = secretKeyCallback.getPrincipal();
secretKeyCallback.setKey(null);
if (_logger.isLoggable(Level.WARNING)) {
_logger.log(Level.WARNING, "jmac.unsupportreadprinciple");
}
}
| public void | setHandlerContext(com.sun.enterprise.security.jmac.config.HandlerContext handlerContext)
this.handlerContext = handlerContext;
|
|