| /* |
| * Copyright 2003-2004 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.ws.security.message; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.ws.security.SOAPConstants; |
| import org.apache.ws.security.WSConstants; |
| import org.apache.ws.security.WSEncryptionPart; |
| import org.apache.ws.security.WSSecurityException; |
| import org.apache.ws.security.components.crypto.Crypto; |
| import org.apache.ws.security.message.token.Reference; |
| import org.apache.ws.security.message.token.SecurityTokenReference; |
| import org.apache.ws.security.util.Base64; |
| import org.apache.ws.security.util.WSSecurityUtil; |
| import org.apache.xml.security.encryption.EncryptedData; |
| import org.apache.xml.security.encryption.XMLCipher; |
| import org.apache.xml.security.encryption.XMLEncryptionException; |
| import org.apache.xml.security.keys.KeyInfo; |
| import org.w3c.dom.Attr; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NamedNodeMap; |
| import org.w3c.dom.Node; |
| |
| import javax.crypto.KeyGenerator; |
| import javax.crypto.SecretKey; |
| |
| import java.security.MessageDigest; |
| import java.security.NoSuchAlgorithmException; |
| import java.security.cert.X509Certificate; |
| import java.util.Vector; |
| |
| /** |
| * Encrypts a parts of a message according to WS Specification, X509 profile, |
| * and adds the encryption data. |
| * |
| * @author Davanum Srinivas (dims@yahoo.com). |
| * @author Werner Dittmann (Werner.Dittmann@apache.org). |
| */ |
| public class WSSecEncrypt extends WSSecEncryptedKey { |
| private static Log log = LogFactory.getLog(WSSecEncrypt.class.getName()); |
| |
| protected String symEncAlgo = WSConstants.AES_128; |
| |
| protected String encCanonAlgo = null; |
| |
| protected byte[] embeddedKey = null; |
| |
| protected String embeddedKeyName = null; |
| |
| protected boolean useKeyIdentifier; |
| |
| /** |
| * Symmetric key used in the EncrytpedKey. |
| */ |
| protected SecretKey symmetricKey = null; |
| |
| /** |
| * SecurityTokenReference to be inserted into EncryptedData/keyInfo element. |
| */ |
| protected SecurityTokenReference securityTokenReference = null; |
| |
| /** |
| * Indicates whether to encrypt the symmetric key into an EncryptedKey |
| * or not. |
| */ |
| private boolean encryptSymmKey = true; |
| |
| /** |
| * Custom reference value |
| */ |
| private String customReferenceValue; |
| |
| /** |
| * Constructor. |
| */ |
| public WSSecEncrypt() { |
| } |
| |
| /** |
| * Sets the key to use during embedded encryption. |
| * |
| * <p/> |
| * |
| * @param key |
| * to use during encryption. The key must fit the selected |
| * symmetrical encryption algorithm |
| */ |
| public void setKey(byte[] key) { |
| this.embeddedKey = key; |
| } |
| |
| /** |
| * Sets the algorithm to encode the symmetric key. |
| * |
| * Default is the <code>WSConstants.KEYTRANSPORT_RSA15</code> algorithm. |
| * |
| * @param keyEnc |
| * specifies the key encoding algorithm. |
| * @see WSConstants#KEYTRANSPORT_RSA15 |
| * @see WSConstants#KEYTRANSPORT_RSAOEP |
| */ |
| public void setKeyEnc(String keyEnc) { |
| keyEncAlgo = keyEnc; |
| } |
| |
| /** |
| * Set the key name for EMBEDDED_KEYNAME |
| * |
| * @param embeddedKeyName |
| */ |
| public void setEmbeddedKeyName(String embeddedKeyName) { |
| this.embeddedKeyName = embeddedKeyName; |
| } |
| |
| /** |
| * Set this true if a key identifier must be used in the KeyInfo |
| * |
| * @param useKeyIdentifier |
| */ |
| public void setUseKeyIdentifier(boolean useKeyIdentifier) { |
| this.useKeyIdentifier = useKeyIdentifier; |
| } |
| |
| /** |
| * Set the name of the symmetric encryption algorithm to use. |
| * |
| * This encryption algorithm is used to encrypt the data. If the algorithm |
| * is not set then AES128 is used. Refer to WSConstants which algorithms are |
| * supported. |
| * |
| * @param algo |
| * Is the name of the encryption algorithm |
| * @see WSConstants#TRIPLE_DES |
| * @see WSConstants#AES_128 |
| * @see WSConstants#AES_192 |
| * @see WSConstants#AES_256 |
| */ |
| public void setSymmetricEncAlgorithm(String algo) { |
| symEncAlgo = algo; |
| } |
| |
| /** |
| * Set the name of an optional canonicalization algorithm to use before |
| * encryption. |
| * |
| * This c14n algorithm is used to serialize the data before encryption. If |
| * the algorithm is not set then a standard serialization is used (provided |
| * by XMLCipher, usually a XMLSerializer according to DOM 3 specification). |
| * |
| * @param algo |
| * Is the name of the canonicalization algorithm |
| */ |
| public void setEncCanonicalization(String algo) { |
| encCanonAlgo = algo; |
| } |
| |
| /** |
| * Get the name of symmetric encryption algorithm to use. |
| * |
| * The name of the encryption algorithm to encrypt the data, i.e. the SOAP |
| * Body. Refer to WSConstants which algorithms are supported. |
| * |
| * @return the name of the currently selected symmetric encryption algorithm |
| * @see WSConstants#TRIPLE_DES |
| * @see WSConstants#AES_128 |
| * @see WSConstants#AES_192 |
| * @see WSConstants#AES_256 |
| */ |
| public String getSymmetricEncAlgorithm() { |
| return symEncAlgo; |
| } |
| |
| /** |
| * Returns if Key Identifiers should be used in KeyInfo |
| * @return if Key Identifiers should be used in KeyInfo |
| */ |
| public boolean getUseKeyIdentifier() { |
| return useKeyIdentifier; |
| } |
| |
| /** |
| * Initialize a WSSec Encrypt. |
| * |
| * The method prepares and initializes a WSSec Encrypt structure after the |
| * relevant information was set. After preparation of the token references |
| * can be added and encrypted. |
| * |
| * </p> |
| * |
| * This method does not add any element to the security header. This must be |
| * done explicitly. |
| * |
| * @param doc |
| * The SOAP envelope as <code>Document</code> |
| * @param crypto |
| * An instance of the Crypto API to handle keystore and |
| * certificates |
| * @throws WSSecurityException |
| */ |
| public void prepare(Document doc, Crypto crypto) throws WSSecurityException { |
| |
| document = doc; |
| |
| /* |
| * If no external key (symmetricalKey) was set generate an encryption |
| * key (session key) for this Encrypt element. This key will be |
| * encrypted using the public key of the receiver |
| */ |
| |
| |
| if(this.ephemeralKey == null) { |
| if (symmetricKey == null) { |
| KeyGenerator keyGen = getKeyGenerator(); |
| this.symmetricKey = keyGen.generateKey(); |
| } |
| this.ephemeralKey = this.symmetricKey.getEncoded(); |
| } |
| |
| if (this.symmetricKey == null) { |
| |
| this.symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo, |
| this.ephemeralKey); |
| } |
| |
| /* |
| * Get the certificate that contains the public key for the public key |
| * algorithm that will encrypt the generated symmetric (session) key. |
| */ |
| if(this.encryptSymmKey) { |
| X509Certificate remoteCert = null; |
| if (useThisCert != null) { |
| remoteCert = useThisCert; |
| } else { |
| X509Certificate[] certs = crypto.getCertificates(user); |
| if (certs == null || certs.length <= 0) { |
| throw new WSSecurityException( |
| WSSecurityException.FAILURE, |
| "noUserCertsFound", |
| new Object[] { user, "encryption" } |
| ); |
| } |
| remoteCert = certs[0]; |
| } |
| prepareInternal(this.ephemeralKey, remoteCert, crypto); |
| } |
| } |
| |
| /** |
| * Builds the SOAP envelope with encrypted Body and adds encrypted key. |
| * |
| * This is a convenience method and for backward compatibility. The method |
| * calls the single function methods in order to perform a <i>one shot |
| * encryption</i>. This method is compatible with the build method of the |
| * previous version with the exception of the additional WSSecHeader |
| * parameter. |
| * |
| * @param doc |
| * the SOAP envelope as <code>Document</code> with plain text |
| * Body |
| * @param crypto |
| * an instance of the Crypto API to handle keystore and |
| * Certificates |
| * @param secHeader |
| * the security header element to hold the encrypted key element. |
| * @return the SOAP envelope with encrypted Body as <code>Document |
| * </code> |
| * @throws WSSecurityException |
| */ |
| public Document build(Document doc, Crypto crypto, WSSecHeader secHeader) |
| throws WSSecurityException { |
| doDebug = log.isDebugEnabled(); |
| |
| if (keyIdentifierType == WSConstants.EMBEDDED_KEYNAME |
| || keyIdentifierType == WSConstants.EMBED_SECURITY_TOKEN_REF) { |
| return buildEmbedded(doc, secHeader); |
| } |
| |
| if (doDebug) { |
| log.debug("Beginning Encryption..."); |
| } |
| |
| prepare(doc, crypto); |
| |
| if (envelope == null) { |
| envelope = document.getDocumentElement(); |
| } |
| |
| SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope); |
| if (parts == null) { |
| parts = new Vector(); |
| WSEncryptionPart encP = new WSEncryptionPart(soapConstants |
| .getBodyQName().getLocalPart(), soapConstants |
| .getEnvelopeURI(), "Content"); |
| parts.add(encP); |
| } |
| |
| Element refs = encryptForInternalRef(null, parts); |
| addInternalRefElement(refs); |
| |
| prependToHeader(secHeader); |
| |
| if (bstToken != null) { |
| prependBSTElementToHeader(secHeader); |
| } |
| |
| log.debug("Encryption complete."); |
| return doc; |
| } |
| |
| /** |
| * Encrypt one or more parts or elements of the message (internal). |
| * |
| * This method takes a vector of <code>WSEncryptionPart</code> object that |
| * contain information about the elements to encrypt. The method call the |
| * encryption method, takes the reference information generated during |
| * encryption and add this to the <code>xenc:Reference</code> element. |
| * This method can be called after <code>prepare()</code> and can be |
| * called multiple times to encrypt a number of parts or elements. |
| * |
| * </p> |
| * |
| * The method generates a <code>xenc:Reference</code> element that <i>must</i> |
| * be added to this token. See <code>addInternalRefElement()</code>. |
| * |
| * </p> |
| * |
| * If the <code>dataRef</code> parameter is <code>null</code> the method |
| * creates and initializes a new Reference element. |
| * |
| * @param dataRef |
| * A <code>xenc:Reference</code> element or <code>null</code> |
| * @param references |
| * A vector containing WSEncryptionPart objects |
| * @return Returns the updated <code>xenc:Reference</code> element |
| * @throws WSSecurityException |
| */ |
| public Element encryptForInternalRef(Element dataRef, Vector references) |
| throws WSSecurityException { |
| Vector encDataRefs = doEncryption(document, this.symmetricKey, |
| references); |
| Element referenceList = dataRef; |
| if (referenceList == null) { |
| referenceList = document.createElementNS(WSConstants.ENC_NS, |
| WSConstants.ENC_PREFIX + ":ReferenceList"); |
| } |
| createDataRefList(document, referenceList, encDataRefs); |
| return referenceList; |
| } |
| |
| /** |
| * Encrypt one or more parts or elements of the message (external). |
| * |
| * This method takes a vector of <code>WSEncryptionPart</code> object that |
| * contain information about the elements to encrypt. The method call the |
| * encryption method, takes the reference information generated during |
| * encryption and add this to the <code>xenc:Reference</code> element. |
| * This method can be called after <code>prepare()</code> and can be |
| * called multiple times to encrypt a number of parts or elements. |
| * |
| * </p> |
| * |
| * The method generates a <code>xenc:Reference</code> element that <i>must</i> |
| * be added to the SecurityHeader. See <code>addExternalRefElement()</code>. |
| * |
| * </p> |
| * |
| * If the <code>dataRef</code> parameter is <code>null</code> the method |
| * creates and initializes a new Reference element. |
| * |
| * @param dataRef |
| * A <code>xenc:Reference</code> element or <code>null</code> |
| * @param references |
| * A vector containing WSEncryptionPart objects |
| * @return Returns the updated <code>xenc:Reference</code> element |
| * @throws WSSecurityException |
| */ |
| public Element encryptForExternalRef(Element dataRef, Vector references) |
| throws WSSecurityException { |
| |
| Vector encDataRefs = doEncryption(document, this.symmetricKey, |
| references); |
| Element referenceList = dataRef; |
| if (referenceList == null) { |
| referenceList = document.createElementNS(WSConstants.ENC_NS, |
| WSConstants.ENC_PREFIX + ":ReferenceList"); |
| } |
| createDataRefList(document, referenceList, encDataRefs); |
| return referenceList; |
| } |
| |
| /** |
| * Adds the internal Reference element to this Encrypt data. |
| * |
| * The reference element <i>must</i> be created by the |
| * <code>encryptForInternalRef()</code> method. The reference element is |
| * added to the <code>EncryptedKey</code> element of this encrypt block. |
| * |
| * @param dataRef |
| * The internal <code>enc:Reference</code> element |
| */ |
| public void addInternalRefElement(Element dataRef) { |
| WSSecurityUtil.appendChildElement(document, encryptedKeyElement, dataRef); |
| } |
| |
| /** |
| * Adds (prepends) the external Reference element to the Security header. |
| * |
| * The reference element <i>must</i> be created by the |
| * <code>encryptForExternalRef() </code> method. The method prepends the |
| * reference element in the SecurityHeader. |
| * |
| * @param dataRef |
| * The external <code>enc:Reference</code> element |
| * @param secHeader |
| * The security header. |
| */ |
| public void addExternalRefElement(Element dataRef, WSSecHeader secHeader) { |
| WSSecurityUtil.prependChildElement(document, secHeader |
| .getSecurityHeader(), dataRef, false); |
| } |
| |
| private Vector doEncryption(Document doc, SecretKey secretKey, |
| Vector references) throws WSSecurityException { |
| |
| KeyInfo keyInfo = null; |
| |
| // Prepare KeyInfo if useKeyIdentifier is set |
| if (useKeyIdentifier && |
| keyIdentifierType == WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER) { |
| keyInfo = new KeyInfo(document); |
| SecurityTokenReference secToken = new SecurityTokenReference(document); |
| if(this.customReferenceValue != null) { |
| secToken.setKeyIdentifierEncKeySHA1(this.customReferenceValue); |
| } else { |
| secToken.setKeyIdentifierEncKeySHA1(getSHA1(encryptedEphemeralKey)); |
| } |
| |
| keyInfo.addUnknownElement(secToken.getElement()); |
| Element keyInfoElement = keyInfo.getElement(); |
| keyInfoElement.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" |
| + WSConstants.SIG_PREFIX, WSConstants.SIG_NS); |
| } |
| |
| return doEncryption(doc, secretKey, keyInfo, references); |
| } |
| |
| private Vector doEncryption(Document doc, SecretKey secretKey, |
| KeyInfo keyInfo, Vector references) throws WSSecurityException { |
| |
| XMLCipher xmlCipher = null; |
| try { |
| xmlCipher = XMLCipher.getInstance(symEncAlgo); |
| } catch (XMLEncryptionException e3) { |
| throw new WSSecurityException( |
| WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e3); |
| } |
| |
| Vector encDataRef = new Vector(); |
| |
| boolean cloneKeyInfo = false; |
| for (int part = 0; part < references.size(); part++) { |
| WSEncryptionPart encPart = (WSEncryptionPart) references.get(part); |
| |
| String idToEnc = encPart.getId(); |
| |
| String elemName = encPart.getName(); |
| String nmSpace = encPart.getNamespace(); |
| String modifier = encPart.getEncModifier(); |
| /* |
| * Third step: get the data to encrypt. |
| * |
| */ |
| Element body = null; |
| if (idToEnc != null) { |
| body = WSSecurityUtil.findElementById(document |
| .getDocumentElement(), idToEnc, WSConstants.WSU_NS); |
| if (body == null) { |
| body = WSSecurityUtil.findElementById(document |
| .getDocumentElement(), idToEnc, null); |
| } |
| } else { |
| body = (Element) WSSecurityUtil.findElement(document, elemName, |
| nmSpace); |
| } |
| if (body == null) { |
| throw new WSSecurityException(WSSecurityException.FAILURE, |
| "noEncElement", new Object[] { "{" + nmSpace + "}" |
| + elemName }); |
| } |
| |
| boolean content = modifier.equals("Content") ? true : false; |
| String xencEncryptedDataId = "EncDataId-" + body.hashCode(); |
| encPart.setEncId(xencEncryptedDataId); |
| |
| cloneKeyInfo = true; |
| |
| if(keyInfo == null) { |
| keyInfo = new KeyInfo(document); |
| SecurityTokenReference secToken = new SecurityTokenReference(document); |
| Reference ref = new Reference(document); |
| ref.setURI("#" + encKeyId); |
| secToken.setReference(ref); |
| keyInfo.addUnknownElement(secToken.getElement()); |
| Element keyInfoElement = keyInfo.getElement(); |
| keyInfoElement.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" |
| + WSConstants.SIG_PREFIX, WSConstants.SIG_NS); |
| } |
| /* |
| * Forth step: encrypt data, and set necessary attributes in |
| * xenc:EncryptedData |
| */ |
| try { |
| |
| if (modifier.equals("Header")) { |
| |
| Element elem = doc.createElementNS(WSConstants.WSSE11_NS,"wsse11:"+WSConstants.ENCRYPTED_HEADER); |
| WSSecurityUtil.setNamespace(elem, WSConstants.WSSE11_NS, WSConstants.WSSE11_PREFIX); |
| String wsuPrefix = WSSecurityUtil.setNamespace(elem, |
| WSConstants.WSU_NS, WSConstants.WSU_PREFIX); |
| elem.setAttributeNS(WSConstants.WSU_NS, wsuPrefix + ":Id", "EncHeader-" + body.hashCode()); |
| |
| |
| NamedNodeMap map = body.getAttributes(); |
| |
| for (int i = 0 ; i < map.getLength() ; i++) { |
| Attr attr = (Attr)map.item(i); |
| if (attr.getNamespaceURI().equals(WSConstants.URI_SOAP11_ENV) |
| || attr.getNamespaceURI().equals(WSConstants.URI_SOAP12_ENV)) { |
| String soapEnvPrefix = WSSecurityUtil.setNamespace(elem, |
| attr.getNamespaceURI(), "soapevn"); |
| elem.setAttributeNS(attr.getNamespaceURI(), soapEnvPrefix +":"+attr.getLocalName(), attr.getValue()); |
| } |
| } |
| |
| xmlCipher.init(XMLCipher.ENCRYPT_MODE, secretKey); |
| EncryptedData encData = xmlCipher.getEncryptedData(); |
| encData.setId(xencEncryptedDataId); |
| encData.setKeyInfo(keyInfo); |
| xmlCipher.doFinal(doc, body, content); |
| |
| Element encDataElem = WSSecurityUtil.findElementById(document |
| .getDocumentElement(), xencEncryptedDataId, null); |
| Node clone = encDataElem.cloneNode(true); |
| elem.appendChild(clone); |
| encDataElem.getParentNode().appendChild(elem); |
| encDataElem.getParentNode().removeChild(encDataElem); |
| |
| } else { |
| xmlCipher.init(XMLCipher.ENCRYPT_MODE, secretKey); |
| EncryptedData encData = xmlCipher.getEncryptedData(); |
| encData.setId(xencEncryptedDataId); |
| encData.setKeyInfo(keyInfo); |
| xmlCipher.doFinal(doc, body, content); |
| } |
| if(cloneKeyInfo) { |
| keyInfo = new KeyInfo((Element) keyInfo.getElement() |
| .cloneNode(true), null); |
| } |
| } catch (Exception e2) { |
| throw new WSSecurityException( |
| WSSecurityException.FAILED_ENCRYPTION, null, null, e2); |
| } |
| encDataRef.add(new String("#" + xencEncryptedDataId)); |
| } |
| return encDataRef; |
| } |
| |
| private Document buildEmbedded(Document doc, WSSecHeader secHeader) |
| throws WSSecurityException { |
| doDebug = log.isDebugEnabled(); |
| |
| if (doDebug) { |
| log.debug("Beginning Encryption embedded..."); |
| } |
| envelope = doc.getDocumentElement(); |
| envelope.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" |
| + WSConstants.ENC_PREFIX, WSConstants.ENC_NS); |
| |
| /* |
| * Second step: generate a symmetric key from the specified key |
| * (password) for this algorithm, and set the cipher into encryption |
| * mode. |
| */ |
| if (this.symmetricKey == null) { |
| if (embeddedKey == null) { |
| throw new WSSecurityException(WSSecurityException.FAILURE, |
| "noKeySupplied"); |
| } |
| this.symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo, |
| embeddedKey); |
| } |
| |
| KeyInfo keyInfo = null; |
| if (this.keyIdentifierType == WSConstants.EMBEDDED_KEYNAME) { |
| keyInfo = new KeyInfo(doc); |
| keyInfo |
| .addKeyName(embeddedKeyName == null ? user |
| : embeddedKeyName); |
| } else if (this.keyIdentifierType == WSConstants.EMBED_SECURITY_TOKEN_REF) { |
| /* |
| * This means that we want to embed a <wsse:SecurityTokenReference> |
| * into keyInfo element. If we need this functionality, this.secRef |
| * MUST be set before calling the build(doc, crypto) method. So if |
| * secRef is null then throw an exception. |
| */ |
| if (this.securityTokenReference == null) { |
| throw new WSSecurityException( |
| WSSecurityException.SECURITY_TOKEN_UNAVAILABLE, |
| "You must set keyInfo element, if the keyIdentifier " |
| + "== EMBED_SECURITY_TOKEN_REF"); |
| } else { |
| keyInfo = new KeyInfo(doc); |
| Element tmpE = securityTokenReference.getElement(); |
| tmpE.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" |
| + tmpE.getPrefix(), tmpE.getNamespaceURI()); |
| keyInfo.addUnknownElement(securityTokenReference.getElement()); |
| } |
| } |
| Element keyInfoElement = keyInfo.getElement(); |
| keyInfoElement.setAttributeNS(WSConstants.XMLNS_NS, "xmlns:" |
| + WSConstants.SIG_PREFIX, WSConstants.SIG_NS); |
| |
| SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope); |
| if (parts == null) { |
| parts = new Vector(); |
| WSEncryptionPart encP = new WSEncryptionPart(soapConstants |
| .getBodyQName().getLocalPart(), soapConstants |
| .getEnvelopeURI(), "Content"); |
| parts.add(encP); |
| } |
| Vector encDataRefs = doEncryption(doc, this.symmetricKey, keyInfo, |
| parts); |
| |
| /* |
| * At this point data is encrypted with the symmetric key and can be |
| * referenced via the above Id |
| */ |
| |
| /* |
| * Now we need to setup the wsse:Security header block 1) get (or |
| * create) the wsse:Security header block 2) The last step sets up the |
| * reference list that pints to the encrypted data |
| */ |
| Element wsseSecurity = secHeader.getSecurityHeader(); |
| |
| Element referenceList = doc.createElementNS(WSConstants.ENC_NS, |
| WSConstants.ENC_PREFIX + ":ReferenceList"); |
| referenceList = createDataRefList(doc, referenceList, encDataRefs); |
| WSSecurityUtil.prependChildElement(doc, wsseSecurity, referenceList, |
| true); |
| |
| return doc; |
| } |
| |
| private KeyGenerator getKeyGenerator() throws WSSecurityException { |
| KeyGenerator keyGen = null; |
| try { |
| /* |
| * Assume AES as default, so initialize it |
| */ |
| keyGen = KeyGenerator.getInstance("AES"); |
| if (symEncAlgo.equalsIgnoreCase(WSConstants.TRIPLE_DES)) { |
| keyGen = KeyGenerator.getInstance("DESede"); |
| } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_128)) { |
| keyGen.init(128); |
| } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_192)) { |
| keyGen.init(192); |
| } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_256)) { |
| keyGen.init(256); |
| } else { |
| return null; |
| } |
| } catch (NoSuchAlgorithmException e) { |
| throw new WSSecurityException( |
| WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e); |
| } |
| return keyGen; |
| } |
| |
| /** |
| * Create DOM subtree for <code>xenc:EncryptedKey</code> |
| * |
| * @param doc |
| * the SOAP envelope parent document |
| * @param referenceList |
| * @param encDataRefs |
| * @return an <code>xenc:EncryptedKey</code> element |
| */ |
| |
| public static Element createDataRefList(Document doc, |
| Element referenceList, Vector encDataRefs) { |
| for (int i = 0; i < encDataRefs.size(); i++) { |
| String dataReferenceUri = (String) encDataRefs.get(i); |
| Element dataReference = doc.createElementNS(WSConstants.ENC_NS, |
| WSConstants.ENC_PREFIX + ":DataReference"); |
| dataReference.setAttributeNS(null, "URI", dataReferenceUri); |
| referenceList.appendChild(dataReference); |
| } |
| return referenceList; |
| } |
| |
| /** |
| * @return The symmetric key |
| */ |
| public SecretKey getSymmetricKey() { |
| return symmetricKey; |
| } |
| |
| /** |
| * Set the symmetric key to be used for encryption |
| * |
| * @param key |
| */ |
| public void setSymmetricKey(SecretKey key) { |
| this.symmetricKey = key; |
| } |
| |
| /** |
| * @return Return the SecurityTokenRefernce |
| */ |
| public SecurityTokenReference getSecurityTokenReference() { |
| return securityTokenReference; |
| } |
| |
| /** |
| * @param reference |
| */ |
| public void setSecurityTokenReference(SecurityTokenReference reference) { |
| securityTokenReference = reference; |
| } |
| |
| public boolean isEncryptSymmKey() { |
| return encryptSymmKey; |
| } |
| |
| public void setEncryptSymmKey(boolean encryptSymmKey) { |
| this.encryptSymmKey = encryptSymmKey; |
| } |
| |
| private String getSHA1(byte[] input) throws WSSecurityException { |
| try { |
| MessageDigest sha = null; |
| sha = MessageDigest.getInstance("SHA-1"); |
| sha.reset(); |
| sha.update(input); |
| byte[] data = sha.digest(); |
| |
| return Base64.encode(data); |
| } catch (NoSuchAlgorithmException e) { |
| throw new WSSecurityException( |
| WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e); |
| } |
| } |
| |
| public void setCustomReferenceValue(String customReferenceValue) { |
| this.customReferenceValue = customReferenceValue; |
| } |
| |
| } |