List of usage examples for javax.security.auth.callback CallbackHandler handle
void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException;
Retrieve or display the information requested in the provided Callbacks.
From source file:org.apache.jackrabbit.core.security.authentication.AbstractLoginModule.java
/** * Initialize this LoginModule.<br> This abstract implementation, initalizes * the following fields for later use:/* www .j a v a 2 s.c om*/ * <ul> * <li>{@link PrincipalManager} for group-membership resoultion</li> * <li>{@link PrincipalProvider} for user-{@link Principal} resolution.</li> * <li>{@link LoginModuleConfig#PARAM_ADMIN_ID} option is evaluated</li> * <li>{@link LoginModuleConfig#PARAM_ANONYMOUS_ID} option is evaluated</li> * </ul> * Implementations are called via * {@link #doInit(CallbackHandler, Session, Map)} to implement * additional initalization * * @param subject the <code>Subject</code> to be authenticated. <p> * @param callbackHandler a <code>CallbackHandler</code> for communicating * with the end user (prompting for usernames and * passwords, for example). <p> * @param sharedState state shared with other configured * LoginModules.<p> * @param options options specified in the login <code>Configuration</code> * for this particular <code>LoginModule</code>. * @see LoginModule#initialize(Subject, CallbackHandler, Map, Map) * @see #doInit(CallbackHandler, Session, Map) * @see #isInitialized() */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { // common jaas state variables this.callbackHandler = callbackHandler; this.subject = subject; this.sharedState = sharedState; // initialize the login module try { log.debug("Initalize LoginModule: "); RepositoryCallback repositoryCb = new RepositoryCallback(); callbackHandler.handle(new Callback[] { repositoryCb }); // retrieve the principal-provider configured for this module. // if not configured -> retrieve the provider from the callback. PrincipalProviderRegistry registry = repositoryCb.getPrincipalProviderRegistry(); if (options.containsKey(LoginModuleConfig.PARAM_PRINCIPAL_PROVIDER_CLASS)) { principalProviderClassName = (String) options.get(LoginModuleConfig.PARAM_PRINCIPAL_PROVIDER_CLASS); principalProvider = registry.getProvider(principalProviderClassName); } else if (principalProviderClassName != null) { principalProvider = registry.getProvider(principalProviderClassName); } if (principalProvider == null) { principalProvider = registry.getDefault(); if (principalProvider == null) { return; // abort. not even a default principal provider } } log.debug("- PrincipalProvider -> '" + principalProvider.getClass().getName() + "'"); // call implementation for additional setup doInit(callbackHandler, repositoryCb.getSession(), options); // adminId: if not present in options -> retrieve from callback if (options.containsKey(LoginModuleConfig.PARAM_ADMIN_ID)) { adminId = (String) options.get(LoginModuleConfig.PARAM_ADMIN_ID); } if (adminId == null) { adminId = repositoryCb.getAdminId(); } // anonymousId: if not present in options -> retrieve from callback if (options.containsKey(LoginModuleConfig.PARAM_ANONYMOUS_ID)) { anonymousId = (String) options.get(LoginModuleConfig.PARAM_ANONYMOUS_ID); } if (anonymousId == null) { anonymousId = repositoryCb.getAnonymousId(); } //log config values for debug if (log.isDebugEnabled()) { Iterator itr = options.keySet().iterator(); while (itr.hasNext()) { String option = (String) itr.next(); log.debug("- Option: " + option + " -> '" + options.get(option) + "'"); } } initialized = (this.subject != null); } catch (Exception e) { log.error("LoginModule failed to initialize.", e); } }
From source file:org.apache.rahas.impl.util.SAML2Utils.java
public static SAML2KeyInfo getSAML2KeyInfo(Assertion assertion, Crypto crypto, CallbackHandler cb) throws WSSecurityException { //First ask the cb whether it can provide the secret WSPasswordCallback pwcb = new WSPasswordCallback(assertion.getID(), WSPasswordCallback.CUSTOM_TOKEN); if (cb != null) { try {//ww w .jav a 2 s . com cb.handle(new Callback[] { pwcb }); } catch (Exception e1) { throw new WSSecurityException(WSSecurityException.FAILURE, "noKey", new Object[] { assertion.getID() }, e1); } } byte[] key = pwcb.getKey(); if (key != null) { return new SAML2KeyInfo(assertion, key); } else { // if the cb fails to provide the secret. try { // extract the subject Subject samlSubject = assertion.getSubject(); if (samlSubject == null) { throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAML2Token", new Object[] { "for Signature (no Subject)" }); } // extract the subject confirmation element from the subject SubjectConfirmation subjectConf = (SubjectConfirmation) samlSubject.getSubjectConfirmations() .get(0); if (subjectConf == null) { throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAML2Token", new Object[] { "for Signature (no Subject Confirmation)" }); } // Get the subject confirmation data, KeyInfoConfirmationDataType extends SubjectConfirmationData. SubjectConfirmationData scData = subjectConf.getSubjectConfirmationData(); if (scData == null) { throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAML2Token", new Object[] { "for Signature (no Subject Confirmation Data)" }); } // Get the SAML specific XML representation of the keyInfo object XMLObject KIElem = null; List<XMLObject> scDataElements = scData.getOrderedChildren(); Iterator<XMLObject> iterator = scDataElements.iterator(); while (iterator.hasNext()) { XMLObject xmlObj = iterator.next(); if (xmlObj instanceof org.opensaml.xml.signature.KeyInfo) { KIElem = xmlObj; break; } } Element keyInfoElement; // Generate a DOM element from the XMLObject. if (KIElem != null) { // Set the "javax.xml.parsers.DocumentBuilderFactory" system property to make sure the endorsed JAXP // implementation is picked over the default jaxp impl shipped with the JDK. String jaxpProperty = System.getProperty("javax.xml.parsers.DocumentBuilderFactory"); System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"); MarshallerFactory marshallerFactory = org.opensaml.xml.Configuration.getMarshallerFactory(); Marshaller marshaller = marshallerFactory.getMarshaller(KIElem); keyInfoElement = marshaller.marshall(KIElem); // Reset the sys. property to its previous value. if (jaxpProperty == null) { System.getProperties().remove("javax.xml.parsers.DocumentBuilderFactory"); } else { System.setProperty("javax.xml.parsers.DocumentBuilderFactory", jaxpProperty); } } else { throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAML2Token", new Object[] { "for Signature (no key info element)" }); } AttributeStatement attrStmt = assertion.getAttributeStatements().size() != 0 ? (AttributeStatement) assertion.getAttributeStatements().get(0) : null; AuthnStatement authnStmt = assertion.getAuthnStatements().size() != 0 ? (AuthnStatement) assertion.getAuthnStatements().get(0) : null; // if an attr stmt is present, then it has a symmetric key. if (attrStmt != null) { NodeList children = keyInfoElement.getChildNodes(); int len = children.getLength(); for (int i = 0; i < len; i++) { Node child = children.item(i); if (child.getNodeType() != Node.ELEMENT_NODE) { continue; } QName el = new QName(child.getNamespaceURI(), child.getLocalName()); if (el.equals(WSSecurityEngine.ENCRYPTED_KEY)) { EncryptedKeyProcessor proc = new EncryptedKeyProcessor(); proc.handleEncryptedKey((Element) child, cb, crypto, null); return new SAML2KeyInfo(assertion, proc.getDecryptedBytes()); } else if (el.equals(new QName(WSConstants.WST_NS, "BinarySecret"))) { Text txt = (Text) child.getFirstChild(); return new SAML2KeyInfo(assertion, Base64.decode(txt.getData())); } else if (el.equals(new QName(WSConstants.SIG_NS, "X509Data"))) { X509Certificate[] certs = null; try { KeyInfo ki = new KeyInfo(keyInfoElement, null); if (ki.containsX509Data()) { X509Data data = ki.itemX509Data(0); XMLX509Certificate certElem = null; if (data != null && data.containsCertificate()) { certElem = data.itemCertificate(0); } if (certElem != null) { X509Certificate cert = certElem.getX509Certificate(); certs = new X509Certificate[1]; certs[0] = cert; return new SAML2KeyInfo(assertion, certs); } } } catch (XMLSecurityException e3) { throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity", new Object[] { "cannot get certificate (key holder)" }, e3); } } } } // If an authn stmt is present then it has a public key. if (authnStmt != null) { X509Certificate[] certs = null; try { KeyInfo ki = new KeyInfo(keyInfoElement, null); if (ki.containsX509Data()) { X509Data data = ki.itemX509Data(0); XMLX509Certificate certElem = null; if (data != null && data.containsCertificate()) { certElem = data.itemCertificate(0); } if (certElem != null) { X509Certificate cert = certElem.getX509Certificate(); certs = new X509Certificate[1]; certs[0] = cert; return new SAML2KeyInfo(assertion, certs); } } } catch (XMLSecurityException e3) { throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity", new Object[] { "cannot get certificate (key holder)" }, e3); } } throw new WSSecurityException(WSSecurityException.FAILURE, "invalidSAMLsecurity", new Object[] { "cannot get certificate or key " }); } catch (MarshallingException e) { throw new WSSecurityException(WSSecurityException.FAILURE, "Failed marshalling the SAML Assertion", null, e); } } }
From source file:org.apache.rampart.builder.BindingBuilder.java
/** * Add a UsernameToken to the security header * //w w w .j a va 2 s .co m * @param rmd * @return The <code>WSSecUsernameToken</code> instance * @throws RampartException */ protected WSSecUsernameToken addUsernameToken(RampartMessageData rmd, UsernameToken token) throws RampartException { log.debug("Adding a UsernameToken"); RampartPolicyData rpd = rmd.getPolicyData(); // Get the user // First try options Options options = rmd.getMsgContext().getOptions(); String user = options.getUserName(); if (user == null || user.length() == 0) { // Then try RampartConfig if (rpd.getRampartConfig() != null) { user = rpd.getRampartConfig().getUser(); } } if (user != null && !"".equals(user)) { if (log.isDebugEnabled()) { log.debug("User : " + user); } // If NoPassword property is set we don't need to set the password if (token.isNoPassword()) { WSSecUsernameToken utBuilder = new WSSecUsernameToken(); utBuilder.setUserInfo(user, null); utBuilder.setPasswordType(null); if (rmd.getConfig() != null) { utBuilder.setWsConfig(rmd.getConfig()); } return utBuilder; } // Get the password // First check options object for a password String password = options.getPassword(); if (password == null || password.length() == 0) { // Then try to get the password from the given callback handler CallbackHandler handler = RampartUtil.getPasswordCB(rmd); if (handler == null) { // If the callback handler is missing throw new RampartException("cbHandlerMissing"); } WSPasswordCallback[] cb = { new WSPasswordCallback(user, WSPasswordCallback.USERNAME_TOKEN) }; try { handler.handle(cb); } catch (Exception e) { throw new RampartException("errorInGettingPasswordForUser", new String[] { user }, e); } // get the password password = cb[0].getPassword(); } if (log.isDebugEnabled()) { log.debug("Password : " + password); } if (password != null && !"".equals(password)) { // If the password is available then build the token WSSecUsernameToken utBuilder = new WSSecUsernameToken(); if (rmd.getConfig() != null) { utBuilder.setWsConfig(rmd.getConfig()); } if (token.isHashPassword()) { utBuilder.setPasswordType(WSConstants.PASSWORD_DIGEST); } else { utBuilder.setPasswordType(WSConstants.PASSWORD_TEXT); } utBuilder.setUserInfo(user, password); return utBuilder; } else { // If there's no password then throw an exception throw new RampartException("noPasswordForUser", new String[] { user }); } } else { log.debug("No user value specified in the configuration"); throw new RampartException("userMissing"); } }
From source file:org.apache.rampart.builder.BindingBuilder.java
protected WSSecSignature getSignatureBuilder(RampartMessageData rmd, Token token, String userCertAlias) throws RampartException { RampartPolicyData rpd = rmd.getPolicyData(); WSSecSignature sig = new WSSecSignature(); checkForX509PkiPath(sig, token);/*from w w w . ja v a 2 s . c o m*/ sig.setWsConfig(rmd.getConfig()); if (log.isDebugEnabled()) { log.debug("Token inclusion: " + token.getInclusion()); } RampartUtil.setKeyIdentifierType(rmd, sig, token); String user = null; if (userCertAlias != null) { user = userCertAlias; } // Get the user - First check whether userCertAlias present if (user == null) { user = rpd.getRampartConfig().getUserCertAlias(); } // If userCertAlias is not present, use user property as Alias if (user == null) { user = rpd.getRampartConfig().getUser(); } String password = null; if (user != null && !"".equals(user)) { if (log.isDebugEnabled()) { log.debug("User : " + user); } // Get the password CallbackHandler handler = RampartUtil.getPasswordCB(rmd); if (handler == null) { // If the callback handler is missing throw new RampartException("cbHandlerMissing"); } WSPasswordCallback[] cb = { new WSPasswordCallback(user, WSPasswordCallback.SIGNATURE) }; try { handler.handle(cb); if (cb[0].getPassword() != null && !"".equals(cb[0].getPassword())) { password = cb[0].getPassword(); if (log.isDebugEnabled()) { log.debug("Password : " + password); } } else { // If there's no password then throw an exception throw new RampartException("noPasswordForUser", new String[] { user }); } } catch (IOException e) { throw new RampartException("errorInGettingPasswordForUser", new String[] { user }, e); } catch (UnsupportedCallbackException e) { throw new RampartException("errorInGettingPasswordForUser", new String[] { user }, e); } } else { log.debug("No user value specified in the configuration"); if (token instanceof IssuedToken) { throw new RampartException("userMissing"); } } sig.setUserInfo(user, password); sig.setSignatureAlgorithm(rpd.getAlgorithmSuite().getAsymmetricSignature()); sig.setSigCanonicalization(rpd.getAlgorithmSuite().getInclusiveC14n()); try { sig.prepare(rmd.getDocument(), RampartUtil.getSignatureCrypto(rpd.getRampartConfig(), rmd.getCustomClassLoader()), rmd.getSecHeader()); } catch (WSSecurityException e) { throw new RampartException("errorInSignatureWithX509Token", e); } return sig; }
From source file:org.apache.rampart.builder.BindingBuilder.java
protected WSSecKerberosToken getKerberosTokenBuilder(RampartMessageData rmd, Token token) throws RampartException { RampartPolicyData rpd = rmd.getPolicyData(); KerberosConfig krbConfig = rpd.getRampartConfig().getKerberosConfig(); if (krbConfig == null || krbConfig.getProp() == null) { throw new RampartException("noKerberosConfigDefined"); }//w w w. j a v a 2s . co m WSSecKerberosToken krb = new WSSecKerberosToken(); krb.setWsConfig(rmd.getConfig()); log.debug("Token inclusion: " + token.getInclusion()); RampartUtil.setKeyIdentifierType(rmd, krb, token); String user = null; String passwordFromConfig = null; String clientPricipal = null; String servicePrincipal = null; String password = null; String service = null; clientPricipal = (String) rmd.getMsgContext().getProperty(KerberosConfig.CLIENT_PRINCIPLE_NAME); servicePrincipal = (String) rmd.getMsgContext().getProperty(KerberosConfig.SERVICE_PRINCIPLE_NAME); if (clientPricipal == null || servicePrincipal == null || rmd.isInitiator()) { // Get the user from kerberos configuration user = krbConfig.getProp().getProperty(KerberosConfig.CLIENT_PRINCIPLE_NAME); passwordFromConfig = krbConfig.getProp().getProperty(KerberosConfig.CLIENT_PRINCIPLE_PASSWORD); if (passwordFromConfig == null) { passwordFromConfig = krbConfig.getProp().getProperty(KerberosConfig.SERVICE_PRINCIPLE_PASSWORD); } // If kerberos user is not present, use user property as Alias if (user == null) { user = rpd.getRampartConfig().getUser(); } if (user != null && !"".equals(user)) { log.debug("User : " + user); // Get the password CallbackHandler handler = RampartUtil.getPasswordCB(rmd); if (handler != null) { WSPasswordCallback[] cb = { new WSPasswordCallback(user, WSPasswordCallback.KERBEROS_TOKEN) }; try { handler.handle(cb); if (cb[0].getPassword() != null && !"".equals(cb[0].getPassword())) { password = cb[0].getPassword(); log.debug("Password : " + password); } else { password = passwordFromConfig; } } catch (IOException e) { throw new RampartException("errorInGettingPasswordForUser", new String[] { user }, e); } catch (UnsupportedCallbackException e) { throw new RampartException("errorInGettingPasswordForUser", new String[] { user }, e); } } else { password = passwordFromConfig; } } service = krbConfig.getProp().getProperty(KerberosConfig.SERVICE_PRINCIPLE_NAME); } else { user = clientPricipal; service = servicePrincipal; } krb.setUserInfo(user, password); krb.setServicePrincipalName(service); if (!rmd.isInitiator()) { krb.setReceiver(true); } try { krb.build(rmd.getDocument(), rmd.getSecHeader()); } catch (WSSecurityException e) { throw new RampartException("errorInBuilingKereberosToken", e); } if (!rmd.isInitiator()) { setKerberosToken(rmd, krb); } return krb; }
From source file:org.apache.rampart.util.RampartUtil.java
/** * Perform a callback to get a password. * <p/>/*from w ww . j a v a2 s . c o m*/ * The called back function gets an indication why to provide a password: * to produce a UsernameToken, Signature, or a password (key) for a given * name. */ public static WSPasswordCallback performCallback(CallbackHandler cbHandler, String username, int doAction) throws RampartException { WSPasswordCallback pwCb; int reason = 0; switch (doAction) { case WSConstants.UT: case WSConstants.UT_SIGN: reason = WSPasswordCallback.USERNAME_TOKEN; break; case WSConstants.SIGN: reason = WSPasswordCallback.SIGNATURE; break; case WSConstants.ENCR: reason = WSPasswordCallback.KEY_NAME; break; } pwCb = new WSPasswordCallback(username, reason); Callback[] callbacks = new Callback[1]; callbacks[0] = pwCb; /* * Call back the application to get the password */ try { cbHandler.handle(callbacks); } catch (Exception e) { throw new RampartException("pwcbFailed", e); } return pwCb; }
From source file:org.apache.ws.security.components.crypto.Merlin.java
/** * Get a password from the CallbackHandler * @param identifier The identifier to give to the Callback * @param cb The CallbackHandler// w w w .ja v a 2 s. c o m * @return The password retrieved from the CallbackHandler * @throws WSSecurityException */ private String getPassword(String identifier, CallbackHandler cb) throws WSSecurityException { WSPasswordCallback pwCb = new WSPasswordCallback(identifier, WSPasswordCallback.DECRYPT); try { Callback[] callbacks = new Callback[] { pwCb }; cb.handle(callbacks); } catch (IOException e) { throw new WSSecurityException(WSSecurityException.FAILURE, "noPassword", new Object[] { identifier }, e); } catch (UnsupportedCallbackException e) { throw new WSSecurityException(WSSecurityException.FAILURE, "noPassword", new Object[] { identifier }, e); } return pwCb.getPassword(); }
From source file:org.apache.ws.security.handler.WSHandler.java
/** * Perform a callback to get a password. * <p/>/*from w w w . j a v a 2 s. c o m*/ * The called back function gets an indication why to provide a password: * to produce a UsernameToken, Signature, or a password (key) for a given * name. */ private WSPasswordCallback performCallback(CallbackHandler cbHandler, String username, int doAction) throws WSSecurityException { WSPasswordCallback pwCb = constructPasswordCallback(username, doAction); Callback[] callbacks = new Callback[1]; callbacks[0] = pwCb; /* * Call back the application to get the password */ try { cbHandler.handle(callbacks); } catch (Exception e) { throw new WSSecurityException("WSHandler: password callback failed", e); } return pwCb; }
From source file:org.apache.ws.security.message.token.SecurityTokenReference.java
private Element findTokenElement(Document doc, WSDocInfo docInfo, CallbackHandler cb, String uri, String type) { Element tokElement = null;/*w ww . j a v a 2s.c o m*/ String id = uri; if (id.charAt(0) == '#') { id = id.substring(1); } // // If the type is a SAMLAssertionID then find the SAML assertion - first check // if it has been previously processed, else search the header for it // String assertionStr = WSConstants.WSS_SAML_NS + WSConstants.ASSERTION_LN; if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(type) || assertionStr.equals(type)) { Element sa = docInfo.getAssertion(); if (sa == null) { sa = (Element) WSSecurityUtil.findElement(docInfo.getDocument().getDocumentElement(), WSConstants.ASSERTION_LN, WSConstants.SAML_NS); } if (sa != null) { String saID = sa.getAttribute("AssertionID"); if (doDebug) { log.debug("SAML token ID: " + saID); } if (saID.equals(id)) { tokElement = sa; } } if (tokElement == null) { Node assertion = WSSecurityUtil.findSAMLAssertionElementById(doc.getDocumentElement(), id); if (assertion != null) { tokElement = (Element) assertion; } } } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(type) || assertionStr.equals(type)) { Element sa = docInfo.getAssertion(); if (sa == null) { sa = (Element) WSSecurityUtil.findElement(docInfo.getDocument().getDocumentElement(), "Assertion", WSConstants.SAML2_NS); } if (sa != null) { String saID = sa.getAttribute("ID"); if (doDebug) log.debug((new StringBuilder()).append("SAML token ID: ").append(saID).toString()); if (saID.equals(id)) tokElement = sa; } if (tokElement == null) { Node assertion = WSSecurityUtil.findSAMLAssertionElementById(doc.getDocumentElement(), id); if (assertion != null) tokElement = (Element) assertion; } } // // Try to find a custom token // if (tokElement == null && cb != null && (WSConstants.WSC_SCT.equals(type) || WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(type) || WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(type) || assertionStr.equals(type))) { // try to find a custom token WSPasswordCallback pwcb = new WSPasswordCallback(id, WSPasswordCallback.CUSTOM_TOKEN); try { cb.handle(new Callback[] { pwcb }); Element assertionElem = pwcb.getCustomToken(); if (assertionElem != null) { tokElement = (Element) doc.importNode(assertionElem, true); } } catch (Exception e) { log.debug(e.getMessage(), e); // Consume this failure } } // // Finally try to find the element by its Id // if (tokElement == null) { tokElement = WSSecurityUtil.getElementByWsuId(doc, uri); // In some scenarios id is used rather than wsu:Id if (tokElement == null) { tokElement = WSSecurityUtil.getElementByGenId(doc, uri); } } return tokElement; }
From source file:org.apache.ws.security.processor.EncryptedKeyProcessor.java
public ArrayList handleEncryptedKey(Element xencEncryptedKey, CallbackHandler cb, Crypto crypto, PrivateKey privateKey) throws WSSecurityException { long t0 = 0, t1 = 0, t2 = 0; if (tlog.isDebugEnabled()) { t0 = System.currentTimeMillis(); }/*w ww . j a v a2 s.c o m*/ // need to have it to find the encrypted data elements in the envelope Document doc = xencEncryptedKey.getOwnerDocument(); // lookup xenc:EncryptionMethod, get the Algorithm attribute to determine // how the key was encrypted. Then check if we support the algorithm Node tmpE = null; // short living Element used for lookups only tmpE = (Element) WSSecurityUtil.getDirectChild((Node) xencEncryptedKey, "EncryptionMethod", WSConstants.ENC_NS); if (tmpE != null) { this.encryptedKeyTransportMethod = ((Element) tmpE).getAttribute("Algorithm"); } if (this.encryptedKeyTransportMethod == null) { throw new WSSecurityException(WSSecurityException.UNSUPPORTED_ALGORITHM, "noEncAlgo"); } Cipher cipher = WSSecurityUtil.getCipherInstance(this.encryptedKeyTransportMethod); // // Well, we can decrypt the session (symmetric) key. Now lookup CipherValue, this is the // value of the encrypted session key (session key usually is a symmetrical key that encrypts // the referenced content). This is a 2-step lookup // Element xencCipherValue = null; tmpE = (Element) WSSecurityUtil.getDirectChild((Node) xencEncryptedKey, "CipherData", WSConstants.ENC_NS); if (tmpE != null) { xencCipherValue = (Element) WSSecurityUtil.getDirectChild(tmpE, "CipherValue", WSConstants.ENC_NS); } if (xencCipherValue == null) { throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "noCipher"); } if (privateKey == null) { Element keyInfo = (Element) WSSecurityUtil.getDirectChild((Node) xencEncryptedKey, "KeyInfo", WSConstants.SIG_NS); String alias; if (keyInfo != null) { Element secRefToken = (Element) WSSecurityUtil.getDirectChild(keyInfo, "SecurityTokenReference", WSConstants.WSSE_NS); // // EncryptedKey must a a STR as child of KeyInfo, KeyName // valid only for EncryptedData // // if (secRefToken == null) { // secRefToken = (Element) WSSecurityUtil.getDirectChild(keyInfo, // "KeyName", WSConstants.SIG_NS); // } if (secRefToken == null) { throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "noSecTokRef"); } SecurityTokenReference secRef = new SecurityTokenReference(secRefToken); // // Well, at this point there are several ways to get the key. // Try to handle all of them :-). // alias = null; // // handle X509IssuerSerial here. First check if all elements are available, // get the appropriate data, check if all data is available. // If all is ok up to that point, look up the certificate alias according // to issuer name and serial number. // This method is recommended by OASIS WS-S specification, X509 profile // if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) { alias = secRef.getX509IssuerSerialAlias(crypto); if (log.isDebugEnabled()) { log.debug("X509IssuerSerial alias: " + alias); } } // // If wsse:KeyIdentifier found, then the public key of the attached cert was used to // encrypt the session (symmetric) key that encrypts the data. Extract the certificate // using the BinarySecurity token (was enhanced to handle KeyIdentifier too). // This method is _not_ recommended by OASIS WS-S specification, X509 profile // else if (secRef.containsKeyIdentifier()) { X509Certificate[] certs = null; if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) { Element token = secRef.getKeyIdentifierTokenElement(doc, docInfo, cb); if (crypto == null) { throw new WSSecurityException(WSSecurityException.FAILURE, "noSigCryptoFile"); } SAMLKeyInfo samlKi = SAMLUtil.getSAMLKeyInfo(token, crypto, cb); certs = samlKi.getCerts(); } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) { Element token = secRef.getKeyIdentifierTokenElement(doc, docInfo, cb); if (crypto == null) { throw new WSSecurityException(0, "noSigCryptoFile"); } SAML2KeyInfo samlKi = SAML2Util.getSAML2KeyInfo(token, crypto, cb); certs = samlKi.getCerts(); } else { certs = secRef.getKeyIdentifier(crypto); } if (certs == null || certs.length < 1 || certs[0] == null) { throw new WSSecurityException(WSSecurityException.FAILURE, "noCertsFound", new Object[] { "decryption (KeyId)" }); } // // Here we have the certificate. Now find the alias for it. Needed to identify // the private key associated with this certificate // alias = crypto.getAliasForX509Cert(certs[0]); cert = certs[0]; if (log.isDebugEnabled()) { log.debug("cert: " + certs[0]); log.debug("KeyIdentifier Alias: " + alias); } } else if (secRef.containsReference()) { Element bstElement = secRef.getTokenElement(doc, null, cb); // at this point ... check token type: Binary QName el = new QName(bstElement.getNamespaceURI(), bstElement.getLocalName()); if (el.equals(WSSecurityEngine.binaryToken)) { X509Security token = new X509Security(bstElement); String value = bstElement.getAttribute(WSSecurityEngine.VALUE_TYPE); if (!X509Security.X509_V3_TYPE.equals(value) || (token == null)) { throw new WSSecurityException(WSSecurityException.UNSUPPORTED_SECURITY_TOKEN, "unsupportedBinaryTokenType", new Object[] { "for decryption (BST)" }); } cert = token.getX509Certificate(crypto); if (cert == null) { throw new WSSecurityException(WSSecurityException.FAILURE, "noCertsFound", new Object[] { "decryption" }); } // // Here we have the certificate. Now find the alias for it. Needed to identify // the private key associated with this certificate // alias = crypto.getAliasForX509Cert(cert); if (log.isDebugEnabled()) { log.debug("BST Alias: " + alias); } } else { throw new WSSecurityException(WSSecurityException.UNSUPPORTED_SECURITY_TOKEN, "unsupportedBinaryTokenType", null); } // // The following code is somewhat strange: the called crypto method gets // the keyname and searches for a certificate with an issuer's name that is // equal to this keyname. No serialnumber is used - IMHO this does // not identifies a certificate. In addition neither the WSS4J encryption // nor signature methods use this way to identify a certificate. Because of that // the next lines of code are disabled. // // } else if (secRef.containsKeyName()) { // alias = crypto.getAliasForX509Cert(secRef.getKeyNameValue()); // if (log.isDebugEnabled()) { // log.debug("KeyName alias: " + alias); // } } else { throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "unsupportedKeyId"); } } else if (crypto.getDefaultX509Alias() != null) { alias = crypto.getDefaultX509Alias(); } else { throw new WSSecurityException(WSSecurityException.INVALID_SECURITY, "noKeyinfo"); } // // At this point we have all information necessary to decrypt the session // key: // - the Cipher object intialized with the correct methods // - The data that holds the encrypted session key // - the alias name for the private key // // Now use the callback here to get password that enables // us to read the private key // WSPasswordCallback pwCb = new WSPasswordCallback(alias, WSPasswordCallback.DECRYPT); try { Callback[] callbacks = new Callback[] { pwCb }; cb.handle(callbacks); } catch (IOException e) { throw new WSSecurityException(WSSecurityException.FAILURE, "noPassword", new Object[] { alias }, e); } catch (UnsupportedCallbackException e) { throw new WSSecurityException(WSSecurityException.FAILURE, "noPassword", new Object[] { alias }, e); } String password = pwCb.getPassword(); if (password == null) { throw new WSSecurityException(WSSecurityException.FAILURE, "noPassword", new Object[] { alias }); } try { privateKey = crypto.getPrivateKey(alias, password); } catch (Exception e) { throw new WSSecurityException(WSSecurityException.FAILED_CHECK, null, null, e); } } try { cipher.init(Cipher.DECRYPT_MODE, privateKey); } catch (Exception e1) { throw new WSSecurityException(WSSecurityException.FAILED_CHECK, null, null, e1); } try { encryptedEphemeralKey = getDecodedBase64EncodedData(xencCipherValue); decryptedBytes = cipher.doFinal(encryptedEphemeralKey); } catch (IllegalStateException e2) { throw new WSSecurityException(WSSecurityException.FAILED_CHECK, null, null, e2); } catch (Exception e2) { decryptedBytes = getRandomKey(getDataRefURIs(xencCipherValue), xencEncryptedKey.getOwnerDocument(), docInfo); } if (tlog.isDebugEnabled()) { t1 = System.currentTimeMillis(); } // At this point we have the decrypted session (symmetric) key. According // to W3C XML-Enc this key is used to decrypt _any_ references contained in // the reference list // Now lookup the references that are encrypted with this key // Element refList = (Element) WSSecurityUtil.getDirectChild((Node) xencEncryptedKey, "ReferenceList", WSConstants.ENC_NS); ArrayList dataRefs = new ArrayList(); if (refList != null) { for (tmpE = refList.getFirstChild(); tmpE != null; tmpE = tmpE.getNextSibling()) { if (tmpE.getNodeType() != Node.ELEMENT_NODE) { continue; } if (!tmpE.getNamespaceURI().equals(WSConstants.ENC_NS)) { continue; } if (tmpE.getLocalName().equals("DataReference")) { String dataRefURI = ((Element) tmpE).getAttribute("URI"); if (dataRefURI.charAt(0) == '#') { dataRefURI = dataRefURI.substring(1); } WSDataRef dataRef = decryptDataRef(doc, dataRefURI, decryptedBytes); dataRefs.add(dataRef); } } return dataRefs; } if (tlog.isDebugEnabled()) { t2 = System.currentTimeMillis(); tlog.debug( "XMLDecrypt: total= " + (t2 - t0) + ", get-sym-key= " + (t1 - t0) + ", decrypt= " + (t2 - t1)); } return null; }