blob: 535b5ac2f356f4736852d0ece4551c9b02007936 [file] [log] [blame]
/*
* 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;
}
}
}