| /* |
| * Copyright 2004,2005 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.rampart.builder; |
| |
| import org.apache.axiom.om.OMElement; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.rahas.TrustException; |
| import org.apache.rampart.RampartException; |
| import org.apache.rampart.RampartMessageData; |
| import org.apache.rampart.policy.RampartPolicyData; |
| import org.apache.rampart.util.RampartUtil; |
| import org.apache.ws.secpolicy.Constants; |
| import org.apache.ws.secpolicy.model.IssuedToken; |
| import org.apache.ws.secpolicy.model.SupportingToken; |
| import org.apache.ws.secpolicy.model.Token; |
| import org.apache.ws.secpolicy.model.UsernameToken; |
| import org.apache.ws.secpolicy.model.X509Token; |
| import org.apache.ws.security.WSConstants; |
| import org.apache.ws.security.WSEncryptionPart; |
| import org.apache.ws.security.WSSecurityException; |
| import org.apache.ws.security.conversation.ConversationException; |
| import org.apache.ws.security.handler.WSHandlerConstants; |
| import org.apache.ws.security.message.WSSecDKSign; |
| import org.apache.ws.security.message.WSSecEncryptedKey; |
| import org.apache.ws.security.message.WSSecSignature; |
| import org.apache.ws.security.message.WSSecUsernameToken; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.Vector; |
| |
| public class TransportBindingBuilder extends BindingBuilder { |
| |
| private static Log log = LogFactory.getLog(TransportBindingBuilder.class); |
| |
| public void build(RampartMessageData rmd) throws RampartException { |
| |
| log.debug("TransportBindingBuilder build invoked"); |
| |
| RampartPolicyData rpd = rmd.getPolicyData(); |
| |
| if (rpd.isIncludeTimestamp()) { |
| addTimestamp(rmd); |
| } |
| |
| /* |
| * Process Supporting tokens |
| */ |
| if(rmd.isInitiator()) { |
| Vector signatureValues = new Vector(); |
| |
| SupportingToken sgndSuppTokens = rpd.getSignedSupportingTokens(); |
| |
| if(sgndSuppTokens != null && sgndSuppTokens.getTokens() != null && |
| sgndSuppTokens.getTokens().size() > 0) { |
| |
| log.debug("Processing signed supporting tokens"); |
| |
| ArrayList tokens = sgndSuppTokens.getTokens(); |
| for (Iterator iter = tokens.iterator(); iter.hasNext();) { |
| |
| Token token = (Token) iter.next(); |
| if(token instanceof UsernameToken) { |
| WSSecUsernameToken utBuilder = addUsernameToken(rmd); |
| utBuilder.setPasswordType(WSConstants.PASSWORD_TEXT); |
| |
| utBuilder.prepare(rmd.getDocument()); |
| |
| //Add the UT |
| utBuilder.appendToHeader(rmd.getSecHeader()); |
| |
| } else { |
| throw new RampartException("unsupportedSignedSupportingToken", |
| new String[]{"{" +token.getName().getNamespaceURI() |
| + "}" + token.getName().getLocalPart()}); |
| } |
| } |
| } |
| |
| SupportingToken sgndEndSuppTokens = rpd.getSignedEndorsingSupportingTokens(); |
| if(sgndEndSuppTokens != null && sgndEndSuppTokens.getTokens() != null && |
| sgndEndSuppTokens.getTokens().size() > 0) { |
| |
| log.debug("Processing endorsing signed supporting tokens"); |
| |
| ArrayList tokens = sgndEndSuppTokens.getTokens(); |
| for (Iterator iter = tokens.iterator(); iter.hasNext();) { |
| Token token = (Token) iter.next(); |
| if(token instanceof IssuedToken && rmd.isInitiator()) { |
| signatureValues.add(doIssuedTokenSignature(rmd, token)); |
| } else if(token instanceof X509Token) { |
| signatureValues.add(doX509TokenSignature(rmd, token)); |
| } |
| } |
| } |
| |
| SupportingToken endSupptokens = rpd.getEndorsingSupportingTokens(); |
| if(endSupptokens != null && endSupptokens.getTokens() != null && |
| endSupptokens.getTokens().size() > 0) { |
| log.debug("Processing endorsing supporting tokens"); |
| ArrayList tokens = endSupptokens.getTokens(); |
| for (Iterator iter = tokens.iterator(); iter.hasNext();) { |
| Token token = (Token) iter.next(); |
| if(token instanceof IssuedToken && rmd.isInitiator()){ |
| signatureValues.add(doIssuedTokenSignature(rmd, token)); |
| } else if(token instanceof X509Token) { |
| signatureValues.add(doX509TokenSignature(rmd, token)); |
| } |
| } |
| } |
| |
| |
| SupportingToken supportingToks = rpd.getSupportingTokens(); |
| this.handleSupportingTokens(rmd, supportingToks); |
| |
| |
| //Store the signature values vector |
| rmd.getMsgContext().setProperty(WSHandlerConstants.SEND_SIGV, signatureValues); |
| } else { |
| addSignatureConfirmation(rmd, null); |
| } |
| } |
| |
| |
| |
| /** |
| * X.509 signature |
| * @param rmd |
| * @param token |
| */ |
| private byte[] doX509TokenSignature(RampartMessageData rmd, Token token) throws RampartException { |
| |
| RampartPolicyData rpd = rmd.getPolicyData(); |
| Document doc = rmd.getDocument(); |
| |
| if(token.isDerivedKeys()) { |
| //In this case we will have to encrypt the ephmeral key with the |
| //other party's key and then use it as the parent key of the |
| // derived keys |
| try { |
| |
| WSSecEncryptedKey encrKey = getEncryptedKeyBuilder(rmd, token); |
| |
| Element bstElem = encrKey.getBinarySecurityTokenElement(); |
| if(bstElem != null) { |
| RampartUtil.appendChildToSecHeader(rmd, bstElem); |
| } |
| |
| encrKey.appendToHeader(rmd.getSecHeader()); |
| |
| WSSecDKSign dkSig = new WSSecDKSign(); |
| |
| dkSig.setWsConfig(rmd.getConfig()); |
| |
| dkSig.setSigCanonicalization(rpd.getAlgorithmSuite().getInclusiveC14n()); |
| dkSig.setSignatureAlgorithm(rpd.getAlgorithmSuite().getSymmetricSignature()); |
| dkSig.setDerivedKeyLength(rpd.getAlgorithmSuite().getMinimumSymmetricKeyLength()/8); |
| |
| dkSig.setExternalKey(encrKey.getEphemeralKey(), encrKey.getId()); |
| |
| dkSig.prepare(doc, rmd.getSecHeader()); |
| |
| Vector sigParts = new Vector(); |
| |
| if(this.timestampElement != null){ |
| sigParts.add(new WSEncryptionPart(rmd.getTimestampId())); |
| } |
| |
| if(rpd.isTokenProtection()) { |
| sigParts.add(new WSEncryptionPart(encrKey.getBSTTokenId())); |
| } |
| |
| dkSig.setParts(sigParts); |
| |
| dkSig.addReferencesToSign(sigParts, rmd.getSecHeader()); |
| |
| //Do signature |
| dkSig.computeSignature(); |
| |
| dkSig.appendDKElementToHeader(rmd.getSecHeader()); |
| |
| dkSig.appendSigToHeader(rmd.getSecHeader()); |
| |
| return dkSig.getSignatureValue(); |
| |
| } catch (WSSecurityException e) { |
| throw new RampartException("errorInDerivedKeyTokenSignature", e); |
| } catch (ConversationException e) { |
| throw new RampartException("errorInDerivedKeyTokenSignature", e); |
| } |
| |
| } else { |
| |
| try { |
| WSSecSignature sig = this.getSignatureBuider(rmd, token); |
| |
| |
| sig.appendBSTElementToHeader(rmd.getSecHeader()); |
| |
| Vector sigParts = new Vector(); |
| |
| if(this.timestampElement != null ){ |
| sigParts.add(new WSEncryptionPart(rmd.getTimestampId())); |
| } |
| |
| if (rpd.isTokenProtection() |
| && !Constants.INCLUDE_NEVER |
| .equals(token.getInclusion())) { |
| sigParts.add(new WSEncryptionPart(sig.getBSTTokenId())); |
| } |
| |
| sig.addReferencesToSign(sigParts, rmd.getSecHeader()); |
| |
| sig.appendToHeader(rmd.getSecHeader()); |
| |
| sig.computeSignature(); |
| |
| return sig.getSignatureValue(); |
| } catch (WSSecurityException e) { |
| throw new RampartException("errorInSignatureWithX509Token", e); |
| } |
| |
| |
| } |
| |
| } |
| |
| |
| /** |
| * IssuedToken signature |
| * @param rmd |
| * @param token |
| * @throws RampartException |
| */ |
| private byte[] doIssuedTokenSignature(RampartMessageData rmd, Token token) throws RampartException { |
| |
| RampartPolicyData rpd = rmd.getPolicyData(); |
| Document doc= rmd.getDocument(); |
| |
| //Get the issued token |
| String id = RampartUtil.getIssuedToken(rmd, (IssuedToken)token); |
| |
| String inclusion = token.getInclusion(); |
| org.apache.rahas.Token tok = null; |
| try { |
| tok = rmd.getTokenStorage().getToken(id); |
| } catch (TrustException e) { |
| throw new RampartException("errorExtractingToken", |
| new String[]{id} ,e); |
| } |
| |
| boolean tokenIncluded = false; |
| |
| if(inclusion.equals(Constants.INCLUDE_ALWAYS) || |
| ((inclusion.equals(Constants.INCLUDE_ALWAYS_TO_RECIPIENT) |
| || inclusion.equals(Constants.INCLUDE_ONCE)) |
| && rmd.isInitiator())) { |
| |
| //Add the token |
| rmd.getSecHeader().getSecurityHeader().appendChild( |
| doc.importNode((Element) tok.getToken(), true)); |
| |
| tokenIncluded = true; |
| } |
| |
| //check for dirived keys |
| if(token.isDerivedKeys()) { |
| //Create a derived key and add |
| try { |
| |
| //Do Signature with derived keys |
| WSSecDKSign dkSign = new WSSecDKSign(); |
| |
| OMElement ref = tok.getAttachedReference(); |
| if(ref == null) { |
| ref = tok.getUnattachedReference(); |
| } |
| if(ref != null) { |
| dkSign.setExternalKey(tok.getSecret(), (Element) |
| doc.importNode((Element) ref, true)); |
| } else { |
| dkSign.setExternalKey(tok.getSecret(), tok.getId()); |
| } |
| |
| //Set the algo info |
| dkSign.setSignatureAlgorithm(rpd.getAlgorithmSuite().getSymmetricSignature()); |
| |
| |
| dkSign.prepare(doc); |
| |
| dkSign.appendDKElementToHeader(rmd.getSecHeader()); |
| |
| Vector sigParts = new Vector(); |
| |
| if(this.timestampElement != null){ |
| sigParts.add(new WSEncryptionPart(rmd.getTimestampId())); |
| } |
| |
| if(rpd.isTokenProtection() && tokenIncluded) { |
| sigParts.add(new WSEncryptionPart(id)); |
| } |
| |
| dkSign.setParts(sigParts); |
| |
| dkSign.addReferencesToSign(sigParts, rmd.getSecHeader()); |
| |
| //Do signature |
| dkSign.computeSignature(); |
| |
| dkSign.appendSigToHeader(rmd.getSecHeader()); |
| |
| return dkSign.getSignatureValue(); |
| |
| } catch (ConversationException e) { |
| throw new RampartException( |
| "errorInDerivedKeyTokenSignature", e); |
| } catch (WSSecurityException e) { |
| throw new RampartException( |
| "errorInDerivedKeyTokenSignature", e); |
| } |
| |
| } else { |
| //TODO: Do signature withtout derived keys with the Issuedtoken ?? |
| return null; |
| } |
| } |
| } |