0001: /*
0002: * $Id: WssProviderSecurityEnvironment.java,v 1.13 2007/09/13 12:42:21 kumarjayanti Exp $
0003: */
0004:
0005: /*
0006: * The contents of this file are subject to the terms
0007: * of the Common Development and Distribution License
0008: * (the License). You may not use this file except in
0009: * compliance with the License.
0010: *
0011: * You can obtain a copy of the license at
0012: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
0013: * See the License for the specific language governing
0014: * permissions and limitations under the License.
0015: *
0016: * When distributing Covered Code, include this CDDL
0017: * Header Notice in each file and include the License file
0018: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
0019: * If applicable, add the following below the CDDL Header,
0020: * with the fields enclosed by brackets [] replaced by
0021: * you own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
0025: */
0026:
0027: package com.sun.xml.wss.impl;
0028:
0029: import java.math.BigInteger;
0030: import java.security.AccessController;
0031:
0032: import java.security.Key;
0033: import java.security.KeyStore;
0034: import java.security.PublicKey;
0035: import java.security.Principal;
0036: import java.security.PrivateKey;
0037: import java.security.KeyStoreException;
0038:
0039: import java.security.cert.Certificate;
0040: import java.security.cert.X509Certificate;
0041: import java.security.cert.CertPathBuilder;
0042: import java.security.cert.X509CertSelector;
0043: import java.security.cert.PKIXBuilderParameters;
0044: import java.security.cert.PKIXCertPathBuilderResult;
0045: import java.security.cert.CertificateExpiredException;
0046: import java.security.cert.CertificateNotYetValidException;
0047:
0048: import java.text.ParseException;
0049: import java.text.SimpleDateFormat;
0050:
0051: import java.util.Map;
0052: import java.util.Set;
0053: import java.util.Date;
0054: import java.util.Timer;
0055: import java.util.Arrays;
0056: import java.util.Calendar;
0057: import java.util.Iterator;
0058: import java.util.Enumeration;
0059: import java.util.StringTokenizer;
0060: import java.util.GregorianCalendar;
0061:
0062: import javax.security.auth.Subject;
0063: import javax.security.auth.callback.Callback;
0064: import javax.security.auth.callback.CallbackHandler;
0065: import javax.security.auth.x500.X500Principal;
0066: import javax.security.auth.x500.X500PrivateCredential;
0067: import javax.security.auth.callback.NameCallback;
0068: import javax.security.auth.callback.PasswordCallback;
0069:
0070: import javax.crypto.SecretKey;
0071:
0072: import com.sun.enterprise.security.jauth.callback.CertStoreCallback;
0073: import com.sun.enterprise.security.jauth.callback.PasswordValidationCallback;
0074: import com.sun.enterprise.security.jauth.callback.PrivateKeyCallback;
0075: import com.sun.enterprise.security.jauth.callback.SecretKeyCallback;
0076: import com.sun.enterprise.security.jauth.callback.TrustStoreCallback;
0077:
0078: import com.sun.org.apache.xml.internal.security.utils.Base64;
0079: import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
0080: import com.sun.xml.wss.SecurityEnvironment;
0081: import com.sun.xml.wss.XWSSecurityException;
0082: import com.sun.xml.wss.core.Timestamp;
0083: import com.sun.xml.wss.impl.misc.NonceCache;
0084: import com.sun.xml.wss.impl.misc.DefaultSecurityEnvironmentImpl;
0085:
0086: import com.sun.xml.wss.core.reference.X509SubjectKeyIdentifier;
0087:
0088: import com.sun.xml.wss.saml.Assertion; //import com.sun.xml.wss.saml.assertion.AuthorityBinding;
0089:
0090: import com.sun.xml.wss.impl.policy.mls.AuthenticationTokenPolicy;
0091: import com.sun.xml.wss.impl.configuration.DynamicApplicationContext;
0092: import javax.xml.stream.XMLStreamReader;
0093:
0094: import org.w3c.dom.Element;
0095: import org.w3c.dom.Document;
0096:
0097: import java.security.MessageDigest;
0098: import java.security.NoSuchAlgorithmException;
0099: import java.security.PrivilegedAction;
0100: import java.security.cert.CertificateEncodingException;
0101:
0102: //import javax.security.auth.message.callback.PasswordValidationCallback;
0103:
0104: public class WssProviderSecurityEnvironment implements
0105: SecurityEnvironment {
0106: /* menu of module options - includes algorithm Ids, keystore aliases etc., */
0107: private Map _securityOptions;
0108:
0109: /* Callbacks */
0110: private CallbackHandler _handler;
0111:
0112: /* Map of aliases-key passwords obtained via Module Options */
0113: //Map aliases_keypwds = null;
0114: // value of the maximum skew between the local times of two
0115: // systems (in milliseconds).
0116: // Keeping it 1 minute.
0117: protected final long MAX_CLOCK_SKEW = 360000;
0118:
0119: // milliseconds (set to 5 mins), time for which a timestamp is considered fresh
0120: protected final long TIMESTAMP_FRESHNESS_LIMIT = 5 * 60 * 1000;
0121:
0122: private static final SimpleDateFormat calendarFormatter1 = new SimpleDateFormat(
0123: "yyyy-MM-dd'T'HH:mm:ss'Z'");
0124: private static final SimpleDateFormat calendarFormatter2 = new SimpleDateFormat(
0125: "yyyy-MM-dd'T'HH:mm:ss'.'SSS'Z'");
0126:
0127: // Nonce Cache
0128: NonceCache nonceCache = null;
0129:
0130: // Nonce clean-up timer
0131: static final boolean USE_DAEMON_THREAD = true;
0132: static final Timer nonceCleanupTimer = new Timer(USE_DAEMON_THREAD);
0133:
0134: public WssProviderSecurityEnvironment(CallbackHandler handler,
0135: Map options) throws XWSSecurityException {
0136: _handler = handler;
0137: _securityOptions = options;
0138:
0139: if (_securityOptions != null) {
0140: String mo_aliases = (String) _securityOptions
0141: .get("ALIASES");
0142: String mo_keypwds = (String) _securityOptions
0143: .get("PASSWORDS");
0144:
0145: if (mo_aliases != null && mo_keypwds != null) {
0146: StringTokenizer aliases = new StringTokenizer(
0147: mo_aliases, " ");
0148: StringTokenizer keypwds = new StringTokenizer(
0149: mo_keypwds, " ");
0150: if (aliases.countTokens() != keypwds.countTokens())
0151: ;// log.INFO
0152:
0153: // while (aliases.hasMoreElements()) {
0154: // aliases_keypwds.put(aliases.nextToken(), keypwds.nextToken());
0155: // }
0156: }
0157: }
0158: }
0159:
0160: /*
0161: * @throws XWSSecurityException
0162: */
0163: public PrivateKey getPrivateKey(Map context, String alias)
0164: throws XWSSecurityException {
0165:
0166: PrivateKey privateKey = null;
0167: try {
0168: PrivateKeyCallback.Request request = new PrivateKeyCallback.AliasRequest(
0169: alias);
0170: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
0171: request);
0172: Callback[] callbacks = new Callback[] { pkCallback };
0173: _handler.handle(callbacks);
0174: privateKey = (PrivateKey) pkCallback.getKey();
0175: } catch (Exception e) {
0176: throw new XWSSecurityException(e);
0177: }
0178:
0179: if (privateKey == null) {
0180: throw new XWSSecurityException(
0181: "Unable to locate private key for the alias "
0182: + alias);
0183: }
0184:
0185: return privateKey;
0186: }
0187:
0188: /*
0189: * Retrieves the PrivateKey corresponding to the cert
0190: * with the given KeyIdentifier value
0191: *
0192: * @param keyIdentifier an Opaque identifier indicating
0193: * the X509 certificate
0194: *
0195: * @return the PrivateKey corresponding to the cert
0196: * with the given KeyIdentifier value
0197: *
0198: * @throws XWSSecurityException
0199: */
0200: public PrivateKey getPrivateKey(Map context, byte[] keyIdentifier)
0201: throws XWSSecurityException {
0202: /*
0203: use PrivateKeyCallback
0204: */
0205: try {
0206: Subject subject = getSubject(context);
0207: if (subject != null) {
0208: Set set = subject
0209: .getPrivateCredentials(X500PrivateCredential.class);
0210: if (set != null) {
0211: Iterator it = set.iterator();
0212: while (it.hasNext()) {
0213: X500PrivateCredential cred = (X500PrivateCredential) it
0214: .next();
0215: if (matchesKeyIdentifier(Base64
0216: .decode(keyIdentifier), cred
0217: .getCertificate()))
0218: return cred.getPrivateKey();
0219: }
0220: }
0221: }
0222:
0223: PrivateKeyCallback.Request request = new PrivateKeyCallback.SubjectKeyIDRequest(
0224: keyIdentifier);
0225: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
0226: request);
0227: Callback[] callbacks = new Callback[] { pkCallback };
0228: _handler.handle(callbacks);
0229:
0230: return pkCallback.getKey();
0231: } catch (Exception e) {
0232: throw new XWSSecurityException(e);
0233: }
0234: }
0235:
0236: /*
0237: * Retrieves the PrivateKey corresponding to the given cert
0238: *
0239: * @param cert an X509 certificate
0240: *
0241: * @return the PrivateKey corresponding to the cert
0242: *
0243: * @throws XWSSecurityException
0244: */
0245: public PrivateKey getPrivateKey(Map context, X509Certificate cert)
0246: throws XWSSecurityException {
0247: /*
0248: use PrivateKeyCallback
0249: */
0250: try {
0251: Subject subject = getSubject(context);
0252: if (subject != null) {
0253: Set set = subject
0254: .getPrivateCredentials(X500PrivateCredential.class);
0255: if (set != null) {
0256: String issuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0257: .normalize(cert.getIssuerDN().getName());
0258: Iterator it = set.iterator();
0259: while (it.hasNext()) {
0260: X500PrivateCredential cred = (X500PrivateCredential) it
0261: .next();
0262: X509Certificate x509Cert = cred
0263: .getCertificate();
0264: BigInteger serialNo = x509Cert
0265: .getSerialNumber();
0266: String currentIssuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0267: .normalize(x509Cert.getIssuerDN()
0268: .getName());
0269: if (serialNo.equals(cert.getSerialNumber())
0270: && currentIssuerName.equals(issuerName)) {
0271: return cred.getPrivateKey();
0272: }
0273: }
0274: }
0275: }
0276:
0277: PrivateKeyCallback.Request request = new PrivateKeyCallback.IssuerSerialNumRequest(
0278: cert.getIssuerX500Principal(), cert
0279: .getSerialNumber());
0280: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
0281: request);
0282: Callback[] callbacks = new Callback[] { pkCallback };
0283: _handler.handle(callbacks);
0284:
0285: return pkCallback.getKey();
0286: } catch (Exception e) {
0287: throw new XWSSecurityException(e);
0288: }
0289: }
0290:
0291: /*
0292: * Retrieves the matching PrivateKey corresponding to cert whose
0293: * SerialNumber and IssuerName are given
0294: *
0295: * @param serialNumber X509Certificate SerialNumber
0296: * @param issuerName X509Certificate IssuerName
0297: *
0298: * @return PrivateKey
0299: *
0300: * @throws XWSSecurityException
0301: */
0302: public PrivateKey getPrivateKey(Map context,
0303: BigInteger serialNumber, String issuerName)
0304: throws XWSSecurityException {
0305: /*
0306: use PrivateKeyCallback
0307: */
0308: try {
0309: Subject subject = getSubject(context);
0310: if (subject != null) {
0311: Set set = subject
0312: .getPrivateCredentials(X500PrivateCredential.class);
0313: if (set != null) {
0314: Iterator it = set.iterator();
0315: while (it.hasNext()) {
0316: X500PrivateCredential cred = (X500PrivateCredential) it
0317: .next();
0318: X509Certificate x509Cert = cred
0319: .getCertificate();
0320: BigInteger serialNo = x509Cert
0321: .getSerialNumber();
0322: String currentIssuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0323: .normalize(x509Cert.getIssuerDN()
0324: .getName());
0325: if (serialNo.equals(serialNumber)
0326: && currentIssuerName.equals(issuerName)) {
0327: return cred.getPrivateKey();
0328: }
0329: }
0330: }
0331: }
0332:
0333: PrivateKeyCallback.Request request = new PrivateKeyCallback.IssuerSerialNumRequest(
0334: new X500Principal(issuerName), serialNumber);
0335: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
0336: request);
0337: Callback[] callbacks = new Callback[] { pkCallback };
0338: _handler.handle(callbacks);
0339:
0340: return pkCallback.getKey();
0341: } catch (Exception e) {
0342: throw new XWSSecurityException(e);
0343: }
0344: }
0345:
0346: /**
0347: * Retrieves a reasonable default value for the current user's
0348: * X509Certificate if one exists.
0349: *
0350: * @return the default certificate for the current user
0351: *
0352: * @param keyIdentifier an Opaque identifier indicating
0353: * the X509 certificate.
0354: * @throws XWSSecurityException
0355: */
0356: public X509Certificate getDefaultCertificate(Map context)
0357: throws XWSSecurityException {
0358: /*
0359: use PrivateKeyCallback to get the
0360: certChain - return the first certificate
0361: */
0362: Subject subject = getSubject(context);
0363: if (subject != null) {
0364: Set set = subject
0365: .getPublicCredentials(X509Certificate.class);
0366: if (set != null && set.size() == 1)
0367: return ((X509Certificate) (set.toArray())[0]);
0368: }
0369:
0370: PrivateKeyCallback pkCallback = new PrivateKeyCallback(null);
0371: Callback[] _callbacks = new Callback[] { pkCallback };
0372: try {
0373: _handler.handle(_callbacks);
0374: } catch (Exception e) {
0375: throw new XWSSecurityException(e);
0376: }
0377:
0378: Certificate[] chain = pkCallback.getChain();
0379: if (chain == null) {
0380: throw new XWSSecurityException(
0381: "Empty certificate chain returned by PrivateKeyCallback");
0382: }
0383: return (X509Certificate) chain[0];
0384: }
0385:
0386: /**
0387: * Authenticate the user against a list of known username-password
0388: * pairs.
0389: *
0390: * @param username
0391: * @param password
0392: * @return true if the username-password pair is valid
0393: */
0394: public boolean authenticateUser(Map context, String username,
0395: String password) throws XWSSecurityException {
0396: /*
0397: use PasswordValidationCallback
0398: */
0399: char[] pwd = (password == null) ? null : password.toCharArray();
0400: PasswordValidationCallback pvCallback = new PasswordValidationCallback(
0401: username, pwd);
0402: //PasswordValidationCallback pvCallback = new PasswordValidationCallback(
0403: // this.getRequesterSubject(context),username, pwd);
0404: Callback[] callbacks = new Callback[] { pvCallback };
0405: try {
0406: _handler.handle(callbacks);
0407: } catch (Exception e) {
0408: throw new XWSSecurityException(e);
0409: }
0410:
0411: // zero the password
0412: if (pwd != null)
0413: pvCallback.clearPassword();
0414:
0415: return pvCallback.getResult();
0416: }
0417:
0418: /**
0419: * Authenticate the user given the password digest.
0420: *
0421: * @param username
0422: * @param passwordDigest
0423: * @param nonce
0424: * @param created
0425: * @return true if the password digest is valid
0426: */
0427: public boolean authenticateUser(Map context, String username,
0428: String passwordDigest, String nonce, String created)
0429: throws XWSSecurityException {
0430: /*
0431: can not implement
0432: */
0433: return false;
0434: }
0435:
0436: /**
0437: * Validate an X509Certificate.
0438: * @return true, if the cert is a valid one, false o/w.
0439: * @throws XWSSecurityException
0440: * if there is some problem during validation.
0441: */
0442: public boolean validateCertificate(X509Certificate cert)
0443: throws XWSSecurityException {
0444: /*
0445: use TrustStore and CertStore
0446: */
0447: try {
0448: cert.checkValidity();
0449: } catch (CertificateExpiredException e) {
0450: throw new XWSSecurityException("X509Certificate Expired", e);
0451: } catch (CertificateNotYetValidException e) {
0452: throw new XWSSecurityException(
0453: "X509Certificate not yet valid", e);
0454: }
0455:
0456: X509CertSelector certSelector = new X509CertSelector();
0457: certSelector.setCertificate(cert);
0458:
0459: PKIXBuilderParameters parameters;
0460: CertPathBuilder builder;
0461: try {
0462: Callback[] callbacks = null;
0463: CertStoreCallback csCallback = null;
0464: TrustStoreCallback tsCallback = null;
0465:
0466: if (tsCallback == null && csCallback == null) {
0467: csCallback = new CertStoreCallback();
0468: tsCallback = new TrustStoreCallback();
0469: callbacks = new Callback[] { csCallback, tsCallback };
0470: } else if (csCallback == null) {
0471: csCallback = new CertStoreCallback();
0472: callbacks = new Callback[] { csCallback };
0473: } else if (tsCallback == null) {
0474: tsCallback = new TrustStoreCallback();
0475: callbacks = new Callback[] { tsCallback };
0476: }
0477:
0478: try {
0479: _handler.handle(callbacks);
0480: } catch (Exception e) {
0481: throw new XWSSecurityException(e);
0482: }
0483:
0484: parameters = new PKIXBuilderParameters(tsCallback
0485: .getTrustStore(), certSelector);
0486: parameters.setRevocationEnabled(false);
0487: parameters.addCertStore(csCallback.getCertStore());
0488: builder = CertPathBuilder.getInstance("PKIX");
0489: } catch (Exception e) {
0490: // Log Message
0491: throw new XWSSecurityException(e);
0492: }
0493:
0494: try {
0495: PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) builder
0496: .build(parameters);
0497: } catch (Exception e) {
0498: // log message
0499: return false;
0500: }
0501:
0502: return true;
0503: }
0504:
0505: /**
0506: * @param keyIdMatch
0507: * KeyIdentifier to search for
0508: * @return the matching Certificate
0509: */
0510: public X509Certificate getMatchingCertificate(Map context,
0511: byte[] keyIdMatch) throws XWSSecurityException {
0512:
0513: Subject subject = getSubject(context);
0514: if (subject != null) {
0515: Set set = subject
0516: .getPrivateCredentials(X500PrivateCredential.class);
0517: if (set != null) {
0518: Iterator it = set.iterator();
0519: while (it.hasNext()) {
0520: X500PrivateCredential cred = (X500PrivateCredential) it
0521: .next();
0522: X509Certificate cert = cred.getCertificate();
0523: if (matchesKeyIdentifier(keyIdMatch, cert))
0524: return cert;
0525: }
0526: }
0527: }
0528:
0529: PrivateKeyCallback.Request request = new PrivateKeyCallback.SubjectKeyIDRequest(
0530: keyIdMatch);
0531: PrivateKeyCallback pkCallback = new PrivateKeyCallback(request);
0532: TrustStoreCallback tsCallback = new TrustStoreCallback();
0533:
0534: Callback[] callbacks = new Callback[] { pkCallback, tsCallback };
0535:
0536: try {
0537: _handler.handle(callbacks);
0538: } catch (Exception e) {
0539: throw new XWSSecurityException(e);
0540: }
0541:
0542: Certificate[] chain = pkCallback.getChain();
0543: if (chain != null) {
0544: for (int i = 0; i < chain.length; i++) {
0545: X509Certificate x509Cert = (X509Certificate) chain[i];
0546: if (matchesKeyIdentifier(keyIdMatch, x509Cert))
0547: return x509Cert;
0548: }
0549: }
0550:
0551: // if not found, look in Truststore
0552: //TODO: i should probably look inside the CertStore and not in TrustStore
0553: KeyStore trustStore = tsCallback.getTrustStore();
0554: if (trustStore != null) {
0555: X509Certificate otherPartyCert = getMatchingCertificate(
0556: keyIdMatch, trustStore);
0557: if (otherPartyCert != null)
0558: return otherPartyCert;
0559: }
0560:
0561: // if still not found, throw Exception
0562: throw new XWSSecurityException("No Matching Certificate for :"
0563: + Arrays.toString(keyIdMatch)
0564: + " found in KeyStore or TrustStore");
0565: }
0566:
0567: public X509Certificate getMatchingCertificate(Map context,
0568: BigInteger serialNumber, String issuerName)
0569: throws XWSSecurityException {
0570:
0571: Subject subject = getSubject(context);
0572: if (subject != null) {
0573: Set set = subject
0574: .getPrivateCredentials(X500PrivateCredential.class);
0575: if (set != null) {
0576: Iterator it = set.iterator();
0577: while (it.hasNext()) {
0578: X500PrivateCredential cred = (X500PrivateCredential) it
0579: .next();
0580: X509Certificate x509Cert = cred.getCertificate();
0581: BigInteger serialNo = x509Cert.getSerialNumber();
0582: String currentIssuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0583: .normalize(x509Cert.getIssuerDN().getName());
0584: if (serialNo.equals(serialNumber)
0585: && currentIssuerName.equals(issuerName)) {
0586: return x509Cert;
0587: }
0588: }
0589: }
0590: }
0591:
0592: PrivateKeyCallback.Request request = new PrivateKeyCallback.IssuerSerialNumRequest(
0593: new X500Principal(issuerName), serialNumber);
0594: PrivateKeyCallback pkCallback = new PrivateKeyCallback(request);
0595: TrustStoreCallback tsCallback = new TrustStoreCallback();
0596:
0597: Callback[] callbacks = new Callback[] { pkCallback, tsCallback };
0598:
0599: try {
0600: _handler.handle(callbacks);
0601: } catch (Exception e) {
0602: throw new XWSSecurityException(e);
0603: }
0604:
0605: Certificate[] chain = pkCallback.getChain();
0606: if (chain != null) {
0607: for (int i = 0; i < chain.length; i++) {
0608: X509Certificate x509Cert = (X509Certificate) chain[i];
0609: if (matchesIssuerSerialAndName(serialNumber,
0610: issuerName, x509Cert))
0611: return x509Cert;
0612: }
0613: } else {
0614: // log
0615: }
0616:
0617: // if not found, look in Truststore
0618: //TODO: I should probably look inside CertStore instead of TrustStore
0619: KeyStore trustStore = tsCallback.getTrustStore();
0620: if (trustStore != null) {
0621: X509Certificate otherPartyCert = getMatchingCertificate(
0622: serialNumber, issuerName, trustStore);
0623: if (otherPartyCert != null)
0624: return otherPartyCert;
0625: } else {
0626: // log
0627: }
0628:
0629: // if still not found, throw Exception
0630: throw new XWSSecurityException("No Matching Certificate for :"
0631: + " found in KeyStore or TrustStore");
0632: }
0633:
0634: /**
0635: * @param keyIdMatch
0636: * KeyIdentifier to search for
0637: * @return the matching Certificate
0638: */
0639: public X509Certificate getMatchingCertificate(Map context,
0640: byte[] keyIdMatch, String valueType)
0641: throws XWSSecurityException {
0642:
0643: if (MessageConstants.KEY_INDETIFIER_TYPE.equals(valueType)) {
0644: return getMatchingCertificate(context, keyIdMatch);
0645: }
0646: // handle thumbprint here
0647: Subject subject = getSubject(context);
0648: if (subject != null) {
0649: Set set = subject
0650: .getPrivateCredentials(X500PrivateCredential.class);
0651: if (set != null) {
0652: Iterator it = set.iterator();
0653: while (it.hasNext()) {
0654: X500PrivateCredential cred = (X500PrivateCredential) it
0655: .next();
0656: X509Certificate cert = cred.getCertificate();
0657: if (matchesThumbPrint(keyIdMatch, cert))
0658: return cert;
0659: }
0660: }
0661: }
0662:
0663: // TODO: change this once we get support for this.
0664: //PrivateKeyCallback.Request request = new PrivateKeyCallback.ThumbPrintRequest(keyIdMatch);
0665: PrivateKeyCallback.Request request = new PrivateKeyCallback.SubjectKeyIDRequest(
0666: keyIdMatch);
0667: PrivateKeyCallback pkCallback = new PrivateKeyCallback(request);
0668: TrustStoreCallback tsCallback = new TrustStoreCallback();
0669:
0670: Callback[] callbacks = new Callback[] { pkCallback, tsCallback };
0671:
0672: try {
0673: _handler.handle(callbacks);
0674: } catch (Exception e) {
0675: throw new XWSSecurityException(e);
0676: }
0677:
0678: Certificate[] chain = pkCallback.getChain();
0679: if (chain != null) {
0680: for (int i = 0; i < chain.length; i++) {
0681: X509Certificate x509Cert = (X509Certificate) chain[i];
0682: if (matchesThumbPrint(keyIdMatch, x509Cert))
0683: return x509Cert;
0684: }
0685: }
0686:
0687: // if not found, look in Truststore
0688: //TODO: i guess i need to look inside the CertStore and not TrustStore
0689: KeyStore trustStore = tsCallback.getTrustStore();
0690: if (trustStore != null) {
0691: X509Certificate otherPartyCert = getMatchingCertificate(
0692: keyIdMatch, trustStore, valueType);
0693: if (otherPartyCert != null)
0694: return otherPartyCert;
0695: }
0696:
0697: // if still not found, throw Exception
0698: throw new XWSSecurityException("No Matching Certificate for :"
0699: + Arrays.toString(keyIdMatch)
0700: + " found in KeyStore or TrustStore");
0701: }
0702:
0703: public SecretKey getSecretKey(Map context, String alias,
0704: boolean encryptMode) throws XWSSecurityException {
0705: /*
0706: Use SecretKeyCallback
0707: */
0708: SecretKeyCallback.Request request = new SecretKeyCallback.AliasRequest(
0709: alias);
0710: SecretKeyCallback skCallback = new SecretKeyCallback(request);
0711: Callback[] callbacks = new Callback[] { skCallback };
0712: try {
0713: _handler.handle(callbacks);
0714: } catch (Exception e) {
0715: throw new XWSSecurityException(e);
0716: }
0717:
0718: return (SecretKey) skCallback.getKey();
0719: }
0720:
0721: public X509Certificate getCertificate(Map context, String alias,
0722: boolean forSigning) throws XWSSecurityException {
0723: X509Certificate cert = null;
0724: try {
0725: PrivateKeyCallback pkCallback = null;
0726: if (forSigning) {
0727: try {
0728: Subject subject = getSubject(context);
0729: if (subject != null) {
0730: Set set = subject
0731: .getPrivateCredentials(X500PrivateCredential.class);
0732: if (set != null) {
0733: Iterator it = set.iterator();
0734: while (it.hasNext()) {
0735: X500PrivateCredential cred = (X500PrivateCredential) it
0736: .next();
0737: if (cred.getAlias().equals(alias))
0738: return cred.getCertificate();
0739: }
0740: }
0741: }
0742:
0743: PrivateKeyCallback.Request request = new PrivateKeyCallback.AliasRequest(
0744: alias);
0745: pkCallback = new PrivateKeyCallback(request);
0746: Callback[] callbacks = new Callback[] { pkCallback };
0747: _handler.handle(callbacks);
0748: } catch (Exception e) {
0749: throw new XWSSecurityException(e);
0750: }
0751:
0752: Certificate[] chain = pkCallback.getChain();
0753: if (chain != null)
0754: cert = (X509Certificate) chain[0];
0755: else
0756: ;//log
0757: } else {
0758: TrustStoreCallback tsCallback = new TrustStoreCallback();
0759: Callback[] _callbacks = new Callback[] { tsCallback };
0760: _handler.handle(_callbacks);
0761:
0762: // look for dynamic certificate first
0763: cert = getDynamicCertificate(context, tsCallback
0764: .getTrustStore());
0765: //System.out.println("got dynamic cert " + cert);
0766: // look for alias
0767: if (cert == null) {
0768: if (tsCallback.getTrustStore() != null) {
0769: cert = (X509Certificate) tsCallback
0770: .getTrustStore().getCertificate(alias);
0771: }
0772: }
0773: }
0774: } catch (Exception e) {
0775: throw new XWSSecurityException(e);
0776: }
0777:
0778: if (cert == null) {
0779: throw new XWSSecurityException(
0780: "Unable to locate certificate for the alias '"
0781: + alias + "'");
0782: }
0783:
0784: return cert;
0785: }
0786:
0787: private boolean matchesKeyIdentifier(byte[] keyIdMatch,
0788: X509Certificate x509Cert) throws XWSSecurityException {
0789:
0790: byte[] keyId = X509SubjectKeyIdentifier
0791: .getSubjectKeyIdentifier(x509Cert);
0792: if (keyId == null) {
0793: // Cert does not contain a key identifier
0794: return false;
0795: }
0796:
0797: if (Arrays.equals(keyIdMatch, keyId)) {
0798: return true;
0799: }
0800: return false;
0801: }
0802:
0803: public static byte[] getThumbprintIdentifier(X509Certificate cert)
0804: throws XWSSecurityException {
0805: byte[] thumbPrintIdentifier = null;
0806:
0807: try {
0808: thumbPrintIdentifier = MessageDigest.getInstance("SHA-1")
0809: .digest(cert.getEncoded());
0810: } catch (NoSuchAlgorithmException ex) {
0811: throw new XWSSecurityException(
0812: "Digest algorithm SHA-1 not found");
0813: } catch (CertificateEncodingException ex) {
0814: throw new XWSSecurityException(
0815: "Error while getting certificate's raw content");
0816: }
0817: return thumbPrintIdentifier;
0818: }
0819:
0820: private boolean matchesThumbPrint(byte[] keyIdMatch,
0821: X509Certificate x509Cert) throws XWSSecurityException {
0822:
0823: byte[] keyId = getThumbprintIdentifier(x509Cert);
0824: if (keyId == null) {
0825: // Cert does not contain a key identifier
0826: return false;
0827: }
0828:
0829: if (Arrays.equals(keyIdMatch, keyId)) {
0830: return true;
0831: }
0832: return false;
0833: }
0834:
0835: private X509Certificate getMatchingCertificate(byte[] keyIdMatch,
0836: KeyStore kStore) throws XWSSecurityException {
0837:
0838: if (kStore == null) {
0839: return null;
0840: }
0841:
0842: try {
0843: Enumeration enum1 = kStore.aliases();
0844: while (enum1.hasMoreElements()) {
0845: String alias = (String) enum1.nextElement();
0846:
0847: Certificate cert = kStore.getCertificate(alias);
0848: if (cert == null || !"X.509".equals(cert.getType())) {
0849: continue;
0850: }
0851:
0852: X509Certificate x509Cert = (X509Certificate) cert;
0853: byte[] keyId = X509SubjectKeyIdentifier
0854: .getSubjectKeyIdentifier(x509Cert);
0855: if (keyId == null) {
0856: // Cert does not contain a key identifier
0857: continue;
0858: }
0859:
0860: if (Arrays.equals(keyIdMatch, keyId)) {
0861: return x509Cert;
0862: }
0863: }
0864: } catch (KeyStoreException kEx) {
0865: throw new XWSSecurityException(kEx);
0866: }
0867: return null;
0868: }
0869:
0870: private X509Certificate getMatchingCertificate(byte[] keyIdMatch,
0871: KeyStore kStore, String valueType)
0872: throws XWSSecurityException {
0873:
0874: if (MessageConstants.KEY_INDETIFIER_TYPE.equals(valueType)) {
0875: return getMatchingCertificate(keyIdMatch, kStore);
0876: }
0877:
0878: // now handle thumbprint here
0879: if (kStore == null) {
0880: return null;
0881: }
0882:
0883: try {
0884: Enumeration enum1 = kStore.aliases();
0885: while (enum1.hasMoreElements()) {
0886: String alias = (String) enum1.nextElement();
0887:
0888: Certificate cert = kStore.getCertificate(alias);
0889: if (cert == null || !"X.509".equals(cert.getType())) {
0890: continue;
0891: }
0892:
0893: X509Certificate x509Cert = (X509Certificate) cert;
0894: byte[] keyId = getThumbprintIdentifier(x509Cert);
0895:
0896: if (Arrays.equals(keyIdMatch, keyId)) {
0897: return x509Cert;
0898: }
0899: }
0900: } catch (KeyStoreException kEx) {
0901: throw new XWSSecurityException(kEx);
0902: }
0903: return null;
0904: }
0905:
0906: private boolean matchesIssuerSerialAndName(
0907: BigInteger serialNumberMatch, String issuerNameMatch,
0908: X509Certificate x509Cert) {
0909:
0910: BigInteger serialNumber = x509Cert.getSerialNumber();
0911: String issuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0912: .normalize(x509Cert.getIssuerDN().getName());
0913:
0914: if (serialNumber.equals(serialNumberMatch)
0915: && issuerName.equals(issuerNameMatch)) {
0916: return true;
0917: }
0918: return false;
0919: }
0920:
0921: private X509Certificate getMatchingCertificate(
0922: BigInteger serialNumber, String issuerName, KeyStore kStore)
0923: throws XWSSecurityException {
0924:
0925: if (kStore == null) {
0926: return null;
0927: }
0928: try {
0929: Enumeration enum1 = kStore.aliases();
0930: while (enum1.hasMoreElements()) {
0931: String alias = (String) enum1.nextElement();
0932:
0933: Certificate cert = kStore.getCertificate(alias);
0934: if (cert == null || !"X.509".equals(cert.getType())) {
0935: continue;
0936: }
0937:
0938: X509Certificate x509Cert = (X509Certificate) cert;
0939: BigInteger serialNo = x509Cert.getSerialNumber();
0940: String currentIssuerName = com.sun.org.apache.xml.internal.security.utils.RFC2253Parser
0941: .normalize(x509Cert.getIssuerDN().getName());
0942:
0943: if (serialNo.equals(serialNumber)
0944: && currentIssuerName.equals(issuerName)) {
0945: return x509Cert;
0946: }
0947: }
0948: } catch (KeyStoreException kEx) {
0949: throw new XWSSecurityException(kEx);
0950: }
0951: return null;
0952: }
0953:
0954: public void updateOtherPartySubject(final Subject subject,
0955: final String username, final String password) {
0956: AccessController.doPrivileged(new PrivilegedAction() {
0957: public Object run() {
0958: String x500Name = "CN=" + username;
0959: Principal principal = new X500Principal(x500Name);
0960: subject.getPrincipals().add(principal);
0961: subject.getPrivateCredentials().add(password);
0962: return null;
0963: }
0964: });
0965:
0966: }
0967:
0968: public void updateOtherPartySubject(final Subject subject,
0969: final X509Certificate cert) {
0970: AccessController.doPrivileged(new PrivilegedAction() {
0971: public Object run() {
0972: Principal principal = cert.getSubjectX500Principal();
0973: subject.getPrincipals().add(principal);
0974: subject.getPublicCredentials().add(cert);
0975: return null;
0976: }
0977: });
0978: }
0979:
0980: public void updateOtherPartySubject(final Subject subject,
0981: final Assertion assertion) {
0982:
0983: //subject.getPublicCredentials().add(assertion);
0984: }
0985:
0986: public PublicKey getPublicKey(Map context, BigInteger serialNumber,
0987: String issuerName) throws XWSSecurityException {
0988: return getMatchingCertificate(context, serialNumber, issuerName)
0989: .getPublicKey();
0990: }
0991:
0992: public PublicKey getPublicKey(String keyIdentifier)
0993: throws XWSSecurityException {
0994: try {
0995: return getMatchingCertificate(null,
0996: getDecodedBase64EncodedData(keyIdentifier))
0997: .getPublicKey();
0998: } catch (Exception e) {
0999: throw new XWSSecurityException(e);
1000: }
1001: }
1002:
1003: public PublicKey getPublicKey(Map context, byte[] keyIdentifier)
1004: throws XWSSecurityException {
1005: try {
1006: return getMatchingCertificate(context, keyIdentifier)
1007: .getPublicKey();
1008: } catch (Exception e) {
1009: throw new XWSSecurityException(e);
1010: }
1011: }
1012:
1013: public PublicKey getPublicKey(Map context, byte[] identifier,
1014: String valueType) throws XWSSecurityException {
1015: return getMatchingCertificate(context, identifier, valueType)
1016: .getPublicKey();
1017: }
1018:
1019: private byte[] getDecodedBase64EncodedData(String encodedData)
1020: throws XWSSecurityException {
1021: try {
1022: return Base64.decode(encodedData);
1023: } catch (Base64DecodingException e) {
1024: throw new SecurityHeaderException(
1025: "Unable to decode Base64 encoded data", e);
1026: }
1027: }
1028:
1029: public X509Certificate getCertificate(Map context,
1030: BigInteger serialNumber, String issuerName)
1031: throws XWSSecurityException {
1032: return getMatchingCertificate(context, serialNumber, issuerName);
1033: }
1034:
1035: public X509Certificate getCertificate(String keyIdentifier)
1036: throws XWSSecurityException {
1037: try {
1038: byte[] decoded = getDecodedBase64EncodedData(keyIdentifier);
1039: return getMatchingCertificate(null, decoded);
1040: } catch (Exception e) {
1041: throw new XWSSecurityException(e);
1042: }
1043: }
1044:
1045: public PrivateKey getPrivateKey(Map context, PublicKey publicKey,
1046: boolean forSign) {
1047: return null;
1048: }
1049:
1050: public X509Certificate getCertificate(Map context, byte[] ski) {
1051: return null;
1052: }
1053:
1054: public X509Certificate getCertificate(Map context,
1055: PublicKey publicKey, boolean forSign)
1056: throws XWSSecurityException {
1057: return null;
1058: }
1059:
1060: public X509Certificate getCertificate(Map context,
1061: byte[] identifier, String valueType)
1062: throws XWSSecurityException {
1063: // on the lines of other getCertificates here return null for now.
1064: return null;
1065: }
1066:
1067: public boolean validateSamlIssuer(String issuer) {
1068: return true;
1069: }
1070:
1071: public boolean validateSamlUser(String user, String domain,
1072: String format) {
1073: return true;
1074: }
1075:
1076: public void setSubject(Subject subject, Map context) {
1077: context.put(MessageConstants.SELF_SUBJECT, subject);
1078: }
1079:
1080: public void setRequesterSubject(Subject subject, Map context) {
1081: context.put(MessageConstants.AUTH_SUBJECT, subject);
1082: }
1083:
1084: public Subject getSubject() {
1085: return null;
1086: }
1087:
1088: public Subject getSubject(Map context) {
1089: return (Subject) context.get(MessageConstants.SELF_SUBJECT);
1090: }
1091:
1092: public Subject getRequesterSubject(Map context) {
1093: return (Subject) context.get(MessageConstants.AUTH_SUBJECT);
1094: }
1095:
1096: private Date getGMTDateWithSkewAdjusted(Calendar c, boolean addSkew) {
1097: long offset = c.get(Calendar.ZONE_OFFSET);
1098: if (c.getTimeZone().inDaylightTime(c.getTime())) {
1099: offset += c.getTimeZone().getDSTSavings();
1100: }
1101: long beforeTime = c.getTimeInMillis();
1102: long currentTime = beforeTime - offset;
1103:
1104: if (addSkew)
1105: currentTime = currentTime + MAX_CLOCK_SKEW;
1106: else
1107: currentTime = currentTime - MAX_CLOCK_SKEW;
1108:
1109: c.setTimeInMillis(currentTime);
1110: return c.getTime();
1111: }
1112:
1113: /**
1114: * Not implemented: AuthModules use Callbacks internally
1115: */
1116: public String getUsername(Map context) throws XWSSecurityException {
1117:
1118: NameCallback nameCallback = new NameCallback("Username: ");
1119: try {
1120: Callback[] cbs = new Callback[] { nameCallback };
1121: _handler.handle(cbs);
1122: } catch (Exception e) {
1123: throw new RuntimeException(e);
1124: }
1125:
1126: return nameCallback.getName();
1127: }
1128:
1129: /**
1130: * Not implemented: AuthModules use Callbacks internally
1131: */
1132: public String getPassword(Map context) throws XWSSecurityException {
1133:
1134: PasswordCallback pwdCallback = new PasswordCallback(
1135: "Password: ", false);
1136: try {
1137: Callback[] cbs = new Callback[] { pwdCallback };
1138: _handler.handle(cbs);
1139: } catch (Exception e) {
1140: throw new RuntimeException(e);
1141: }
1142:
1143: if (pwdCallback.getPassword() == null)
1144: return null;
1145:
1146: return new String(pwdCallback.getPassword());
1147: }
1148:
1149: public boolean validateAndCacheNonce(String nonce, String created,
1150: long maxNonceAge) throws XWSSecurityException {
1151: if ((nonceCache == null) || nonceCache.wasCanceled())
1152: initNonceCache(maxNonceAge);
1153:
1154: // check if the reclaimer Task is scheduled or not
1155: if (!nonceCache.isScheduled())
1156: setNonceCacheCleanup();
1157:
1158: return nonceCache.validateAndCacheNonce(nonce, created);
1159: }
1160:
1161: private synchronized void initNonceCache(long maxNonceAge) {
1162:
1163: if (nonceCache == null) {
1164: if (maxNonceAge == 0) {
1165: nonceCache = new NonceCache();
1166: } else {
1167: nonceCache = new NonceCache(maxNonceAge);
1168: }
1169: } else if (nonceCache.wasCanceled()) {
1170: if (maxNonceAge == 0) {
1171: nonceCache = new NonceCache();
1172: } else {
1173: nonceCache = new NonceCache(maxNonceAge);
1174: }
1175: }
1176: }
1177:
1178: private synchronized void setNonceCacheCleanup() {
1179:
1180: if (!nonceCache.isScheduled()) {
1181: nonceCleanupTimer.schedule(nonceCache, nonceCache
1182: .getMaxNonceAge(), // run it the first time after
1183: nonceCache.getMaxNonceAge()); //repeat every
1184: nonceCache.scheduled(true);
1185: }
1186: }
1187:
1188: public void validateTimestamp(Map context, String created,
1189: String expires, long maxClockSkew, long freshnessLimit)
1190: throws XWSSecurityException {
1191: if (expiresBeforeCreated(created, expires)) {
1192: XWSSecurityException xwsse = new XWSSecurityException(
1193: "Message expired!");
1194: throw DefaultSecurityEnvironmentImpl.newSOAPFaultException(
1195: MessageConstants.WSU_MESSAGE_EXPIRED,
1196: "Message expired!", xwsse);
1197: }
1198: validateCreationTime(context, created, maxClockSkew,
1199: freshnessLimit);
1200: validateExpirationTime(expires, maxClockSkew, freshnessLimit);
1201: }
1202:
1203: public void validateTimestamp(Map context, Timestamp timestamp,
1204: long maxClockSkew, long freshnessLimit)
1205: throws XWSSecurityException {
1206: validateTimestamp(context, timestamp.getCreated(), timestamp
1207: .getExpires(), maxClockSkew, freshnessLimit);
1208: }
1209:
1210: private static boolean expiresBeforeCreated(String creationTime,
1211: String expirationTime) throws XWSSecurityException {
1212: Date created = null;
1213: Date expires = null;
1214: try {
1215: try {
1216: synchronized (calendarFormatter1) {
1217: created = calendarFormatter1.parse(creationTime);
1218: }
1219: if (expirationTime != null) {
1220: synchronized (calendarFormatter1) {
1221: expires = calendarFormatter1
1222: .parse(expirationTime);
1223: }
1224: }
1225:
1226: } catch (java.text.ParseException pe) {
1227: synchronized (calendarFormatter2) {
1228: created = calendarFormatter2.parse(creationTime);
1229: }
1230: if (expirationTime != null) {
1231: synchronized (calendarFormatter2) {
1232: expires = calendarFormatter2
1233: .parse(expirationTime);
1234: }
1235: }
1236: }
1237: } catch (java.text.ParseException pe) {
1238: throw new XWSSecurityException(pe.getMessage());
1239: }
1240:
1241: if ((expires != null) && expires.before(created))
1242: return true;
1243:
1244: return false;
1245: }
1246:
1247: public void validateCreationTime(Map context, String creationTime,
1248: long maxClockSkew, long timestampFreshnessLimit)
1249: throws XWSSecurityException {
1250: Date created;
1251: try {
1252: synchronized (calendarFormatter1) {
1253: created = calendarFormatter1.parse(creationTime);
1254: }
1255: } catch (java.text.ParseException pe) {
1256: try {
1257: synchronized (calendarFormatter2) {
1258: created = calendarFormatter2.parse(creationTime);
1259: }
1260: } catch (java.text.ParseException pe1) {
1261: throw new XWSSecurityException(
1262: "Exception while parsing Creation Time :"
1263: + pe1.getMessage());
1264: }
1265: }
1266:
1267: Date current = null;
1268: try {
1269: current = getFreshnessAndSkewAdjustedDate(maxClockSkew,
1270: timestampFreshnessLimit);
1271: } catch (java.text.ParseException pe) {
1272: throw new XWSSecurityException(pe.getMessage());
1273: }
1274:
1275: if (created.before(current)) {
1276: XWSSecurityException xwsse = new XWSSecurityException(
1277: "Creation Time is older than configured Timestamp Freshness Interval!");
1278: throw DefaultSecurityEnvironmentImpl
1279: .newSOAPFaultException(
1280: MessageConstants.WSSE_INVALID_SECURITY,
1281: "Creation Time is older than configured Timestamp Freshness Interval!",
1282: xwsse);
1283: }
1284:
1285: Date currentTime = getGMTDateWithSkewAdjusted(
1286: new GregorianCalendar(), maxClockSkew, true);
1287:
1288: if (currentTime.before(created)) {
1289: XWSSecurityException xwsse = new XWSSecurityException(
1290: "Creation Time ahead of Current Time!");
1291: throw DefaultSecurityEnvironmentImpl.newSOAPFaultException(
1292: MessageConstants.WSSE_INVALID_SECURITY,
1293: "Creation Time ahead of Current Time!", xwsse);
1294: }
1295:
1296: }
1297:
1298: private void validateExpirationTime(String expirationTime,
1299: long maxClockSkew, long timestampFreshnessLimit)
1300: throws XWSSecurityException {
1301: if (expirationTime != null) {
1302: Date expires;
1303: try {
1304: synchronized (calendarFormatter1) {
1305: expires = calendarFormatter1.parse(expirationTime);
1306: }
1307: } catch (java.text.ParseException pe) {
1308: try {
1309: synchronized (calendarFormatter2) {
1310: expires = calendarFormatter2
1311: .parse(expirationTime);
1312: }
1313: } catch (java.text.ParseException pe1) {
1314: throw new XWSSecurityException(
1315: "Exception while parsing Expiration Time :"
1316: + pe1.getMessage());
1317: }
1318: }
1319:
1320: Date currentTime = getGMTDateWithSkewAdjusted(
1321: new GregorianCalendar(), maxClockSkew, false);
1322:
1323: if (expires.before(currentTime)) {
1324: XWSSecurityException xwsse = new XWSSecurityException(
1325: "Message Expired!");
1326: throw DefaultSecurityEnvironmentImpl
1327: .newSOAPFaultException(
1328: MessageConstants.WSU_MESSAGE_EXPIRED,
1329: "Message Expired!", xwsse);
1330: }
1331: }
1332: }
1333:
1334: public CallbackHandler getCallbackHandler()
1335: throws XWSSecurityException {
1336: return _handler;
1337: }
1338:
1339: public void validateSAMLAssertion(Map context, Element assertion)
1340: throws XWSSecurityException {
1341: throw new UnsupportedOperationException("Not supported");
1342: }
1343:
1344: public Element locateSAMLAssertion(Map context, Element binding,
1345: String assertionId, Document ownerDoc)
1346: throws XWSSecurityException {
1347: throw new UnsupportedOperationException("Not supported");
1348: }
1349:
1350: public AuthenticationTokenPolicy.SAMLAssertionBinding populateSAMLPolicy(
1351: Map fpcontext,
1352: AuthenticationTokenPolicy.SAMLAssertionBinding policy,
1353: DynamicApplicationContext context)
1354: throws XWSSecurityException {
1355: throw new UnsupportedOperationException("Not supported");
1356: }
1357:
1358: private static Date getGMTDateWithSkewAdjusted(Calendar c,
1359: long maxClockSkew, boolean addSkew) {
1360: long offset = c.get(Calendar.ZONE_OFFSET);
1361: if (c.getTimeZone().inDaylightTime(c.getTime())) {
1362: offset += c.getTimeZone().getDSTSavings();
1363: }
1364: long beforeTime = c.getTimeInMillis();
1365: long currentTime = beforeTime - offset;
1366:
1367: if (addSkew)
1368: currentTime = currentTime + maxClockSkew;
1369: else
1370: currentTime = currentTime - maxClockSkew;
1371:
1372: c.setTimeInMillis(currentTime);
1373: return c.getTime();
1374: }
1375:
1376: private static Date getFreshnessAndSkewAdjustedDate(
1377: long maxClockSkew, long timestampFreshnessLimit)
1378: throws ParseException {
1379: Calendar c = new GregorianCalendar();
1380: long offset = c.get(Calendar.ZONE_OFFSET);
1381: if (c.getTimeZone().inDaylightTime(c.getTime())) {
1382: offset += c.getTimeZone().getDSTSavings();
1383: }
1384: long beforeTime = c.getTimeInMillis();
1385: long currentTime = beforeTime - offset;
1386:
1387: // allow for clock_skew and timestamp_freshness
1388: long adjustedTime = currentTime - maxClockSkew
1389: - timestampFreshnessLimit;
1390: c.setTimeInMillis(adjustedTime);
1391:
1392: return c.getTime();
1393: }
1394:
1395: private X509Certificate getDynamicCertificate(Map context,
1396: KeyStore trustStore) {
1397:
1398: X509Certificate cert = null;
1399:
1400: Subject requesterSubject = getRequesterSubject(context);
1401: String keyId = (String) context
1402: .get(MessageConstants.REQUESTER_KEYID);
1403: String issuerName = (String) context
1404: .get(MessageConstants.REQUESTER_ISSUERNAME);
1405: BigInteger issuerSerial = (BigInteger) context
1406: .get(MessageConstants.REQUESTER_SERIAL);
1407:
1408: if (keyId != null) {
1409: try {
1410: cert = getMatchingCertificate(keyId.getBytes(),
1411: trustStore);
1412: if (cert != null)
1413: return cert;
1414: } catch (XWSSecurityException e) {
1415: }
1416: } else if ((issuerName != null) && (issuerSerial != null)) {
1417: try {
1418: cert = getMatchingCertificate(issuerSerial, issuerName,
1419: trustStore);
1420: if (cert != null)
1421: return cert;
1422: } catch (XWSSecurityException e) {
1423: }
1424: } else if (requesterSubject != null) {
1425: Set publicCredentials = requesterSubject
1426: .getPublicCredentials();
1427: for (Iterator it = publicCredentials.iterator(); it
1428: .hasNext();) {
1429: Object cred = it.next();
1430: if (cred instanceof java.security.cert.X509Certificate) {
1431: cert = (java.security.cert.X509Certificate) cred;
1432: }
1433: }
1434: if (cert != null) {
1435: return cert;
1436: }
1437: }
1438: return null;
1439: }
1440:
1441: public void updateOtherPartySubject(Subject subj,
1442: String encryptedKey) {
1443: //TODO:
1444: }
1445:
1446: public void updateOtherPartySubject(Subject subject, Key secretKey) {
1447: }
1448:
1449: public PrivateKey getPrivateKey(Map context, byte[] keyIdentifier,
1450: String valueType) throws XWSSecurityException {
1451: if (MessageConstants.KEY_INDETIFIER_TYPE.equals(valueType)) {
1452: return getPrivateKey(context, keyIdentifier);
1453: }
1454:
1455: try {
1456: Subject subject = getSubject(context);
1457: if (subject != null) {
1458: Set set = subject
1459: .getPrivateCredentials(X500PrivateCredential.class);
1460: if (set != null) {
1461: Iterator it = set.iterator();
1462: while (it.hasNext()) {
1463: X500PrivateCredential cred = (X500PrivateCredential) it
1464: .next();
1465: if (matchesThumbPrint(Base64
1466: .decode(keyIdentifier), cred
1467: .getCertificate()))
1468: return cred.getPrivateKey();
1469: }
1470: }
1471: }
1472:
1473: // TODO: change this
1474: //PrivateKeyCallback.Request request = new PrivateKeyCallback.ThumbPrintRequest(
1475: // keyIdentifier);
1476: PrivateKeyCallback.Request request = new PrivateKeyCallback.SubjectKeyIDRequest(
1477: keyIdentifier);
1478:
1479: PrivateKeyCallback pkCallback = new PrivateKeyCallback(
1480: request);
1481: Callback[] callbacks = new Callback[] { pkCallback };
1482: _handler.handle(callbacks);
1483:
1484: return pkCallback.getKey();
1485: } catch (Exception e) {
1486: throw new XWSSecurityException(e);
1487: }
1488:
1489: }
1490:
1491: public void validateSAMLAssertion(Map context,
1492: XMLStreamReader assertion) throws XWSSecurityException {
1493: throw new UnsupportedOperationException("Not supported");
1494: }
1495:
1496: public void updateOtherPartySubject(Subject subject,
1497: XMLStreamReader assertion) {
1498: //TODO:
1499: }
1500:
1501: public boolean isSelfCertificate(X509Certificate cert) {
1502: throw new UnsupportedOperationException("Not supported");
1503: }
1504:
1505: public void updateOtherPartySubject(Subject subject,
1506: Subject bootStrapSubject) {
1507: throw new UnsupportedOperationException("Not supported");
1508: }
1509:
1510: }
|