0001: /*
0002: * WSITProviderSecurityEnvironment.java
0003: *
0004: * Created on November 12, 2006, 1:29 PM
0005: *
0006: * To change this template, choose Tools | Template Manager
0007: * and open the template in the editor.
0008: */
0009:
0010: package com.sun.xml.wss.impl.misc;
0011:
0012: import com.sun.xml.wss.AliasSelector;
0013: import com.sun.xml.wss.impl.callback.SAMLAssertionValidator;
0014: import java.io.IOException;
0015: import java.lang.reflect.Constructor;
0016: import java.lang.reflect.InvocationTargetException;
0017: import java.security.cert.CertSelector;
0018: import java.security.cert.CertStore;
0019: import java.security.cert.CertStoreException;
0020: import java.util.Collection;
0021: import javax.security.auth.callback.UnsupportedCallbackException;
0022: import javax.security.auth.message.callback.CertStoreCallback;
0023: import javax.security.auth.message.callback.PasswordValidationCallback;
0024: import javax.security.auth.message.callback.PrivateKeyCallback;
0025: import javax.security.auth.message.callback.SecretKeyCallback;
0026: import javax.security.auth.message.callback.TrustStoreCallback;
0027: import javax.security.auth.message.callback.CallerPrincipalCallback;
0028:
0029: import java.math.BigInteger;
0030:
0031: import java.security.Key;
0032: import java.security.KeyStore;
0033: import java.security.PublicKey;
0034: import java.security.Principal;
0035: import java.security.PrivateKey;
0036: import java.security.KeyStoreException;
0037:
0038: import java.security.cert.Certificate;
0039: import java.security.cert.X509Certificate;
0040: import java.security.cert.CertPathBuilder;
0041: import java.security.cert.X509CertSelector;
0042: import java.security.cert.PKIXBuilderParameters;
0043: import java.security.cert.PKIXCertPathBuilderResult;
0044: import java.security.cert.CertificateExpiredException;
0045: import java.security.cert.CertificateNotYetValidException;
0046:
0047: import java.text.ParseException;
0048: import java.text.SimpleDateFormat;
0049:
0050: import java.util.Map;
0051: import java.util.Set;
0052: import java.util.Date;
0053: import java.util.Timer;
0054: import java.util.Arrays;
0055: import java.util.Calendar;
0056: import java.util.Iterator;
0057: import java.util.Enumeration;
0058: import java.util.StringTokenizer;
0059: import java.util.GregorianCalendar;
0060:
0061: import javax.security.auth.Subject;
0062: import javax.security.auth.callback.Callback;
0063: import javax.security.auth.callback.CallbackHandler;
0064: import javax.security.auth.x500.X500Principal;
0065: import javax.security.auth.x500.X500PrivateCredential;
0066: import javax.security.auth.callback.NameCallback;
0067: import javax.security.auth.callback.PasswordCallback;
0068:
0069: import javax.crypto.SecretKey;
0070:
0071: import com.sun.org.apache.xml.internal.security.utils.Base64;
0072: import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
0073:
0074: import com.sun.xml.wss.impl.MessageConstants;
0075: import com.sun.xml.wss.SecurityEnvironment;
0076: import com.sun.xml.wss.XWSSecurityException;
0077: import com.sun.xml.wss.impl.SecurityHeaderException;
0078: import com.sun.xml.wss.core.Timestamp;
0079: import com.sun.xml.wss.impl.callback.SAMLCallback;
0080: import com.sun.xml.wss.impl.policy.mls.PrivateKeyBinding;
0081:
0082: import com.sun.xml.wss.core.reference.X509SubjectKeyIdentifier;
0083:
0084: import com.sun.xml.wss.saml.Assertion; //import com.sun.xml.wss.saml.assertion.AuthorityBinding;
0085:
0086: import com.sun.xml.wss.impl.policy.mls.AuthenticationTokenPolicy;
0087: import com.sun.xml.wss.impl.configuration.DynamicApplicationContext;
0088: import java.security.AccessController;
0089: import javax.xml.stream.XMLStreamReader;
0090: import javax.xml.ws.BindingProvider;
0091:
0092: import org.w3c.dom.Element;
0093: import org.w3c.dom.Document;
0094:
0095: import java.security.MessageDigest;
0096: import java.security.NoSuchAlgorithmException;
0097: import java.security.PrivilegedAction;
0098: import java.security.cert.CertificateEncodingException;
0099: import java.util.Properties;
0100:
0101: import java.util.logging.Level;
0102: import java.util.logging.Logger;
0103: import com.sun.xml.wss.logging.LogDomainConstants;
0104:
0105: /**
0106: *
0107: * @author kumar.jayanti
0108: */
0109: public class WSITProviderSecurityEnvironment implements
0110: SecurityEnvironment {
0111:
0112: /* menu of module options - includes algorithm Ids, keystore aliases etc., */
0113: private Map _securityOptions;
0114:
0115: /* Callbacks */
0116: private CallbackHandler _handler;
0117:
0118: /* Map of aliases-key passwords obtained via Module Options */
0119: //Map aliases_keypwds = null;
0120: // value of the maximum skew between the local times of two
0121: // systems (in milliseconds).
0122: // Keeping it 1 minute.
0123: protected final long MAX_CLOCK_SKEW = 360000;
0124:
0125: // milliseconds (set to 5 mins), time for which a timestamp is considered fresh
0126: protected final long TIMESTAMP_FRESHNESS_LIMIT = 5 * 60 * 1000;
0127:
0128: /** logger */
0129: protected static final Logger log = Logger.getLogger(
0130: LogDomainConstants.WSS_API_DOMAIN,
0131: LogDomainConstants.WSS_API_DOMAIN_BUNDLE);
0132:
0133: private static final SimpleDateFormat calendarFormatter1 = new SimpleDateFormat(
0134: "yyyy-MM-dd'T'HH:mm:ss'Z'");
0135: private static final SimpleDateFormat calendarFormatter2 = new SimpleDateFormat(
0136: "yyyy-MM-dd'T'HH:mm:ss'.'SSS'Z'");
0137:
0138: // Nonce Cache
0139: NonceCache nonceCache = null;
0140:
0141: // Nonce clean-up timer
0142: static final boolean USE_DAEMON_THREAD = true;
0143: static final Timer nonceCleanupTimer = new Timer(USE_DAEMON_THREAD);
0144:
0145: private String myAlias;
0146: private String keyPwd;
0147: private String peerEntityAlias;
0148: private String myUsername;
0149: private String myPassword;
0150: private String samlCBH;
0151: private String sV;
0152: private Class samlCbHandler;
0153: private CallbackHandler samlHandler = null;
0154: private Class samlValidator;
0155: private SAMLAssertionValidator sValidator;
0156:
0157: private String mcs;
0158: private String tfl;
0159: private String mna;
0160:
0161: protected long maxClockSkewG;
0162: protected long timestampFreshnessLimitG;
0163: protected long maxNonceAge;
0164:
0165: private boolean isAppClient = true;
0166:
0167: private X509Certificate selfCertificate = null;
0168:
0169: private String certSelectorClassName;
0170: private String crlSelectorClassName;
0171: private Class certSelectorClass;
0172: private Class crlSelectorClass;
0173:
0174: protected String revocationEnabledAttr;
0175: protected boolean revocationEnabled = false;
0176:
0177: private String keystoreCertSelectorClassName;
0178: private String truststoreCertSelectorClassName;
0179:
0180: private Class keystoreCertSelectorClass;
0181: private Class truststoreCertSelectorClass;
0182:
0183: /** Creates a new instance of WSITProviderSecurityEnvironment */
0184: public WSITProviderSecurityEnvironment(CallbackHandler handler,
0185: Map options, Properties configAssertions)
0186: throws XWSSecurityException {
0187: _handler = handler;
0188: _securityOptions = options;
0189:
0190: if (_securityOptions != null) {
0191: String mo_aliases = (String) _securityOptions
0192: .get("ALIASES");
0193: String mo_keypwds = (String) _securityOptions
0194: .get("PASSWORDS");
0195:
0196: if (mo_aliases != null && mo_keypwds != null) {
0197: StringTokenizer aliases = new StringTokenizer(
0198: mo_aliases, " ");
0199: StringTokenizer keypwds = new StringTokenizer(
0200: mo_keypwds, " ");
0201: if (aliases.countTokens() != keypwds.countTokens())
0202: ;// log.INFO
0203:
0204: //while (aliases.hasMoreElements()) {
0205: // aliases_keypwds.put(aliases.nextToken(), keypwds.nextToken());
0206: //}
0207: }
0208: }
0209:
0210: //store the relevant config assertions here
0211: this .myAlias = configAssertions
0212: .getProperty(DefaultCallbackHandler.MY_ALIAS);
0213: this .keyPwd = configAssertions
0214: .getProperty(DefaultCallbackHandler.KEY_PASSWORD);
0215: this .peerEntityAlias = configAssertions
0216: .getProperty(DefaultCallbackHandler.PEER_ENTITY_ALIAS);
0217:
0218: this .myUsername = configAssertions
0219: .getProperty(DefaultCallbackHandler.MY_USERNAME);
0220: this .myPassword = configAssertions
0221: .getProperty(DefaultCallbackHandler.MY_PASSWORD);
0222: this .samlCBH = configAssertions
0223: .getProperty(DefaultCallbackHandler.SAML_CBH);
0224: if (this .samlCBH != null) {
0225: samlCbHandler = loadClass(samlCBH);
0226: }
0227: if (samlCbHandler != null) {
0228: try {
0229: samlHandler = (CallbackHandler) samlCbHandler
0230: .newInstance();
0231: } catch (InstantiationException ex) {
0232: log.log(Level.SEVERE,
0233: "WSS0715.exception.creating.newinstance", ex);
0234: throw new XWSSecurityException(ex);
0235: } catch (IllegalAccessException ex) {
0236: log.log(Level.SEVERE,
0237: "WSS0715.exception.creating.newinstance", ex);
0238: throw new XWSSecurityException(ex);
0239: }
0240: }
0241:
0242: sV = configAssertions
0243: .getProperty(DefaultCallbackHandler.SAML_VALIDATOR);
0244: if (sV != null) {
0245: samlValidator = loadClass(sV);
0246: }
0247:
0248: if (samlValidator != null) {
0249: try {
0250: sValidator = (SAMLAssertionValidator) samlValidator
0251: .newInstance();
0252: } catch (InstantiationException ex) {
0253: log.log(Level.SEVERE,
0254: "WSS0715.exception.creating.newinstance", ex);
0255: throw new XWSSecurityException(ex);
0256: } catch (IllegalAccessException ex) {
0257: log.log(Level.SEVERE,
0258: "WSS0715.exception.creating.newinstance", ex);
0259: throw new XWSSecurityException(ex);
0260: }
0261: }
0262:
0263: mcs = configAssertions
0264: .getProperty(DefaultCallbackHandler.MAX_CLOCK_SKEW_PROPERTY);
0265: tfl = configAssertions
0266: .getProperty(DefaultCallbackHandler.TIMESTAMP_FRESHNESS_LIMIT_PROPERTY);
0267: mna = configAssertions
0268: .getProperty(DefaultCallbackHandler.MAX_NONCE_AGE_PROPERTY);
0269:
0270: revocationEnabledAttr = configAssertions
0271: .getProperty(DefaultCallbackHandler.REVOCATION_ENABLED);
0272: if (revocationEnabledAttr != null) {
0273: this .revocationEnabled = Boolean
0274: .parseBoolean(revocationEnabledAttr);
0275: }
0276: maxClockSkewG = toLong(mcs);
0277: timestampFreshnessLimitG = toLong(tfl);
0278: maxNonceAge = toLong(mna);
0279:
0280: //determine if we are in an AppClient
0281: NameCallback nameCallback = new NameCallback("Username: ");
0282: try {
0283: Callback[] cbs = new Callback[] { nameCallback };
0284: _handler.handle(cbs);
0285: } catch (javax.security.auth.callback.UnsupportedCallbackException e) {
0286: this .isAppClient = false;
0287: } catch (Exception e) {
0288: this .isAppClient = false;
0289: }
0290:
0291: this .certSelectorClassName = configAssertions
0292: .getProperty(DefaultCallbackHandler.CERTSTORE_CERTSELECTOR);
0293: this .crlSelectorClassName = configAssertions
0294: .getProperty(DefaultCallbackHandler.CERTSTORE_CRLSELECTOR);
0295: this .certSelectorClass = loadClass(this .certSelectorClassName);
0296: this .crlSelectorClass = loadClass(this .crlSelectorClassName);
0297:
0298: this .keystoreCertSelectorClassName = configAssertions
0299: .getProperty(DefaultCallbackHandler.KEYSTORE_CERTSELECTOR);
0300: this .truststoreCertSelectorClassName = configAssertions
0301: .getProperty(DefaultCallbackHandler.TRUSTSTORE_CERTSELECTOR);
0302: keystoreCertSelectorClass = loadClass(this .keystoreCertSelectorClassName);
0303: truststoreCertSelectorClass = loadClass(this .truststoreCertSelectorClassName);
0304:
0305: //keep the self certificate handy
0306: if (_handler != null && this .myAlias != null) {
0307: try {
0308: PrivateKeyCallback.Request request = new PrivateKeyCallback.AliasRequest(
0309: this .myAlias);
0310: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
0311: request);
0312:
0313: Callback[] callbacks = new Callback[] { pkCallback };
0314: _handler.handle(callbacks);
0315: Certificate[] chain = pkCallback.getChain();
0316: if (chain != null) {
0317: selfCertificate = (X509Certificate) chain[0];
0318: }
0319: } catch (Exception ex) {
0320: //ignore for now
0321: }
0322: }
0323: }
0324:
0325: /*
0326: * @throws XWSSecurityException
0327: */
0328: public PrivateKey getPrivateKey(Map context, String alias)
0329: throws XWSSecurityException {
0330:
0331: PrivateKey privateKey = null;
0332: try {
0333: PrivateKeyCallback.Request request = new PrivateKeyCallback.AliasRequest(
0334: alias);
0335: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
0336: request);
0337: Callback[] callbacks = new Callback[] { pkCallback };
0338: _handler.handle(callbacks);
0339: privateKey = (PrivateKey) pkCallback.getKey();
0340: } catch (Exception e) {
0341: log.log(Level.SEVERE,
0342: "WSS0216.callbackhandler.handle.exception",
0343: new Object[] { "PrivateKeyCallback.AliasRequest" });
0344: log.log(Level.SEVERE,
0345: "WSS0217.callbackhandler.handle.exception.log", e);
0346: throw new XWSSecurityException(e);
0347: }
0348:
0349: if (privateKey == null) {
0350: log.log(Level.SEVERE, "WSS0222.cannot.locate.privkey",
0351: new Object[] { alias });
0352: throw new XWSSecurityException(
0353: "Unable to locate private key for the alias: "
0354: + alias);
0355: }
0356:
0357: return privateKey;
0358: }
0359:
0360: /*
0361: * Retrieves the PrivateKey corresponding to the cert
0362: * with the given KeyIdentifier value
0363: *
0364: * @param keyIdentifier an Opaque identifier indicating
0365: * the X509 certificate
0366: *
0367: * @return the PrivateKey corresponding to the cert
0368: * with the given KeyIdentifier value
0369: *
0370: * @throws XWSSecurityException
0371: */
0372: public PrivateKey getPrivateKey(Map context, byte[] keyIdentifier)
0373: throws XWSSecurityException {
0374: /*
0375: use PrivateKeyCallback
0376: */
0377: try {
0378: Subject subject = getSubject(context);
0379: if (subject != null) {
0380: Set set = subject
0381: .getPrivateCredentials(X500PrivateCredential.class);
0382: if (set != null) {
0383: Iterator it = set.iterator();
0384: while (it.hasNext()) {
0385: X500PrivateCredential cred = (X500PrivateCredential) it
0386: .next();
0387: if (matchesKeyIdentifier(Base64
0388: .decode(keyIdentifier), cred
0389: .getCertificate()))
0390: return cred.getPrivateKey();
0391: }
0392: }
0393: }
0394:
0395: PrivateKeyCallback.Request request = new PrivateKeyCallback.SubjectKeyIDRequest(
0396: keyIdentifier);
0397: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
0398: request);
0399: Callback[] callbacks = new Callback[] { pkCallback };
0400: _handler.handle(callbacks);
0401:
0402: return pkCallback.getKey();
0403: } catch (Exception e) {
0404: log
0405: .log(
0406: Level.SEVERE,
0407: "WSS0216.callbackhandler.handle.exception",
0408: new Object[] { "PrivateKeyCallback.SubjectKeyIDRequest" });
0409: log.log(Level.SEVERE,
0410: "WSS0217.callbackhandler.handle.exception.log", e);
0411: throw new XWSSecurityException(e);
0412: }
0413: }
0414:
0415: /*
0416: * Retrieves the PrivateKey corresponding to the given cert
0417: *
0418: * @param cert an X509 certificate
0419: *
0420: * @return the PrivateKey corresponding to the cert
0421: *
0422: * @throws XWSSecurityException
0423: */
0424: public PrivateKey getPrivateKey(Map context, X509Certificate cert)
0425: throws XWSSecurityException {
0426: /*
0427: use PrivateKeyCallback
0428: */
0429: try {
0430: Subject subject = getSubject(context);
0431: if (subject != null) {
0432: Set set = subject
0433: .getPrivateCredentials(X500PrivateCredential.class);
0434: if (set != null) {
0435: String issuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0436: .normalize(cert.getIssuerDN().getName());
0437: Iterator it = set.iterator();
0438: while (it.hasNext()) {
0439: X500PrivateCredential cred = (X500PrivateCredential) it
0440: .next();
0441: X509Certificate x509Cert = cred
0442: .getCertificate();
0443: BigInteger serialNo = x509Cert
0444: .getSerialNumber();
0445: String currentIssuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0446: .normalize(x509Cert.getIssuerDN()
0447: .getName());
0448: if (serialNo.equals(cert.getSerialNumber())
0449: && currentIssuerName.equals(issuerName)) {
0450: return cred.getPrivateKey();
0451: }
0452: }
0453: }
0454: }
0455:
0456: PrivateKeyCallback.Request request = new PrivateKeyCallback.IssuerSerialNumRequest(
0457: cert.getIssuerX500Principal(), cert
0458: .getSerialNumber());
0459: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
0460: request);
0461: Callback[] callbacks = new Callback[] { pkCallback };
0462: _handler.handle(callbacks);
0463:
0464: return pkCallback.getKey();
0465: } catch (Exception e) {
0466: log
0467: .log(
0468: Level.SEVERE,
0469: "WSS0216.callbackhandler.handle.exception",
0470: new Object[] { "PrivateKeyCallback.IssuerSerialNumRequest" });
0471: log.log(Level.SEVERE,
0472: "WSS0217.callbackhandler.handle.exception.log", e);
0473: throw new XWSSecurityException(e);
0474: }
0475: }
0476:
0477: /*
0478: * Retrieves the matching PrivateKey corresponding to cert whose
0479: * SerialNumber and IssuerName are given
0480: *
0481: * @param serialNumber X509Certificate SerialNumber
0482: * @param issuerName X509Certificate IssuerName
0483: *
0484: * @return PrivateKey
0485: *
0486: * @throws XWSSecurityException
0487: */
0488: public PrivateKey getPrivateKey(Map context,
0489: BigInteger serialNumber, String issuerName)
0490: throws XWSSecurityException {
0491: /*
0492: use PrivateKeyCallback
0493: */
0494: try {
0495: Subject subject = getSubject(context);
0496: if (subject != null) {
0497: Set set = subject
0498: .getPrivateCredentials(X500PrivateCredential.class);
0499: if (set != null) {
0500: Iterator it = set.iterator();
0501: while (it.hasNext()) {
0502: X500PrivateCredential cred = (X500PrivateCredential) it
0503: .next();
0504: X509Certificate x509Cert = cred
0505: .getCertificate();
0506: BigInteger serialNo = x509Cert
0507: .getSerialNumber();
0508: String currentIssuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0509: .normalize(x509Cert.getIssuerDN()
0510: .getName());
0511: if (serialNo.equals(serialNumber)
0512: && currentIssuerName.equals(issuerName)) {
0513: return cred.getPrivateKey();
0514: }
0515: }
0516: }
0517: }
0518:
0519: PrivateKeyCallback.Request request = new PrivateKeyCallback.IssuerSerialNumRequest(
0520: new X500Principal(issuerName), serialNumber);
0521: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
0522: request);
0523: Callback[] callbacks = new Callback[] { pkCallback };
0524: _handler.handle(callbacks);
0525:
0526: return pkCallback.getKey();
0527: } catch (Exception e) {
0528: log
0529: .log(
0530: Level.SEVERE,
0531: "WSS0216.callbackhandler.handle.exception",
0532: new Object[] { "PrivateKeyCallback.IssuerSerialNumRequest" });
0533: log.log(Level.SEVERE,
0534: "WSS0217.callbackhandler.handle.exception.log", e);
0535: throw new XWSSecurityException(e);
0536: }
0537: }
0538:
0539: /**
0540: * Retrieves a reasonable default value for the current user's
0541: * X509Certificate if one exists.
0542: *
0543: * @return the default certificate for the current user
0544: *
0545: * @param keyIdentifier an Opaque identifier indicating
0546: * the X509 certificate.
0547: * @throws XWSSecurityException
0548: */
0549: public X509Certificate getDefaultCertificate(Map context)
0550: throws XWSSecurityException {
0551: /*
0552: use PrivateKeyCallback to get the
0553: certChain - return the first certificate
0554: */
0555: Subject subject = getSubject(context);
0556: if (subject != null) {
0557: Set set = subject
0558: .getPublicCredentials(X509Certificate.class);
0559: if (set != null && set.size() == 1)
0560: return ((X509Certificate) (set.toArray())[0]);
0561: }
0562:
0563: if (this .myAlias != null
0564: || this .keystoreCertSelectorClass != null) {
0565: return this .getCertificate(context, this .myAlias, true);
0566: }
0567:
0568: PrivateKeyCallback pkCallback = new PrivateKeyCallback(null);
0569: Callback[] _callbacks = new Callback[] { pkCallback };
0570: try {
0571: _handler.handle(_callbacks);
0572: } catch (Exception e) {
0573: log
0574: .log(
0575: Level.SEVERE,
0576: "WSS0216.callbackhandler.handle.exception",
0577: new Object[] { "PrivateKeyCallback with null argument" });
0578: log.log(Level.SEVERE,
0579: "WSS0217.callbackhandler.handle.exception.log", e);
0580: throw new XWSSecurityException(e);
0581: }
0582:
0583: Certificate[] chain = pkCallback.getChain();
0584: if (chain == null) {
0585: log.log(Level.SEVERE, "WSS0296.null.chain.cert");
0586: throw new XWSSecurityException(
0587: "Empty certificate chain returned by PrivateKeyCallback");
0588: }
0589: return (X509Certificate) chain[0];
0590: }
0591:
0592: /**
0593: * Authenticate the user against a list of known username-password
0594: * pairs.
0595: *
0596: * @param username
0597: * @param password
0598: * @return true if the username-password pair is valid
0599: */
0600: public boolean authenticateUser(Map context, String username,
0601: String password) throws XWSSecurityException {
0602: /*
0603: use PasswordValidationCallback
0604: */
0605: char[] pwd = (password == null) ? null : password.toCharArray();
0606: PasswordValidationCallback pvCallback = new PasswordValidationCallback(
0607: this .getRequesterSubject(context), username, pwd);
0608: Callback[] callbacks = new Callback[] { pvCallback };
0609: try {
0610: _handler.handle(callbacks);
0611: } catch (Exception e) {
0612: log
0613: .log(
0614: Level.SEVERE,
0615: "WSS0216.callbackhandler.handle.exception",
0616: new Object[] { "Authenticating User against list of Known username-password pairs" });
0617: throw new XWSSecurityException(e);
0618: }
0619:
0620: // zero the password
0621: if (pwd != null)
0622: pvCallback.clearPassword();
0623:
0624: if (log.isLoggable(Level.FINE)) {
0625: log.log(Level.FINE, "Username Authentication done for "
0626: + username);
0627: }
0628:
0629: return pvCallback.getResult();
0630: }
0631:
0632: /**
0633: * Authenticate the user given the password digest.
0634: *
0635: * @param username
0636: * @param passwordDigest
0637: * @param nonce
0638: * @param created
0639: * @return true if the password digest is valid
0640: */
0641: public boolean authenticateUser(Map context, String username,
0642: String passwordDigest, String nonce, String created)
0643: throws XWSSecurityException {
0644: /*
0645: can not implement
0646: */
0647: return false;
0648: }
0649:
0650: /**
0651: * Validate an X509Certificate.
0652: * @return true, if the cert is a valid one, false o/w.
0653: * @throws XWSSecurityException
0654: * if there is some problem during validation.
0655: */
0656: public boolean validateCertificate(X509Certificate cert)
0657: throws XWSSecurityException {
0658: /*
0659: use TrustStore and CertStore
0660: */
0661: try {
0662: cert.checkValidity();
0663: } catch (CertificateExpiredException e) {
0664: log.log(Level.SEVERE, "WSS0298.X509.expired", e);
0665: throw new XWSSecurityException("X509Certificate Expired", e);
0666: } catch (CertificateNotYetValidException e) {
0667: log.log(Level.SEVERE, "WSS0299.X509.notValid", e);
0668: throw new XWSSecurityException(
0669: "X509Certificate not yet valid", e);
0670: }
0671:
0672: X509CertSelector certSelector = new X509CertSelector();
0673: certSelector.setCertificate(cert);
0674:
0675: PKIXBuilderParameters parameters;
0676: CertPathBuilder builder;
0677: try {
0678: Callback[] callbacks = null;
0679: CertStoreCallback csCallback = null;
0680: TrustStoreCallback tsCallback = null;
0681:
0682: if (tsCallback == null && csCallback == null) {
0683: csCallback = new CertStoreCallback();
0684: tsCallback = new TrustStoreCallback();
0685: callbacks = new Callback[] { csCallback, tsCallback };
0686: } else if (csCallback == null) {
0687: csCallback = new CertStoreCallback();
0688: callbacks = new Callback[] { csCallback };
0689: } else if (tsCallback == null) {
0690: tsCallback = new TrustStoreCallback();
0691: callbacks = new Callback[] { tsCallback };
0692: }
0693:
0694: try {
0695: _handler.handle(callbacks);
0696: } catch (Exception e) {
0697: log.log(Level.SEVERE,
0698: "WSS0216.callbackhandler.handle.exception",
0699: new Object[] { "Validate an X509Certificate" });
0700: throw new XWSSecurityException(e);
0701: }
0702:
0703: parameters = new PKIXBuilderParameters(tsCallback
0704: .getTrustStore(), certSelector);
0705: parameters.setRevocationEnabled(revocationEnabled);
0706: parameters.addCertStore(csCallback.getCertStore());
0707: builder = CertPathBuilder.getInstance("PKIX");
0708: } catch (Exception e) {
0709: // Log Message
0710: log.log(Level.SEVERE,
0711: "WSS0223.failed.certificate.validation", e);
0712: throw new XWSSecurityException(e);
0713: }
0714:
0715: try {
0716: PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) builder
0717: .build(parameters);
0718: } catch (Exception e) {
0719: log.log(Level.SEVERE,
0720: "WSS0223.failed.certificate.validation", e);
0721: throw new XWSSecurityException(e);
0722: }
0723:
0724: if (log.isLoggable(Level.FINE)) {
0725: log.log(Level.FINE,
0726: "Certificate Validation called on certificate "
0727: + cert.getSubjectDN());
0728: }
0729:
0730: return true;
0731: }
0732:
0733: /**
0734: * @param keyIdMatch
0735: * KeyIdentifier to search for
0736: * @return the matching Certificate
0737: */
0738: public X509Certificate getMatchingCertificate(Map context,
0739: byte[] keyIdMatch) throws XWSSecurityException {
0740:
0741: Subject subject = getSubject(context);
0742: if (subject != null) {
0743: Set set = subject
0744: .getPrivateCredentials(X500PrivateCredential.class);
0745: if (set != null) {
0746: Iterator it = set.iterator();
0747: while (it.hasNext()) {
0748: X500PrivateCredential cred = (X500PrivateCredential) it
0749: .next();
0750: X509Certificate cert = cred.getCertificate();
0751: if (matchesKeyIdentifier(keyIdMatch, cert))
0752: return cert;
0753: }
0754: }
0755: }
0756:
0757: PrivateKeyCallback.Request request = new PrivateKeyCallback.SubjectKeyIDRequest(
0758: keyIdMatch);
0759: PrivateKeyCallback pkCallback = new PrivateKeyCallback(request);
0760: CertStoreCallback csCallback = new CertStoreCallback();
0761: TrustStoreCallback tsCallback = new TrustStoreCallback();
0762:
0763: Callback[] callbacks = new Callback[] { pkCallback, tsCallback,
0764: csCallback };
0765:
0766: try {
0767: _handler.handle(callbacks);
0768: } catch (Exception e) {
0769: log
0770: .log(
0771: Level.SEVERE,
0772: "WSS0216.callbackhandler.handle.exception",
0773: new Object[] { "PrivateKeyCallback.SubjectKeyIDRequest" });
0774: throw new XWSSecurityException(e);
0775: }
0776:
0777: Certificate[] chain = pkCallback.getChain();
0778: if (chain != null) {
0779: if (chain.length == 1) {
0780: return (X509Certificate) chain[0];
0781: }
0782: for (int i = 0; i < chain.length; i++) {
0783: X509Certificate x509Cert = (X509Certificate) chain[i];
0784: if (matchesKeyIdentifier(keyIdMatch, x509Cert))
0785: return x509Cert;
0786: }
0787: }
0788:
0789: // if not found, look in CertStore followed by TrustStore
0790: CertStore certStore = csCallback.getCertStore();
0791: if (certStore != null) {
0792: CertSelector selector = new KeyIdentifierCertSelector(
0793: keyIdMatch);
0794: try {
0795: Collection certs = certStore.getCertificates(selector);
0796: if (!certs.isEmpty()) {
0797: Iterator it = certs.iterator();
0798: return (X509Certificate) it.next();
0799: }
0800: } catch (CertStoreException ex) {
0801: //ex.printStackTrace();
0802: log.log(Level.SEVERE,
0803: "WSS0713.error.in.certstore.lookup", ex);
0804: throw new XWSSecurityException(ex);
0805: }
0806: }
0807:
0808: KeyStore trustStore = tsCallback.getTrustStore();
0809: if (trustStore != null) {
0810: X509Certificate otherPartyCert = getMatchingCertificate(
0811: keyIdMatch, trustStore);
0812: if (otherPartyCert != null)
0813: return otherPartyCert;
0814: }
0815:
0816: // if still not found, throw Exception
0817: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
0818: new Object[] { keyIdMatch });
0819: throw new XWSSecurityException("No Matching Certificate for :"
0820: + new String(keyIdMatch)
0821: + " found in KeyStore or TrustStore");
0822: }
0823:
0824: public X509Certificate getMatchingCertificate(Map context,
0825: BigInteger serialNumber, String issuerName)
0826: throws XWSSecurityException {
0827:
0828: Subject subject = getSubject(context);
0829: if (subject != null) {
0830: Set set = subject
0831: .getPrivateCredentials(X500PrivateCredential.class);
0832: if (set != null) {
0833: Iterator it = set.iterator();
0834: while (it.hasNext()) {
0835: X500PrivateCredential cred = (X500PrivateCredential) it
0836: .next();
0837: X509Certificate x509Cert = cred.getCertificate();
0838: BigInteger serialNo = x509Cert.getSerialNumber();
0839: String currentIssuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0840: .normalize(x509Cert.getIssuerDN().getName());
0841: if (serialNo.equals(serialNumber)
0842: && currentIssuerName.equals(issuerName)) {
0843: return x509Cert;
0844: }
0845: }
0846: }
0847: }
0848:
0849: PrivateKeyCallback.Request request = new PrivateKeyCallback.IssuerSerialNumRequest(
0850: new X500Principal(issuerName), serialNumber);
0851: PrivateKeyCallback pkCallback = new PrivateKeyCallback(request);
0852: TrustStoreCallback tsCallback = new TrustStoreCallback();
0853: CertStoreCallback csCallback = new CertStoreCallback();
0854:
0855: Callback[] callbacks = new Callback[] { pkCallback, csCallback,
0856: tsCallback };
0857:
0858: try {
0859: _handler.handle(callbacks);
0860: } catch (Exception e) {
0861: log
0862: .log(
0863: Level.SEVERE,
0864: "WSS0216.callbackhandler.handle.exception",
0865: new Object[] { "PrivateKeyCallback.IssuerSerialNumRequest" });
0866: throw new XWSSecurityException(e);
0867: }
0868:
0869: Certificate[] chain = pkCallback.getChain();
0870: if (chain != null) {
0871: if (chain.length == 1) {
0872: return (X509Certificate) chain[0];
0873: }
0874: for (int i = 0; i < chain.length; i++) {
0875: X509Certificate x509Cert = (X509Certificate) chain[i];
0876: if (matchesIssuerSerialAndName(serialNumber,
0877: issuerName, x509Cert))
0878: return x509Cert;
0879: }
0880: } else {
0881: if (log.isLoggable(Level.FINE)) {
0882: log.log(Level.FINE, "WSS0296.null.chain.cert");
0883: }
0884: }
0885:
0886: // if not found, look in CertStore followed by TrustStore
0887: CertStore certStore = csCallback.getCertStore();
0888: if (certStore != null) {
0889: CertSelector selector = new IssuerNameAndSerialCertSelector(
0890: serialNumber, issuerName);
0891: try {
0892: Collection certs = certStore.getCertificates(selector);
0893: if (!certs.isEmpty()) {
0894: Iterator it = certs.iterator();
0895: return (X509Certificate) it.next();
0896: }
0897: } catch (CertStoreException ex) {
0898: //ex.printStackTrace();
0899: log.log(Level.SEVERE,
0900: "WSS0713.error.in.certstore.lookup", ex);
0901: throw new XWSSecurityException(ex);
0902: }
0903: }
0904:
0905: // if not found, look in Truststore
0906: KeyStore trustStore = tsCallback.getTrustStore();
0907: if (trustStore != null) {
0908: X509Certificate otherPartyCert = getMatchingCertificate(
0909: serialNumber, issuerName, trustStore);
0910: if (otherPartyCert != null)
0911: return otherPartyCert;
0912: } else {
0913: // log
0914: log.log(Level.SEVERE, "WSS0707.null.truststore");
0915: }
0916:
0917: // if still not found, throw Exception
0918: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
0919: new Object[] { issuerName + " : " + serialNumber });
0920: throw new XWSSecurityException("No Matching Certificate for :"
0921: + issuerName + " : " + serialNumber
0922: + " found in KeyStore or TrustStore");
0923: }
0924:
0925: /**
0926: * @param keyIdMatch
0927: * KeyIdentifier to search for
0928: * @return the matching Certificate
0929: */
0930: public X509Certificate getMatchingCertificate(Map context,
0931: byte[] keyIdMatch, String valueType)
0932: throws XWSSecurityException {
0933:
0934: if (MessageConstants.KEY_INDETIFIER_TYPE.equals(valueType)) {
0935: return getMatchingCertificate(context, keyIdMatch);
0936: }
0937:
0938: if (!MessageConstants.THUMB_PRINT_TYPE.equals(valueType)) {
0939: throw new XWSSecurityException(
0940: "Internal Error : Unsupported Valuetype :"
0941: + valueType
0942: + " passed to getMatchingCertificate()");
0943: }
0944: // handle thumbprint here
0945: Subject subject = getSubject(context);
0946: if (subject != null) {
0947: Set set = subject
0948: .getPrivateCredentials(X500PrivateCredential.class);
0949: if (set != null) {
0950: Iterator it = set.iterator();
0951: while (it.hasNext()) {
0952: X500PrivateCredential cred = (X500PrivateCredential) it
0953: .next();
0954: X509Certificate cert = cred.getCertificate();
0955: if (matchesThumbPrint(keyIdMatch, cert))
0956: return cert;
0957: }
0958: }
0959: }
0960:
0961: PrivateKeyCallback.Request request = new PrivateKeyCallback.DigestRequest(
0962: keyIdMatch, "SHA-1");
0963: PrivateKeyCallback pkCallback = new PrivateKeyCallback(request);
0964: TrustStoreCallback tsCallback = new TrustStoreCallback();
0965: CertStoreCallback csCallback = new CertStoreCallback();
0966:
0967: Callback[] callbacks = new Callback[] { pkCallback, csCallback,
0968: tsCallback };
0969:
0970: try {
0971: _handler.handle(callbacks);
0972: } catch (Exception e) {
0973: log
0974: .log(
0975: Level.SEVERE,
0976: "WSS0216.callbackhandler.handle.exception",
0977: new Object[] { "PrivateKeyCallback.SubjectKeyIDRequest" });
0978: throw new XWSSecurityException(e);
0979: }
0980:
0981: Certificate[] chain = pkCallback.getChain();
0982: if (chain != null) {
0983: if (chain.length == 1) {
0984: return (X509Certificate) chain[0];
0985: }
0986: for (int i = 0; i < chain.length; i++) {
0987: X509Certificate x509Cert = (X509Certificate) chain[i];
0988: //why do i need to check again here, it is waste of time
0989: if (matchesThumbPrint(keyIdMatch, x509Cert)) {
0990: return x509Cert;
0991: }
0992: }
0993: }
0994:
0995: // if not found, look in CertStore followed by TrustStore
0996: CertStore certStore = csCallback.getCertStore();
0997: if (certStore != null) {
0998: CertSelector selector = new DigestCertSelector(keyIdMatch,
0999: MessageConstants.SHA1_DIGEST);
1000: try {
1001: Collection certs = certStore.getCertificates(selector);
1002: if (!certs.isEmpty()) {
1003: Iterator it = certs.iterator();
1004: return (X509Certificate) it.next();
1005: }
1006: } catch (CertStoreException ex) {
1007: //ex.printStackTrace();
1008: log.log(Level.SEVERE,
1009: "WSS0713.error.in.certstore.lookup", ex);
1010: throw new XWSSecurityException(ex);
1011: }
1012: }
1013:
1014: // if not found, look in Truststore
1015: KeyStore trustStore = tsCallback.getTrustStore();
1016: if (trustStore != null) {
1017: X509Certificate otherPartyCert = getMatchingCertificate(
1018: keyIdMatch, trustStore, valueType);
1019: if (otherPartyCert != null)
1020: return otherPartyCert;
1021: }
1022:
1023: // if still not found, throw Exception
1024: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
1025: new Object[] { keyIdMatch });
1026: throw new XWSSecurityException("No Matching Certificate for :"
1027: + new String(keyIdMatch)
1028: + " found in KeyStore or TrustStore");
1029: }
1030:
1031: public SecretKey getSecretKey(Map context, String alias,
1032: boolean encryptMode) throws XWSSecurityException {
1033: /*
1034: Use SecretKeyCallback
1035: */
1036: SecretKeyCallback.Request request = new SecretKeyCallback.AliasRequest(
1037: alias);
1038: SecretKeyCallback skCallback = new SecretKeyCallback(request);
1039: Callback[] callbacks = new Callback[] { skCallback };
1040: try {
1041: _handler.handle(callbacks);
1042: } catch (Exception e) {
1043: log.log(Level.SEVERE,
1044: "WSS0216.callbackhandler.handle.exception",
1045: new Object[] { "SecretKeyCallback.AliasRequest" });
1046: throw new XWSSecurityException(e);
1047: }
1048:
1049: return (SecretKey) skCallback.getKey();
1050: }
1051:
1052: public X509Certificate getCertificate(Map context, String alias,
1053: boolean forSigning) throws XWSSecurityException {
1054: String actualAlias = alias;
1055:
1056: if (alias == null || "".equals(alias)) {
1057: if (forSigning) {
1058: if (this .myAlias != null) {
1059: actualAlias = this .myAlias;
1060: } else {
1061: //use the Alias selector if present.
1062: //NOTE: the keystoreCertSelector is actually an AliasSelector it
1063: // cannot be a certSelector (especially JSR 196 does not allow browsing
1064: // a keystore) to do cert selection.
1065: if (this .keystoreCertSelectorClass != null) {
1066: AliasSelector selector = null;
1067: try {
1068: selector = (AliasSelector) this .keystoreCertSelectorClass
1069: .newInstance();
1070: } catch (IllegalAccessException ex) {
1071: log
1072: .log(
1073: Level.SEVERE,
1074: "WSS1532.exception.instantiating.aliasselector",
1075: ex);
1076: throw new RuntimeException(ex);
1077: } catch (InstantiationException ex) {
1078: log
1079: .log(
1080: Level.SEVERE,
1081: "WSS1532.exception.instantiating.aliasselector",
1082: ex);
1083: throw new RuntimeException(ex);
1084: }
1085: actualAlias = selector.select(context);
1086: }
1087:
1088: }
1089: } else {
1090: //for encryption
1091: if (this .peerEntityAlias != null) {
1092: actualAlias = this .peerEntityAlias;
1093: }
1094: }
1095: }
1096: X509Certificate cert = null;
1097:
1098: PrivateKeyCallback pkCallback = null;
1099: if (forSigning) {
1100: try {
1101: Subject subject = getSubject(context);
1102: if (subject != null) {
1103: Set set = subject
1104: .getPrivateCredentials(X500PrivateCredential.class);
1105: if (set != null) {
1106: Iterator it = set.iterator();
1107: while (it.hasNext()) {
1108: X500PrivateCredential cred = (X500PrivateCredential) it
1109: .next();
1110: if (cred.getAlias().equals(actualAlias))
1111: return cred.getCertificate();
1112: }
1113: }
1114: }
1115:
1116: PrivateKeyCallback.Request request = new PrivateKeyCallback.AliasRequest(
1117: actualAlias);
1118: pkCallback = new PrivateKeyCallback(request);
1119: Callback[] callbacks = new Callback[] { pkCallback };
1120: _handler.handle(callbacks);
1121: } catch (Exception e) {
1122: log.log(Level.SEVERE, "WSS0221.cannot.locate.cert",
1123: new Object[] { alias });
1124: throw new XWSSecurityException(e);
1125: }
1126:
1127: Certificate[] chain = pkCallback.getChain();
1128: if (chain != null) {
1129: cert = (X509Certificate) chain[0];
1130: } else {
1131: if (log.isLoggable(Level.FINE)) {
1132: log.log(Level.SEVERE, "WSS0296.null.chain.cert");
1133: }
1134: }
1135: } else {
1136: //for encryption
1137: if (actualAlias != null && !"".equals(actualAlias)) {
1138: TrustStoreCallback tsCallback = new TrustStoreCallback();
1139: Callback[] _callbacks = new Callback[] { tsCallback };
1140: try {
1141: _handler.handle(_callbacks);
1142: } catch (IOException ex) {
1143: log.log(Level.SEVERE, "WSS0221.cannot.locate.cert",
1144: new Object[] { alias });
1145: throw new XWSSecurityException(ex);
1146: } catch (UnsupportedCallbackException ex) {
1147: log.log(Level.SEVERE, "WSS0221.cannot.locate.cert",
1148: new Object[] { alias });
1149: throw new XWSSecurityException(ex);
1150: }
1151: if (tsCallback.getTrustStore() != null) {
1152: try {
1153: cert = (X509Certificate) tsCallback
1154: .getTrustStore().getCertificate(
1155: actualAlias);
1156: } catch (KeyStoreException ex) {
1157: log.log(Level.SEVERE,
1158: "WSS0221.cannot.locate.cert",
1159: new Object[] { alias });
1160: throw new XWSSecurityException(ex);
1161: }
1162: }
1163: } else {
1164:
1165: //actualAlias == null || "".equals(actualAlias)
1166: // first if certStore configured then give it a chance
1167: if (this .certSelectorClass != null) {
1168: CertStoreCallback csCallback = new CertStoreCallback();
1169: Callback[] _callbacks = new Callback[] { csCallback };
1170: try {
1171: _handler.handle(_callbacks);
1172: } catch (IOException ex) {
1173: log.log(Level.SEVERE,
1174: "WSS0221.cannot.locate.cert",
1175: new Object[] { alias });
1176: throw new XWSSecurityException(ex);
1177: } catch (UnsupportedCallbackException ex) {
1178: log.log(Level.SEVERE,
1179: "WSS0221.cannot.locate.cert",
1180: new Object[] { alias });
1181: throw new XWSSecurityException(ex);
1182: }
1183:
1184: if (csCallback.getCertStore() != null) {
1185: CertSelector selector = null;
1186: Constructor ctor = null;
1187: try {
1188: ctor = certSelectorClass
1189: .getConstructor(new Class[] { Map.class });
1190: } catch (SecurityException ex) {
1191: //ignore and use default CTOR
1192: } catch (NoSuchMethodException ex) {
1193: //ignore and use default CTOR
1194: }
1195: if (ctor != null) {
1196: try {
1197: selector = (CertSelector) ctor
1198: .newInstance(context);
1199: } catch (IllegalArgumentException ex) {
1200: log
1201: .log(
1202: Level.SEVERE,
1203: "WSS1531.exception.instantiating.certselector",
1204: ex);
1205: throw new RuntimeException(ex);
1206: } catch (InstantiationException ex) {
1207: log
1208: .log(
1209: Level.SEVERE,
1210: "WSS1531.exception.instantiating.certselector",
1211: ex);
1212: throw new RuntimeException(ex);
1213: } catch (InvocationTargetException ex) {
1214: log
1215: .log(
1216: Level.SEVERE,
1217: "WSS1531.exception.instantiating.certselector",
1218: ex);
1219: throw new RuntimeException(ex);
1220: } catch (IllegalAccessException ex) {
1221: log
1222: .log(
1223: Level.SEVERE,
1224: "WSS1531.exception.instantiating.certselector",
1225: ex);
1226: throw new RuntimeException(ex);
1227: }
1228: } else {
1229: try {
1230: selector = (CertSelector) certSelectorClass
1231: .newInstance();
1232: } catch (InstantiationException ex) {
1233: log
1234: .log(
1235: Level.SEVERE,
1236: "WSS1531.exception.instantiating.certselector",
1237: ex);
1238: throw new RuntimeException(ex);
1239: } catch (IllegalAccessException ex) {
1240: log
1241: .log(
1242: Level.SEVERE,
1243: "WSS1531.exception.instantiating.certselector",
1244: ex);
1245: throw new RuntimeException(ex);
1246: }
1247: }
1248:
1249: if (selector != null) {
1250: Collection certs = null;
1251: try {
1252: certs = csCallback.getCertStore()
1253: .getCertificates(selector);
1254: } catch (CertStoreException ex) {
1255: log
1256: .log(
1257: Level.SEVERE,
1258: "WSS1526.failedto.getcertificate",
1259: ex);
1260: throw new RuntimeException(ex);
1261: }
1262: if (certs.size() > 0) {
1263: cert = (X509Certificate) certs
1264: .iterator().next();
1265: }
1266: }
1267: }
1268: }
1269:
1270: if (cert == null
1271: && this .truststoreCertSelectorClass != null) {
1272:
1273: TrustStoreCallback tsCallback = new TrustStoreCallback();
1274: Callback[] _callbacks = new Callback[] { tsCallback };
1275: try {
1276: _handler.handle(_callbacks);
1277: } catch (IOException ex) {
1278: log.log(Level.SEVERE,
1279: "WSS0221.cannot.locate.cert",
1280: new Object[] { alias });
1281: throw new XWSSecurityException(ex);
1282: } catch (UnsupportedCallbackException ex) {
1283: log.log(Level.SEVERE,
1284: "WSS0221.cannot.locate.cert",
1285: new Object[] { alias });
1286: throw new XWSSecurityException(ex);
1287: }
1288:
1289: KeyStore trustStore = tsCallback.getTrustStore();
1290:
1291: if (trustStore != null) {
1292: if (this .truststoreCertSelectorClass != null) {
1293: CertSelector selector = null;
1294: Constructor ctor = null;
1295: try {
1296: ctor = truststoreCertSelectorClass
1297: .getConstructor(new Class[] { Map.class });
1298: } catch (SecurityException ex) {
1299: //ignore and use default CTOR
1300: } catch (NoSuchMethodException ex) {
1301: //ignore and use default CTOR
1302: }
1303: if (ctor != null) {
1304: try {
1305: selector = (CertSelector) ctor
1306: .newInstance(context);
1307: } catch (IllegalArgumentException ex) {
1308: log
1309: .log(
1310: Level.SEVERE,
1311: "WSS1531.exception.instantiating.certselector",
1312: ex);
1313: throw new RuntimeException(ex);
1314: } catch (InstantiationException ex) {
1315: log
1316: .log(
1317: Level.SEVERE,
1318: "WSS1531.exception.instantiating.certselector",
1319: ex);
1320: throw new RuntimeException(ex);
1321: } catch (InvocationTargetException ex) {
1322: log
1323: .log(
1324: Level.SEVERE,
1325: "WSS1531.exception.instantiating.certselector",
1326: ex);
1327: throw new RuntimeException(ex);
1328: } catch (IllegalAccessException ex) {
1329: log
1330: .log(
1331: Level.SEVERE,
1332: "WSS1531.exception.instantiating.certselector",
1333: ex);
1334: throw new RuntimeException(ex);
1335: }
1336: } else {
1337: try {
1338: selector = (CertSelector) truststoreCertSelectorClass
1339: .newInstance();
1340: } catch (InstantiationException ex) {
1341: log
1342: .log(
1343: Level.SEVERE,
1344: "WSS1531.exception.instantiating.certselector",
1345: ex);
1346: throw new RuntimeException(ex);
1347: } catch (IllegalAccessException ex) {
1348: log
1349: .log(
1350: Level.SEVERE,
1351: "WSS1531.exception.instantiating.certselector",
1352: ex);
1353: throw new RuntimeException(ex);
1354: }
1355: }
1356:
1357: if (selector != null) {
1358: Enumeration aliases = null;
1359: try {
1360: aliases = trustStore.aliases();
1361: } catch (KeyStoreException ex) {
1362: log
1363: .log(
1364: Level.SEVERE,
1365: "WSS1526.failedto.getcertificate",
1366: ex);
1367: throw new RuntimeException(ex);
1368: }
1369: while (aliases.hasMoreElements()) {
1370: String currAlias = (String) aliases
1371: .nextElement();
1372: Certificate this Certificate = null;
1373: try {
1374: this Certificate = trustStore
1375: .getCertificate(currAlias);
1376: } catch (KeyStoreException ex) {
1377: log
1378: .log(
1379: Level.SEVERE,
1380: "WSS1526.failedto.getcertificate",
1381: ex);
1382: throw new RuntimeException(ex);
1383: }
1384: if ((this Certificate instanceof X509Certificate)
1385: && selector
1386: .match(this Certificate)) {
1387: return (X509Certificate) this Certificate;
1388: }
1389: }
1390: }
1391: }
1392: }
1393: }
1394: if (cert == null) {
1395: cert = getDynamicCertificate(context);
1396: }
1397: }
1398: }
1399:
1400: if (cert == null) {
1401: log.log(Level.SEVERE, "WSS0221.cannot.locate.cert",
1402: new Object[] { actualAlias });
1403: throw new XWSSecurityException(
1404: "Unable to locate certificate for the alias '"
1405: + actualAlias + "'");
1406: }
1407:
1408: return cert;
1409: }
1410:
1411: private boolean matchesKeyIdentifier(byte[] keyIdMatch,
1412: X509Certificate x509Cert) throws XWSSecurityException {
1413:
1414: byte[] keyId = X509SubjectKeyIdentifier
1415: .getSubjectKeyIdentifier(x509Cert);
1416: if (keyId == null) {
1417: // Cert does not contain a key identifier
1418: return false;
1419: }
1420:
1421: if (Arrays.equals(keyIdMatch, keyId)) {
1422: return true;
1423: }
1424: return false;
1425: }
1426:
1427: public static byte[] getThumbprintIdentifier(X509Certificate cert)
1428: throws XWSSecurityException {
1429: byte[] thumbPrintIdentifier = null;
1430:
1431: try {
1432: thumbPrintIdentifier = MessageDigest.getInstance("SHA-1")
1433: .digest(cert.getEncoded());
1434: } catch (NoSuchAlgorithmException ex) {
1435: log.log(Level.SEVERE, "WSS0708.no.digest.algorithm");
1436: throw new XWSSecurityException(
1437: "Digest algorithm SHA-1 not found");
1438: } catch (CertificateEncodingException ex) {
1439: log.log(Level.SEVERE, "WSS0709.error.getting.rawContent");
1440: throw new XWSSecurityException(
1441: "Error while getting certificate's raw content");
1442: }
1443: return thumbPrintIdentifier;
1444: }
1445:
1446: private boolean matchesThumbPrint(byte[] keyIdMatch,
1447: X509Certificate x509Cert) throws XWSSecurityException {
1448:
1449: byte[] keyId = getThumbprintIdentifier(x509Cert);
1450: if (keyId == null) {
1451: // Cert does not contain a key identifier
1452: return false;
1453: }
1454:
1455: if (Arrays.equals(keyIdMatch, keyId)) {
1456: return true;
1457: }
1458: return false;
1459: }
1460:
1461: private X509Certificate getMatchingCertificate(byte[] keyIdMatch,
1462: KeyStore kStore) throws XWSSecurityException {
1463:
1464: if (kStore == null) {
1465: return null;
1466: }
1467:
1468: try {
1469: Enumeration enum1 = kStore.aliases();
1470: while (enum1.hasMoreElements()) {
1471: String alias = (String) enum1.nextElement();
1472:
1473: Certificate cert = kStore.getCertificate(alias);
1474: if (cert == null || !"X.509".equals(cert.getType())) {
1475: continue;
1476: }
1477:
1478: X509Certificate x509Cert = (X509Certificate) cert;
1479: byte[] keyId = X509SubjectKeyIdentifier
1480: .getSubjectKeyIdentifier(x509Cert);
1481: if (keyId == null) {
1482: // Cert does not contain a key identifier
1483: continue;
1484: }
1485:
1486: if (Arrays.equals(keyIdMatch, keyId)) {
1487: return x509Cert;
1488: }
1489: }
1490: } catch (KeyStoreException kEx) {
1491: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
1492: new Object[] { keyIdMatch });
1493: throw new XWSSecurityException(
1494: "No Matching Certificate for :"
1495: + new String(keyIdMatch)
1496: + " found in KeyStore.", kEx);
1497: }
1498: return null;
1499: }
1500:
1501: private X509Certificate getMatchingCertificate(byte[] keyIdMatch,
1502: KeyStore kStore, String valueType)
1503: throws XWSSecurityException {
1504:
1505: if (MessageConstants.KEY_INDETIFIER_TYPE.equals(valueType)) {
1506: return getMatchingCertificate(keyIdMatch, kStore);
1507: }
1508:
1509: if (!MessageConstants.THUMB_PRINT_TYPE.equals(valueType)) {
1510: throw new XWSSecurityException(
1511: "Internal Error : Unsupported Valuetype :"
1512: + valueType
1513: + " passed to getMatchingCertificate()");
1514: }
1515: // now handle thumbprint here
1516: if (kStore == null) {
1517: return null;
1518: }
1519:
1520: try {
1521: Enumeration enum1 = kStore.aliases();
1522: while (enum1.hasMoreElements()) {
1523: String alias = (String) enum1.nextElement();
1524:
1525: Certificate cert = kStore.getCertificate(alias);
1526: if (cert == null || !"X.509".equals(cert.getType())) {
1527: continue;
1528: }
1529:
1530: X509Certificate x509Cert = (X509Certificate) cert;
1531: byte[] keyId = getThumbprintIdentifier(x509Cert);
1532:
1533: if (Arrays.equals(keyIdMatch, keyId)) {
1534: return x509Cert;
1535: }
1536: }
1537: } catch (KeyStoreException kEx) {
1538: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
1539: new Object[] { keyIdMatch });
1540: throw new XWSSecurityException(
1541: "No Matching Certificate for :"
1542: + new String(keyIdMatch)
1543: + " found in KeyStore.", kEx);
1544: }
1545: return null;
1546: }
1547:
1548: private boolean matchesIssuerSerialAndName(
1549: BigInteger serialNumberMatch, String issuerNameMatch,
1550: X509Certificate x509Cert) {
1551:
1552: BigInteger serialNumber = x509Cert.getSerialNumber();
1553: String issuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
1554: .normalize(x509Cert.getIssuerDN().getName());
1555:
1556: if (serialNumber.equals(serialNumberMatch)
1557: && issuerName.equals(issuerNameMatch)) {
1558: return true;
1559: }
1560: return false;
1561: }
1562:
1563: private X509Certificate getMatchingCertificate(
1564: BigInteger serialNumber, String issuerName, KeyStore kStore)
1565: throws XWSSecurityException {
1566:
1567: if (kStore == null) {
1568: return null;
1569: }
1570: try {
1571: Enumeration enum1 = kStore.aliases();
1572: while (enum1.hasMoreElements()) {
1573: String alias = (String) enum1.nextElement();
1574:
1575: Certificate cert = kStore.getCertificate(alias);
1576: if (cert == null || !"X.509".equals(cert.getType())) {
1577: continue;
1578: }
1579:
1580: X509Certificate x509Cert = (X509Certificate) cert;
1581: BigInteger serialNo = x509Cert.getSerialNumber();
1582: String currentIssuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
1583: .normalize(x509Cert.getIssuerDN().getName());
1584:
1585: if (serialNo.equals(serialNumber)
1586: && currentIssuerName.equals(issuerName)) {
1587: return x509Cert;
1588: }
1589: }
1590: } catch (KeyStoreException kEx) {
1591: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
1592: new Object[] { issuerName + " : " + serialNumber });
1593: throw new XWSSecurityException(
1594: "No Matching Certificate for :" + issuerName
1595: + " : " + serialNumber
1596: + " found in KeyStore.", kEx);
1597: }
1598: return null;
1599: }
1600:
1601: private X509Certificate getMatchingCertificate(PublicKey publicKey,
1602: KeyStore kStore) throws XWSSecurityException {
1603:
1604: if (kStore == null) {
1605: return null;
1606: }
1607: try {
1608: Enumeration enum1 = kStore.aliases();
1609: while (enum1.hasMoreElements()) {
1610: String alias = (String) enum1.nextElement();
1611:
1612: Certificate cert = kStore.getCertificate(alias);
1613: if (cert == null || !"X.509".equals(cert.getType())) {
1614: continue;
1615: }
1616: X509Certificate x509Cert = (X509Certificate) cert;
1617: if (x509Cert.getPublicKey().equals(publicKey))
1618: return x509Cert;
1619: }
1620: } catch (KeyStoreException kEx) {
1621: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
1622: new Object[] { publicKey });
1623: throw new XWSSecurityException(
1624: "No Matching Certificate for :" + publicKey
1625: + " found in KeyStore.", kEx);
1626: }
1627: return null;
1628: }
1629:
1630: public void updateOtherPartySubject(Subject subject,
1631: String username, String password) {
1632: /*
1633: String x500Name = "CN=" + username;
1634: Principal principal = new X500Principal(x500Name);
1635: subject.getPrincipals().add(principal);
1636: subject.getPrivateCredentials().add(password);*/
1637: CallerPrincipalCallback pvCallback = new CallerPrincipalCallback(
1638: subject, username);
1639: Callback[] callbacks = new Callback[] { pvCallback };
1640: try {
1641: _handler.handle(callbacks);
1642: } catch (Exception e) {
1643: log.log(Level.SEVERE,
1644: "WSS0216.callbackhandler.handle.exception",
1645: new Object[] { "CallerPrincipalCallback" });
1646: throw new RuntimeException(e);
1647: }
1648: }
1649:
1650: public void updateOtherPartySubject(final Subject subject,
1651: final X509Certificate cert) {
1652:
1653: AccessController.doPrivileged(new PrivilegedAction() {
1654: public Object run() {
1655: Principal principal = cert.getSubjectX500Principal();
1656: subject.getPrincipals().add(principal);
1657: subject.getPublicCredentials().add(cert);
1658: return null;
1659: }
1660: });
1661: }
1662:
1663: public void updateOtherPartySubject(final Subject subject,
1664: final Assertion assertion) {
1665: AccessController.doPrivileged(new PrivilegedAction() {
1666: public Object run() {
1667: subject.getPublicCredentials().add(assertion);
1668: return null;
1669: }
1670: });
1671: }
1672:
1673: public PublicKey getPublicKey(Map context, BigInteger serialNumber,
1674: String issuerName) throws XWSSecurityException {
1675: return getMatchingCertificate(context, serialNumber, issuerName)
1676: .getPublicKey();
1677: }
1678:
1679: public PublicKey getPublicKey(String keyIdentifier)
1680: throws XWSSecurityException {
1681: try {
1682: return getMatchingCertificate(null,
1683: getDecodedBase64EncodedData(keyIdentifier))
1684: .getPublicKey();
1685: } catch (Exception e) {
1686: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
1687: new Object[] { keyIdentifier });
1688: throw new XWSSecurityException(
1689: "No Matching Certificate for :" + keyIdentifier
1690: + " found in KeyStore ");
1691: }
1692: }
1693:
1694: public PublicKey getPublicKey(Map context, byte[] keyIdentifier)
1695: throws XWSSecurityException {
1696: try {
1697: return getMatchingCertificate(context, keyIdentifier)
1698: .getPublicKey();
1699: } catch (Exception e) {
1700: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
1701: new Object[] { keyIdentifier });
1702: throw new XWSSecurityException(e);
1703: }
1704: }
1705:
1706: public PublicKey getPublicKey(Map context, byte[] identifier,
1707: String valueType) throws XWSSecurityException {
1708: return getMatchingCertificate(context, identifier, valueType)
1709: .getPublicKey();
1710: }
1711:
1712: private byte[] getDecodedBase64EncodedData(String encodedData)
1713: throws XWSSecurityException {
1714: try {
1715: return Base64.decode(encodedData);
1716: } catch (Base64DecodingException e) {
1717: log.log(Level.SEVERE,
1718: "WSS0144.unableto.decode.base64.data", e);
1719: throw new SecurityHeaderException(
1720: "Unable to decode Base64 encoded data", e);
1721: }
1722: }
1723:
1724: public X509Certificate getCertificate(Map context,
1725: BigInteger serialNumber, String issuerName)
1726: throws XWSSecurityException {
1727:
1728: return getMatchingCertificate(context, serialNumber, issuerName);
1729: }
1730:
1731: public X509Certificate getCertificate(String keyIdentifier)
1732: throws XWSSecurityException {
1733: try {
1734: byte[] decoded = getDecodedBase64EncodedData(keyIdentifier);
1735: return getMatchingCertificate(null, decoded);
1736: } catch (Exception e) {
1737: log.log(Level.SEVERE,
1738: "WSS0711.error.match.cert.for.decoded.string", e);
1739: throw new XWSSecurityException(e);
1740: }
1741: }
1742:
1743: public PrivateKey getPrivateKey(Map context, PublicKey publicKey,
1744: boolean forSign) {
1745: throw new UnsupportedOperationException(
1746: "getPrivateKey(Map context, PublicKey publicKey, boolean forSign)");
1747: }
1748:
1749: public X509Certificate getCertificate(Map context, byte[] ski) {
1750: try {
1751: return this .getMatchingCertificate(context, ski);
1752: } catch (XWSSecurityException ex) {
1753: throw new RuntimeException(ex);
1754: }
1755: }
1756:
1757: public X509Certificate getCertificate(Map context,
1758: PublicKey publicKey, boolean forSign)
1759: throws XWSSecurityException {
1760: Subject subject = getSubject(context);
1761: if (subject != null) {
1762: Set set = subject
1763: .getPrivateCredentials(X500PrivateCredential.class);
1764: if (set != null) {
1765: Iterator it = set.iterator();
1766: while (it.hasNext()) {
1767: X500PrivateCredential cred = (X500PrivateCredential) it
1768: .next();
1769: X509Certificate cert = cred.getCertificate();
1770: if (cert.getPublicKey().equals(publicKey))
1771: return cert;
1772: }
1773: }
1774: }
1775:
1776: if (!forSign) {
1777: CertStoreCallback csCallback = new CertStoreCallback();
1778: TrustStoreCallback tsCallback = new TrustStoreCallback();
1779: Callback[] callbacks = new Callback[] { csCallback,
1780: tsCallback };
1781:
1782: try {
1783: _handler.handle(callbacks);
1784: } catch (Exception e) {
1785: log.log(Level.SEVERE,
1786: "WSS0216.callbackhandler.handle.exception",
1787: new Object[] { "CertStoreCallback" });
1788: throw new XWSSecurityException(e);
1789: }
1790: // look in CertStore followed by Truststore to get certificate of a publicKey passed as argument
1791: CertStore certStore = csCallback.getCertStore();
1792: if (certStore != null) {
1793: CertSelector selector = new PublicKeyCertSelector(
1794: publicKey);
1795: try {
1796: Collection certs = certStore
1797: .getCertificates(selector);
1798: if (!certs.isEmpty()) {
1799: Iterator it = certs.iterator();
1800: return (X509Certificate) it.next();
1801: }
1802: } catch (CertStoreException ex) {
1803: log.log(Level.SEVERE,
1804: "WSS0713.error.in.certstore.lookup", ex);
1805: throw new XWSSecurityException(ex);
1806: }
1807: }
1808:
1809: KeyStore trustStore = tsCallback.getTrustStore();
1810: if (trustStore != null) {
1811: X509Certificate otherPartyCert = getMatchingCertificate(
1812: publicKey, trustStore);
1813: if (otherPartyCert != null)
1814: return otherPartyCert;
1815: }
1816: } else {
1817: // search in keystore
1818: //TODO: not required currently, and also we cannot browse the GF keystore via 196 callbacks
1819: }
1820:
1821: // if still not found, throw Exception
1822: log.log(Level.SEVERE, "WSS0706.no.matching.cert",
1823: new Object[] { publicKey });
1824: throw new XWSSecurityException("No Matching Certificate for :"
1825: + publicKey + " found in KeyStore or TrustStore");
1826: }
1827:
1828: public X509Certificate getCertificate(Map context,
1829: byte[] identifier, String valueType)
1830: throws XWSSecurityException {
1831: if (com.sun.xml.wss.impl.MessageConstants.KEY_INDETIFIER_TYPE
1832: .equals(valueType)) {
1833: return this .getMatchingCertificate(context, identifier);
1834: }
1835: //Handle Thumbprint Reference here
1836: return this .getMatchingCertificate(context, identifier,
1837: valueType);
1838: }
1839:
1840: public boolean validateSamlIssuer(String issuer) {
1841: return true;
1842: }
1843:
1844: public boolean validateSamlUser(String user, String domain,
1845: String format) {
1846: return true;
1847: }
1848:
1849: public void setSubject(Subject subject, Map context) {
1850: context.put(MessageConstants.SELF_SUBJECT, subject);
1851: }
1852:
1853: public void setRequesterSubject(Subject subject, Map context) {
1854: context.put(MessageConstants.AUTH_SUBJECT, subject);
1855: }
1856:
1857: public Subject getSubject() {
1858: return null;
1859: }
1860:
1861: public Subject getSubject(Map context) {
1862: if (context == null) {
1863: return null;
1864: }
1865: return (Subject) context.get(MessageConstants.SELF_SUBJECT);
1866: }
1867:
1868: public Subject getRequesterSubject(final Map context) {
1869: if (context == null) {
1870: return null;
1871: }
1872: Subject otherPartySubject = (Subject) context
1873: .get(MessageConstants.AUTH_SUBJECT);
1874: if (otherPartySubject != null) {
1875: return otherPartySubject;
1876: }
1877: otherPartySubject = (Subject) AccessController
1878: .doPrivileged(new PrivilegedAction() {
1879: public Object run() {
1880: Subject otherPartySubj = new Subject();
1881: context.put(MessageConstants.AUTH_SUBJECT,
1882: otherPartySubj);
1883: return otherPartySubj;
1884: }
1885: });
1886: return otherPartySubject;
1887: }
1888:
1889: private Date getGMTDateWithSkewAdjusted(Calendar c, boolean addSkew) {
1890: long offset = c.get(Calendar.ZONE_OFFSET);
1891: if (c.getTimeZone().inDaylightTime(c.getTime())) {
1892: offset += c.getTimeZone().getDSTSavings();
1893: }
1894: long beforeTime = c.getTimeInMillis();
1895: long currentTime = beforeTime - offset;
1896:
1897: if (addSkew)
1898: currentTime = currentTime + MAX_CLOCK_SKEW;
1899: else
1900: currentTime = currentTime - MAX_CLOCK_SKEW;
1901:
1902: c.setTimeInMillis(currentTime);
1903: return c.getTime();
1904: }
1905:
1906: public String getUsername(Map context) throws XWSSecurityException {
1907:
1908: if (this .myUsername != null) {
1909: return this .myUsername;
1910: } else {
1911: String username = (String) context
1912: .get(BindingProvider.USERNAME_PROPERTY);
1913: if (username != null) {
1914: return username;
1915: }
1916: }
1917:
1918: if (!this .isAppClient) {
1919: //cannot make a Callback since GF CBH will throw UnSupported Exception
1920: // for a servlet client
1921: return null;
1922: }
1923: //this is an Appclient so try and make a callback.
1924: NameCallback nameCallback = new NameCallback("Username: ");
1925: try {
1926: Callback[] cbs = new Callback[] { nameCallback };
1927: _handler.handle(cbs);
1928: } catch (Exception e) {
1929: log.log(Level.SEVERE,
1930: "WSS0216.callbackhandler.handle.exception",
1931: new Object[] { "NameCallback" });
1932: throw new RuntimeException(e);
1933: }
1934:
1935: return nameCallback.getName();
1936: }
1937:
1938: public String getPassword(Map context) throws XWSSecurityException {
1939:
1940: //actually check if myPassword starts with $ etc
1941: if (this .myPassword != null) {
1942: if (this .myPassword.startsWith("$")) {
1943: String alias = this .myPassword.substring(1);
1944: SecretKeyCallback.AliasRequest ar = new SecretKeyCallback.AliasRequest(
1945: alias);
1946: SecretKeyCallback skcb = new SecretKeyCallback(ar);
1947: Callback[] callbacks = new Callback[] { skcb };
1948: try {
1949: this ._handler.handle(callbacks);
1950: javax.crypto.SecretKey key = skcb.getKey();
1951: byte[] password = key.getEncoded();
1952: return new String(password);
1953: } catch (Exception ex) {
1954: log
1955: .log(
1956: Level.SEVERE,
1957: "WSS0216.callbackhandler.handle.exception",
1958: new Object[] { "SecretKeyCallback.AliasRequest" });
1959: throw new XWSSecurityException(ex);
1960: }
1961: } else {
1962: return this .myPassword;
1963: }
1964: } else {
1965: String password = (String) context
1966: .get(BindingProvider.PASSWORD_PROPERTY);
1967: if (password != null) {
1968: return password;
1969: }
1970: }
1971:
1972: if (!this .isAppClient) {
1973: //servlet client: 109
1974: //cannot make callback so return null
1975: return null;
1976: }
1977: PasswordCallback pwdCallback = new PasswordCallback(
1978: "Password: ", false);
1979: try {
1980: Callback[] cbs = new Callback[] { pwdCallback };
1981: _handler.handle(cbs);
1982: } catch (Exception e) {
1983: log.log(Level.SEVERE,
1984: "WSS0225.failed.PasswordValidationCallback", e);
1985: throw new RuntimeException(e);
1986: }
1987:
1988: if (pwdCallback.getPassword() == null)
1989: return null;
1990:
1991: return new String(pwdCallback.getPassword());
1992: }
1993:
1994: public boolean validateAndCacheNonce(String nonce, String created,
1995: long maxNonceAge) throws XWSSecurityException {
1996: if ((nonceCache == null) || nonceCache.wasCanceled())
1997: initNonceCache(maxNonceAge);
1998:
1999: // check if the reclaimer Task is scheduled or not
2000: if (!nonceCache.isScheduled())
2001: setNonceCacheCleanup();
2002:
2003: return nonceCache.validateAndCacheNonce(nonce, created);
2004: }
2005:
2006: private synchronized void initNonceCache(long maxNonceAge) {
2007:
2008: if (nonceCache == null) {
2009: if (maxNonceAge == 0) {
2010: nonceCache = new NonceCache();
2011: } else {
2012: nonceCache = new NonceCache(maxNonceAge);
2013: }
2014: } else if (nonceCache.wasCanceled()) {
2015: if (maxNonceAge == 0) {
2016: nonceCache = new NonceCache();
2017: } else {
2018: nonceCache = new NonceCache(maxNonceAge);
2019: }
2020: }
2021: }
2022:
2023: private synchronized void setNonceCacheCleanup() {
2024:
2025: if (!nonceCache.isScheduled()) {
2026: nonceCleanupTimer.schedule(nonceCache, nonceCache
2027: .getMaxNonceAge(), // run it the first time after
2028: nonceCache.getMaxNonceAge()); //repeat every
2029: nonceCache.scheduled(true);
2030: }
2031: }
2032:
2033: public void validateTimestamp(Map context, String created,
2034: String expires, long maxClockSkew, long freshnessLimit)
2035: throws XWSSecurityException {
2036:
2037: if (expiresBeforeCreated(created, expires)) {
2038: log.log(Level.SEVERE, "WSS0232.expired.Message");
2039: XWSSecurityException xwsse = new XWSSecurityException(
2040: "Message expired!");
2041: throw DefaultSecurityEnvironmentImpl.newSOAPFaultException(
2042: MessageConstants.WSU_MESSAGE_EXPIRED,
2043: "Message expired!", xwsse);
2044: }
2045: validateCreationTime(context, created, maxClockSkew,
2046: freshnessLimit);
2047: validateExpirationTime(expires, maxClockSkew, freshnessLimit);
2048: }
2049:
2050: public void validateTimestamp(Map context, Timestamp timestamp,
2051: long maxClockSkew, long freshnessLimit)
2052: throws XWSSecurityException {
2053: validateTimestamp(context, timestamp.getCreated(), timestamp
2054: .getExpires(), maxClockSkew, freshnessLimit);
2055: }
2056:
2057: private static boolean expiresBeforeCreated(String creationTime,
2058: String expirationTime) throws XWSSecurityException {
2059: Date created = null;
2060: Date expires = null;
2061: try {
2062: try {
2063: synchronized (calendarFormatter1) {
2064: created = calendarFormatter1.parse(creationTime);
2065: }
2066: if (expirationTime != null) {
2067: synchronized (calendarFormatter1) {
2068: expires = calendarFormatter1
2069: .parse(expirationTime);
2070: }
2071: }
2072:
2073: } catch (java.text.ParseException pe) {
2074: synchronized (calendarFormatter2) {
2075: created = calendarFormatter2.parse(creationTime);
2076: }
2077: if (expirationTime != null) {
2078: synchronized (calendarFormatter2) {
2079: expires = calendarFormatter2
2080: .parse(expirationTime);
2081: }
2082: }
2083: }
2084: } catch (java.text.ParseException pe) {
2085: log.log(Level.SEVERE,
2086: "WSS0394.error.parsing.expirationtime");
2087: throw new XWSSecurityException(pe.getMessage());
2088: }
2089:
2090: if ((expires != null) && expires.before(created))
2091: return true;
2092:
2093: return false;
2094: }
2095:
2096: public void validateCreationTime(Map context, String creationTime,
2097: long maxClockSkew, long timestampFreshnessLimit)
2098: throws XWSSecurityException {
2099:
2100: long maxClockSkewActual = maxClockSkew;
2101: long freshnessLimitActual = timestampFreshnessLimit;
2102:
2103: if (this .mcs != null && this .maxClockSkewG >= 0) {
2104: maxClockSkewActual = this .maxClockSkewG;
2105: }
2106: if (this .tfl != null && this .timestampFreshnessLimitG > 0) {
2107: freshnessLimitActual = this .timestampFreshnessLimitG;
2108: }
2109:
2110: Date created;
2111: try {
2112: synchronized (calendarFormatter1) {
2113: created = calendarFormatter1.parse(creationTime);
2114: }
2115: } catch (java.text.ParseException pe) {
2116: try {
2117: synchronized (calendarFormatter2) {
2118: created = calendarFormatter2.parse(creationTime);
2119: }
2120: } catch (java.text.ParseException pe1) {
2121: log
2122: .log(
2123: Level.SEVERE,
2124: "WSS0226.failed.Validating.DefaultCreationTime",
2125: pe1);
2126: throw new XWSSecurityException(
2127: "Exception while parsing Creation Time :"
2128: + pe1.getMessage());
2129: }
2130: }
2131:
2132: Date current = null;
2133: try {
2134: current = getFreshnessAndSkewAdjustedDate(
2135: maxClockSkewActual, freshnessLimitActual);
2136:
2137: } catch (java.text.ParseException pe) {
2138: log.log(Level.SEVERE,
2139: "WSS0712.error.adjust.skew.freshness.time", pe);
2140: throw new XWSSecurityException(pe.getMessage());
2141: }
2142:
2143: if (created.before(current)) {
2144: XWSSecurityException xwsse = new XWSSecurityException(
2145: "Creation Time is older than configured Timestamp Freshness Interval!");
2146: throw DefaultSecurityEnvironmentImpl
2147: .newSOAPFaultException(
2148: MessageConstants.WSSE_INVALID_SECURITY,
2149: "Creation Time is older than configured Timestamp Freshness Interval!",
2150: xwsse);
2151: }
2152:
2153: Date currentTime = getGMTDateWithSkewAdjusted(
2154: new GregorianCalendar(), maxClockSkewActual, true);
2155:
2156: if (currentTime.before(created)) {
2157: XWSSecurityException xwsse = new XWSSecurityException(
2158: "Creation Time ahead of Current Time!");
2159: throw DefaultSecurityEnvironmentImpl.newSOAPFaultException(
2160: MessageConstants.WSSE_INVALID_SECURITY,
2161: "Creation Time ahead of Current Time!", xwsse);
2162: }
2163:
2164: }
2165:
2166: private void validateExpirationTime(String expirationTime,
2167: long maxClockSkew, long timestampFreshnessLimit)
2168: throws XWSSecurityException {
2169: long maxClockSkewActual = maxClockSkew;
2170: long freshnessLimitActual = timestampFreshnessLimit;
2171:
2172: if (this .mcs != null && this .maxClockSkewG >= 0) {
2173: maxClockSkewActual = this .maxClockSkewG;
2174: }
2175: if (this .tfl != null && this .timestampFreshnessLimitG > 0) {
2176: freshnessLimitActual = this .timestampFreshnessLimitG;
2177: }
2178:
2179: if (expirationTime != null) {
2180: Date expires;
2181: try {
2182: synchronized (calendarFormatter1) {
2183: expires = calendarFormatter1.parse(expirationTime);
2184: }
2185: } catch (java.text.ParseException pe) {
2186: try {
2187: synchronized (calendarFormatter2) {
2188: expires = calendarFormatter2
2189: .parse(expirationTime);
2190: }
2191: } catch (java.text.ParseException pe1) {
2192: log.log(Level.SEVERE,
2193: "WSS0394.error.parsing.expirationtime");
2194: throw new XWSSecurityException(
2195: "Exception while parsing Expiration Time :"
2196: + pe1.getMessage());
2197: }
2198: }
2199:
2200: Date currentTime = getGMTDateWithSkewAdjusted(
2201: new GregorianCalendar(), maxClockSkewActual, false);
2202:
2203: if (expires.before(currentTime)) {
2204: XWSSecurityException xwsse = new XWSSecurityException(
2205: "Message Expired!");
2206: throw DefaultSecurityEnvironmentImpl
2207: .newSOAPFaultException(
2208: MessageConstants.WSU_MESSAGE_EXPIRED,
2209: "Message Expired!", xwsse);
2210: }
2211: }
2212: }
2213:
2214: public CallbackHandler getCallbackHandler()
2215: throws XWSSecurityException {
2216: return _handler;
2217: }
2218:
2219: public void validateSAMLAssertion(Map context, Element assertion)
2220: throws XWSSecurityException {
2221: //Subject subj = (Subject) context.get(MessageConstants.AUTH_SUBJECT);
2222: if (sValidator != null) {
2223: try {
2224: sValidator.validate(assertion);
2225: } catch (SAMLAssertionValidator.SAMLValidationException e) {
2226: log.log(Level.SEVERE,
2227: "WSS0716.failed.validateSAMLAssertion", e);
2228: throw new XWSSecurityException(e);
2229: }
2230: }
2231: }
2232:
2233: public Element locateSAMLAssertion(Map context, Element binding,
2234: String assertionId, Document ownerDoc)
2235: throws XWSSecurityException {
2236:
2237: if (samlHandler != null) {
2238: SAMLCallback sc = new SAMLCallback();
2239: sc.setAssertionId(assertionId);
2240: sc.setAuthorityBindingElement(binding);
2241: Callback[] cbs = new Callback[] { sc };
2242: try {
2243: samlHandler.handle(cbs);
2244: } catch (UnsupportedCallbackException ex) {
2245: log.log(Level.SEVERE,
2246: "WSS0718.exception.invoking.samlHandler", ex);
2247: throw new XWSSecurityException(ex);
2248: } catch (IOException ex) {
2249: log.log(Level.SEVERE,
2250: "WSS0718.exception.invoking.samlHandler", ex);
2251: throw new XWSSecurityException(ex);
2252: }
2253: return sc.getAssertionElement();
2254:
2255: } else {
2256: log.log(Level.SEVERE, "WSS0717.no.SAMLCallbackHandler");
2257: throw new XWSSecurityException(
2258: new UnsupportedCallbackException(
2259: null,
2260: "A Required SAML Callback Handler was not specified in configuration : Cannot Populate SAML Assertion"));
2261: }
2262:
2263: }
2264:
2265: public AuthenticationTokenPolicy.SAMLAssertionBinding populateSAMLPolicy(
2266: Map fpcontext,
2267: AuthenticationTokenPolicy.SAMLAssertionBinding samlBinding,
2268: DynamicApplicationContext context)
2269: throws XWSSecurityException {
2270:
2271: AuthenticationTokenPolicy.SAMLAssertionBinding ret = (AuthenticationTokenPolicy.SAMLAssertionBinding) samlBinding
2272: .clone();
2273: if (samlBinding.getAssertionType() == AuthenticationTokenPolicy.SAMLAssertionBinding.SV_ASSERTION) {
2274:
2275: if (samlHandler != null) {
2276: SAMLCallback sc = new SAMLCallback();
2277: sc.setConfirmationMethod(sc.SV_ASSERTION_TYPE);
2278: sc.setSAMLVersion(samlBinding.getSAMLVersion());
2279: Callback[] cbs = new Callback[] { sc };
2280: try {
2281: samlHandler.handle(cbs);
2282: } catch (UnsupportedCallbackException ex) {
2283: log.log(Level.SEVERE,
2284: "WSS0718.exception.invoking.samlHandler",
2285: ex);
2286: throw new XWSSecurityException(ex);
2287: } catch (IOException ex) {
2288: log.log(Level.SEVERE,
2289: "WSS0718.exception.invoking.samlHandler",
2290: ex);
2291: throw new XWSSecurityException(ex);
2292: }
2293: ret.setAssertion(sc.getAssertionElement());
2294: ret.setAssertion(sc.getAssertionReader());
2295: ret
2296: .setAuthorityBinding(sc
2297: .getAuthorityBindingElement());
2298:
2299: } else {
2300: log.log(Level.SEVERE, "WSS0717.no.SAMLCallbackHandler");
2301: throw new XWSSecurityException(
2302: new UnsupportedCallbackException(
2303: null,
2304: "A Required SAML Callback Handler was not specified in configuration : Cannot Populate SAML Assertion"));
2305: }
2306:
2307: } else {
2308:
2309: if (samlHandler != null) {
2310:
2311: SAMLCallback sc = new SAMLCallback();
2312: sc.setConfirmationMethod(sc.HOK_ASSERTION_TYPE);
2313: sc.setSAMLVersion(samlBinding.getSAMLVersion());
2314: Callback[] cbs = new Callback[] { sc };
2315: try {
2316: samlHandler.handle(cbs);
2317: } catch (IOException ex) {
2318: log.log(Level.SEVERE,
2319: "WSS0718.exception.invoking.samlHandler",
2320: ex);
2321: throw new XWSSecurityException(ex);
2322: } catch (UnsupportedCallbackException ex) {
2323: log.log(Level.SEVERE,
2324: "WSS0718.exception.invoking.samlHandler",
2325: ex);
2326: throw new XWSSecurityException(ex);
2327: }
2328: ret.setAssertion(sc.getAssertionElement());
2329: ret
2330: .setAuthorityBinding(sc
2331: .getAuthorityBindingElement());
2332: ret.setAssertion(sc.getAssertionReader());
2333: PrivateKeyBinding pkBinding = (PrivateKeyBinding) ret
2334: .newPrivateKeyBinding();
2335: PrivateKey key = getPrivateKey(fpcontext, this .myAlias);
2336: pkBinding.setPrivateKey(key);
2337:
2338: } else {
2339: log.log(Level.SEVERE, "WSS0717.no.SAMLCallbackHandler");
2340: throw new XWSSecurityException(
2341: new UnsupportedCallbackException(
2342: null,
2343: "A Required SAML Callback Handler was not specified in configuration : Cannot Populate SAML Assertion"));
2344: }
2345: }
2346: return ret;
2347: }
2348:
2349: private static Date getGMTDateWithSkewAdjusted(Calendar c,
2350: long maxClockSkew, boolean addSkew) {
2351: long offset = c.get(Calendar.ZONE_OFFSET);
2352: if (c.getTimeZone().inDaylightTime(c.getTime())) {
2353: offset += c.getTimeZone().getDSTSavings();
2354: }
2355: long beforeTime = c.getTimeInMillis();
2356: long currentTime = beforeTime - offset;
2357:
2358: if (addSkew)
2359: currentTime = currentTime + maxClockSkew;
2360: else
2361: currentTime = currentTime - maxClockSkew;
2362:
2363: c.setTimeInMillis(currentTime);
2364: return c.getTime();
2365: }
2366:
2367: private static Date getFreshnessAndSkewAdjustedDate(
2368: long maxClockSkew, long timestampFreshnessLimit)
2369: throws ParseException {
2370: Calendar c = new GregorianCalendar();
2371: long offset = c.get(Calendar.ZONE_OFFSET);
2372: if (c.getTimeZone().inDaylightTime(c.getTime())) {
2373: offset += c.getTimeZone().getDSTSavings();
2374: }
2375: long beforeTime = c.getTimeInMillis();
2376: long currentTime = beforeTime - offset;
2377:
2378: // allow for clock_skew and timestamp_freshness
2379: long adjustedTime = currentTime - maxClockSkew
2380: - timestampFreshnessLimit;
2381: c.setTimeInMillis(adjustedTime);
2382:
2383: return c.getTime();
2384: }
2385:
2386: private X509Certificate getDynamicCertificate(Map context /*,KeyStore trustStore*/) {
2387:
2388: X509Certificate cert = null;
2389:
2390: Subject requesterSubject = getRequesterSubject(context);
2391: if (requesterSubject != null) {
2392: Set publicCredentials = requesterSubject
2393: .getPublicCredentials();
2394: for (Iterator it = publicCredentials.iterator(); it
2395: .hasNext();) {
2396: Object cred = it.next();
2397: if (cred instanceof java.security.cert.X509Certificate) {
2398: cert = (java.security.cert.X509Certificate) cred;
2399: }
2400: }
2401: if (cert != null) {
2402: return cert;
2403: }
2404: }
2405: /*
2406: String keyId = (String)context.get(MessageConstants.REQUESTER_KEYID);
2407: String issuerName = (String)context.get(MessageConstants.REQUESTER_ISSUERNAME);
2408: BigInteger issuerSerial = (BigInteger)context.get(MessageConstants.REQUESTER_SERIAL);
2409: //TODO: we are not looking for Thumbprints similarly here
2410: if (keyId != null) {
2411: try {
2412: cert = getMatchingCertificate(keyId.getBytes(), trustStore);
2413: if (cert != null)
2414: return cert;
2415: } catch (XWSSecurityException e) {}
2416: } else if ((issuerName != null) && (issuerSerial != null)) {
2417: try {
2418: cert = getMatchingCertificate(issuerSerial, issuerName, trustStore);
2419: if (cert != null)
2420: return cert;
2421: } catch (XWSSecurityException e) {}
2422: } */
2423:
2424: return null;
2425: }
2426:
2427: public void updateOtherPartySubject(Subject subj,
2428: String encryptedKey) {
2429: //DO Nothing here
2430: }
2431:
2432: public void updateOtherPartySubject(Subject subject, Key secretKey) {
2433: //Do nothing here
2434: }
2435:
2436: public PrivateKey getPrivateKey(Map context, byte[] keyIdentifier,
2437: String valueType) throws XWSSecurityException {
2438: if (MessageConstants.KEY_INDETIFIER_TYPE.equals(valueType)) {
2439: return getPrivateKey(context, keyIdentifier);
2440: }
2441:
2442: if (!MessageConstants.THUMB_PRINT_TYPE.equals(valueType)) {
2443: throw new XWSSecurityException(
2444: "Internal Error : Unsupported Valuetype :"
2445: + valueType + " passed to getPrivateKey()");
2446: }
2447: //Handle Thumbprint type here
2448: try {
2449: Subject subject = getSubject(context);
2450: if (subject != null) {
2451: Set set = subject
2452: .getPrivateCredentials(X500PrivateCredential.class);
2453: if (set != null) {
2454: Iterator it = set.iterator();
2455: while (it.hasNext()) {
2456: X500PrivateCredential cred = (X500PrivateCredential) it
2457: .next();
2458: if (matchesThumbPrint(Base64
2459: .decode(keyIdentifier), cred
2460: .getCertificate()))
2461: return cred.getPrivateKey();
2462: }
2463: }
2464: }
2465:
2466: PrivateKeyCallback.Request request = new PrivateKeyCallback.DigestRequest(
2467: keyIdentifier, "SHA-1");
2468: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
2469: request);
2470: Callback[] callbacks = new Callback[] { pkCallback };
2471: _handler.handle(callbacks);
2472:
2473: return pkCallback.getKey();
2474: } catch (Exception e) {
2475: log
2476: .log(
2477: Level.SEVERE,
2478: "WSS0216.callbackhandler.handle.exception",
2479: new Object[] { "PrivateKeyCallback.SubjectKeyIDRequest" });
2480: throw new XWSSecurityException(e);
2481: }
2482: }
2483:
2484: public void validateSAMLAssertion(Map context,
2485: XMLStreamReader assertion) throws XWSSecurityException {
2486: //Subject subj = (Subject) context.get(MessageConstants.AUTH_SUBJECT);
2487: if (sValidator != null) {
2488: try {
2489: sValidator.validate(assertion);
2490: } catch (SAMLAssertionValidator.SAMLValidationException e) {
2491: log.log(Level.SEVERE,
2492: "WSS0716.failed.validateSAMLAssertion", e);
2493: throw new XWSSecurityException(e);
2494: }
2495: }
2496: }
2497:
2498: public void updateOtherPartySubject(final Subject subject,
2499: final XMLStreamReader assertion) {
2500: AccessController.doPrivileged(new PrivilegedAction() {
2501: public Object run() {
2502: subject.getPublicCredentials().add(assertion);
2503: return null;
2504: }
2505: });
2506:
2507: }
2508:
2509: public boolean isSelfCertificate(X509Certificate cert) {
2510: if (this .selfCertificate != null
2511: && this .selfCertificate.equals(cert)) {
2512: return true;
2513: }
2514:
2515: if (_handler != null) {
2516: String alias = this .myAlias;
2517: if (alias == null) {
2518: if (this .keystoreCertSelectorClass != null) {
2519: AliasSelector selector = null;
2520: try {
2521: selector = (AliasSelector) this .keystoreCertSelectorClass
2522: .newInstance();
2523: } catch (IllegalAccessException ex) {
2524: log
2525: .log(
2526: Level.SEVERE,
2527: "WSS1532.exception.instantiating.aliasselector",
2528: ex);
2529: throw new RuntimeException(ex);
2530: } catch (InstantiationException ex) {
2531: log
2532: .log(
2533: Level.SEVERE,
2534: "WSS1532.exception.instantiating.aliasselector",
2535: ex);
2536: throw new RuntimeException(ex);
2537: }
2538: alias = selector.select(null);
2539: }
2540:
2541: }
2542: if (alias != null) {
2543: try {
2544: PrivateKeyCallback.Request request = new PrivateKeyCallback.AliasRequest(
2545: alias);
2546: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
2547: request);
2548:
2549: Callback[] callbacks = new Callback[] { pkCallback };
2550: _handler.handle(callbacks);
2551: Certificate[] chain = pkCallback.getChain();
2552: X509Certificate selfCert = null;
2553: if (chain != null) {
2554: selfCert = (X509Certificate) chain[0];
2555: }
2556: if (selfCert != null && selfCert.equals(cert)) {
2557: return true;
2558: }
2559: } catch (Exception ex) {
2560: //ignore for now since we can always return false form this method
2561: }
2562: }
2563: }
2564: return false;
2565: }
2566:
2567: private Class loadClass(String classname)
2568: throws XWSSecurityException {
2569: if (classname == null) {
2570: return null;
2571: }
2572: Class ret = null;
2573: ClassLoader loader = Thread.currentThread()
2574: .getContextClassLoader();
2575: if (loader != null) {
2576: try {
2577: ret = loader.loadClass(classname);
2578: return ret;
2579: } catch (ClassNotFoundException e) {
2580: // ignore
2581: }
2582: }
2583: // if context classloader didnt work, try this
2584: loader = this .getClass().getClassLoader();
2585: try {
2586: ret = loader.loadClass(classname);
2587: return ret;
2588: } catch (ClassNotFoundException e) {
2589: // ignore
2590: }
2591: log.log(Level.SEVERE, "WSS0714.error.getting.userClass",
2592: new Object[] { classname });
2593: throw new XWSSecurityException("Could not find User Class "
2594: + classname);
2595: }
2596:
2597: private long toLong(String lng) throws XWSSecurityException {
2598: if (lng == null) {
2599: return 0;
2600: }
2601: Long ret = 0L;
2602: try {
2603: ret = Long.valueOf(lng);
2604: } catch (Exception e) {
2605: log.log(Level.SEVERE, "WSS0719.error.getting.longValue");
2606: throw new XWSSecurityException(e);
2607: }
2608: return ret;
2609: }
2610:
2611: public void updateOtherPartySubject(Subject subject,
2612: Subject bootStrapSubject) {
2613: SecurityUtil.copySubject(subject, bootStrapSubject);
2614: }
2615:
2616: }
|