View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.ws.security.message;
21  
22  import java.security.InvalidAlgorithmParameterException;
23  import java.security.InvalidKeyException;
24  import java.security.NoSuchAlgorithmException;
25  import java.security.cert.X509Certificate;
26  import java.security.spec.MGF1ParameterSpec;
27  
28  import javax.crypto.Cipher;
29  import javax.crypto.IllegalBlockSizeException;
30  import javax.crypto.KeyGenerator;
31  import javax.crypto.SecretKey;
32  import javax.crypto.spec.OAEPParameterSpec;
33  import javax.crypto.spec.PSource;
34  
35  import org.apache.ws.security.WSConstants;
36  import org.apache.ws.security.WSSConfig;
37  import org.apache.ws.security.WSSecurityException;
38  import org.apache.ws.security.components.crypto.Crypto;
39  import org.apache.ws.security.components.crypto.CryptoType;
40  import org.apache.ws.security.message.token.BinarySecurity;
41  import org.apache.ws.security.message.token.DOMX509Data;
42  import org.apache.ws.security.message.token.DOMX509IssuerSerial;
43  import org.apache.ws.security.message.token.Reference;
44  import org.apache.ws.security.message.token.SecurityTokenReference;
45  import org.apache.ws.security.message.token.X509Security;
46  import org.apache.ws.security.util.UUIDGenerator;
47  import org.apache.ws.security.util.WSSecurityUtil;
48  import org.apache.xml.security.algorithms.JCEMapper;
49  import org.apache.xml.security.utils.Constants;
50  import org.apache.xml.security.utils.XMLUtils;
51  
52  import org.w3c.dom.Document;
53  import org.w3c.dom.Element;
54  import org.w3c.dom.Text;
55  
56  /**
57   * Builder class to build an EncryptedKey.
58   * 
59   * This is especially useful in the case where the same
60   * <code>EncryptedKey</code> has to be used to sign and encrypt the message In
61   * such a situation this builder will add the <code>EncryptedKey</code> to the
62   * security header and we can use the information form the builder to provide to
63   * other builders to reference to the token
64   */
65  public class WSSecEncryptedKey extends WSSecBase {
66  
67      private static org.apache.commons.logging.Log log = 
68          org.apache.commons.logging.LogFactory.getLog(WSSecEncryptedKey.class);
69  
70      protected Document document;
71  
72      /**
73       * soap:Envelope element
74       */
75      protected Element envelope = null;
76  
77      /**
78       * Session key used as the secret in key derivation
79       */
80      protected byte[] ephemeralKey;
81      
82      /**
83       * Symmetric key used in the EncryptedKey.
84       */
85      protected SecretKey symmetricKey = null;
86  
87      /**
88       * Encrypted bytes of the ephemeral key
89       */
90      protected byte[] encryptedEphemeralKey;
91      
92      /**
93       * Remote user's alias to obtain the cert to encrypt the ephemeral key
94       */
95      protected String encrUser = null;
96  
97      /**
98       * Algorithm used to encrypt the ephemeral key
99       */
100     protected String keyEncAlgo = WSConstants.KEYTRANSPORT_RSAOEP;
101     
102     /**
103      * Algorithm to be used with the ephemeral key
104      */
105     protected String symEncAlgo = WSConstants.AES_128;
106     
107     /**
108      * Digest Algorithm to be used with RSA-OAEP. The default is SHA-1 (which is not
109      * written out unless it is explicitly configured).
110      */
111     protected String digestAlgo = null;
112 
113     /**
114      * xenc:EncryptedKey element
115      */
116     protected Element encryptedKeyElement = null;
117 
118     /**
119      * The Token identifier of the token that the <code>DerivedKeyToken</code>
120      * is (or to be) derived from.
121      */
122     protected String encKeyId = null;
123 
124     /**
125      * Custom token value
126      */
127     protected String customEKTokenValueType;
128     
129     /**
130      * Custom token id
131      */
132     protected String customEKTokenId;
133     
134     /**
135      * BinarySecurityToken to be included in the case where BST_DIRECT_REFERENCE
136      * is used to refer to the asymmetric encryption cert
137      */
138     protected BinarySecurity bstToken = null;
139     
140     protected X509Certificate useThisCert = null;
141     
142     public WSSecEncryptedKey() {
143         super();
144     }
145     
146     public WSSecEncryptedKey(WSSConfig config) {
147         super(config);
148     }
149 
150     /**
151      * Set the user name to get the encryption certificate.
152      * 
153      * The public key of this certificate is used, thus no password necessary.
154      * The user name is a keystore alias usually.
155      * 
156      * @param user
157      */
158     public void setUserInfo(String user) {
159         this.user = user;
160     }
161 
162     /**
163      * Get the id generated during <code>prepare()</code>.
164      * 
165      * Returns the the value of wsu:Id attribute of the EncryptedKey element.
166      * 
167      * @return Return the wsu:Id of this token or null if <code>prepare()</code>
168      *         was not called before.
169      */
170     public String getId() {
171         return encKeyId;
172     }
173 
174     /**
175      * Prepare the ephemeralKey and the tokens required to be added to the
176      * security header
177      * 
178      * @param doc The SOAP envelope as <code>Document</code>
179      * @param crypto An instance of the Crypto API to handle keystore and certificates
180      * @throws WSSecurityException
181      */
182     public void prepare(Document doc, Crypto crypto) throws WSSecurityException {
183 
184         document = doc;
185 
186         //
187         // Set up the ephemeral key
188         //
189         if (ephemeralKey == null) {
190             if (symmetricKey == null) {
191                 KeyGenerator keyGen = getKeyGenerator();
192                 symmetricKey = keyGen.generateKey();
193             } 
194             ephemeralKey = symmetricKey.getEncoded();
195         }
196         
197         if (symmetricKey == null) {
198             symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo, ephemeralKey);
199         }
200 
201         //
202         // Get the certificate that contains the public key for the public key
203         // algorithm that will encrypt the generated symmetric (session) key.
204         //
205         X509Certificate remoteCert = useThisCert;
206         if (remoteCert == null) {
207             CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
208             cryptoType.setAlias(user);
209             X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
210             if (certs == null || certs.length <= 0) {
211                 throw new WSSecurityException(
212                     WSSecurityException.FAILURE,
213                     "noUserCertsFound", 
214                     new Object[] {user, "encryption"}
215                 );
216             }
217             remoteCert = certs[0];
218         }
219         
220         prepareInternal(symmetricKey, remoteCert, crypto);
221     }
222 
223     /**
224      * Encrypt the symmetric key data and prepare the EncryptedKey element
225      * 
226      * This method does the most work for to prepare the EncryptedKey element.
227      * It is also used by the WSSecEncrypt sub-class.
228      * 
229      * @param secretKey The symmetric key
230      * @param remoteCert The certificate that contains the public key to encrypt the
231      *                   symmetric key data
232      * @param crypto An instance of the Crypto API to handle keystore and certificates
233      * @throws WSSecurityException
234      */
235     protected void prepareInternal(
236         SecretKey secretKey, 
237         X509Certificate remoteCert,
238         Crypto crypto
239     ) throws WSSecurityException {
240         Cipher cipher = WSSecurityUtil.getCipherInstance(keyEncAlgo);
241         try {
242             OAEPParameterSpec oaepParameterSpec = null;
243             if (WSConstants.KEYTRANSPORT_RSAOEP.equals(keyEncAlgo)) {
244                 String jceDigestAlgorithm = "SHA-1";
245                 if (digestAlgo != null) {
246                     jceDigestAlgorithm = JCEMapper.translateURItoJCEID(digestAlgo);
247                 }
248                 
249                 oaepParameterSpec = 
250                     new OAEPParameterSpec(
251                         jceDigestAlgorithm, "MGF1", new MGF1ParameterSpec("SHA-1"), PSource.PSpecified.DEFAULT
252                     );
253             }
254             if (oaepParameterSpec == null) {
255                 cipher.init(Cipher.WRAP_MODE, remoteCert);
256             } else {
257                 cipher.init(Cipher.WRAP_MODE, remoteCert.getPublicKey(), oaepParameterSpec);
258             }
259         } catch (InvalidKeyException e) {
260             throw new WSSecurityException(
261                 WSSecurityException.FAILED_ENCRYPTION, null, null, e
262             );
263         } catch (InvalidAlgorithmParameterException e) {
264             throw new WSSecurityException(
265                 WSSecurityException.FAILED_ENCRYPTION, null, null, e
266             );
267         }
268         int blockSize = cipher.getBlockSize();
269         if (doDebug) {
270             log.debug(
271                 "cipher blksize: " + blockSize + ", symm key: " + secretKey.toString()
272             );
273         }
274         
275         try {
276             encryptedEphemeralKey = cipher.wrap(secretKey);
277         } catch (IllegalStateException ex) {
278             throw new WSSecurityException(
279                 WSSecurityException.FAILED_ENCRYPTION, null, null, ex
280             );
281         } catch (IllegalBlockSizeException ex) {
282             throw new WSSecurityException(
283                 WSSecurityException.FAILED_ENCRYPTION, null, null, ex
284             );
285         } catch (InvalidKeyException ex) {
286             throw new WSSecurityException(
287                 WSSecurityException.FAILED_ENCRYPTION, null, null, ex
288             );
289         }
290         Text keyText = 
291             WSSecurityUtil.createBase64EncodedTextNode(document, encryptedEphemeralKey);
292 
293         //
294         // Now we need to setup the EncryptedKey header block 1) create a
295         // EncryptedKey element and set a wsu:Id for it 2) Generate ds:KeyInfo
296         // element, this wraps the wsse:SecurityTokenReference 3) Create and set
297         // up the SecurityTokenReference according to the keyIdentifier parameter
298         // 4) Create the CipherValue element structure and insert the encrypted
299         // session key
300         //
301         encryptedKeyElement = createEncryptedKey(document, keyEncAlgo);
302         if (encKeyId == null || "".equals(encKeyId)) {
303             encKeyId = "EK-" + UUIDGenerator.getUUID();
304         }
305         encryptedKeyElement.setAttributeNS(null, "Id", encKeyId);
306 
307         SecurityTokenReference secToken = new SecurityTokenReference(document);
308 
309         switch (keyIdentifierType) {
310         case WSConstants.X509_KEY_IDENTIFIER:
311             secToken.setKeyIdentifier(remoteCert);
312             break;
313 
314         case WSConstants.SKI_KEY_IDENTIFIER:
315             secToken.setKeyIdentifierSKI(remoteCert, crypto);
316             break;
317 
318         case WSConstants.THUMBPRINT_IDENTIFIER:
319         case WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER:
320             //
321             // This identifier is not applicable for this case, so fall back to
322             // ThumbprintRSA.
323             //
324             secToken.setKeyIdentifierThumb(remoteCert);
325             break;
326 
327         case WSConstants.ISSUER_SERIAL:
328             String issuer = remoteCert.getIssuerX500Principal().getName();
329             java.math.BigInteger serialNumber = remoteCert.getSerialNumber();
330             DOMX509IssuerSerial domIssuerSerial = 
331                 new DOMX509IssuerSerial(
332                     document, issuer, serialNumber
333                 );
334             DOMX509Data domX509Data = new DOMX509Data(document, domIssuerSerial);
335             secToken.setX509Data(domX509Data);
336             break;
337 
338         case WSConstants.BST_DIRECT_REFERENCE:
339             Reference ref = new Reference(document);
340             String certUri = UUIDGenerator.getUUID();
341             ref.setURI("#" + certUri);
342             bstToken = new X509Security(document);
343             ((X509Security) bstToken).setX509Certificate(remoteCert);
344             bstToken.setID(certUri);
345             ref.setValueType(bstToken.getValueType());
346             secToken.setReference(ref);
347             break;
348             
349         case WSConstants.CUSTOM_SYMM_SIGNING :
350             Reference refCust = new Reference(document);
351             if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
352                 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
353                 refCust.setValueType(customEKTokenValueType);
354             } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
355                 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
356             } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
357                 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
358                 refCust.setValueType(customEKTokenValueType);
359             } else {
360                 refCust.setValueType(customEKTokenValueType);
361             }
362             refCust.setURI("#" + customEKTokenId);
363             secToken.setReference(refCust);
364             break;
365             
366         case WSConstants.CUSTOM_SYMM_SIGNING_DIRECT :
367             Reference refCustd = new Reference(document);
368             if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
369                 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
370                 refCustd.setValueType(customEKTokenValueType);
371             } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
372                 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
373             }  else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
374                 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
375                 refCustd.setValueType(customEKTokenValueType);
376             } else {
377                 refCustd.setValueType(customEKTokenValueType);
378             }
379             refCustd.setURI(customEKTokenId);
380             secToken.setReference(refCustd);
381             break;
382             
383         case WSConstants.CUSTOM_KEY_IDENTIFIER:
384             secToken.setKeyIdentifier(customEKTokenValueType, customEKTokenId);
385             if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
386                 secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
387             } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
388                 secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
389             } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
390                 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
391             } else if (SecurityTokenReference.ENC_KEY_SHA1_URI.equals(customEKTokenValueType)) {
392                 secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
393             }
394             break;           
395 
396         default:
397             throw new WSSecurityException(WSSecurityException.FAILURE, "unsupportedKeyId");
398         }
399         Element keyInfoElement = 
400             document.createElementNS(
401                 WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
402             );
403         keyInfoElement.setAttributeNS(
404             WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
405         );
406         keyInfoElement.appendChild(secToken.getElement());
407         encryptedKeyElement.appendChild(keyInfoElement);
408 
409         Element xencCipherValue = createCipherValue(document, encryptedKeyElement);
410         xencCipherValue.appendChild(keyText);
411 
412         envelope = document.getDocumentElement();
413     }
414 
415     protected KeyGenerator getKeyGenerator() throws WSSecurityException {
416         try {
417             //
418             // Assume AES as default, so initialize it
419             //
420             String keyAlgorithm = JCEMapper.getJCEKeyAlgorithmFromURI(symEncAlgo);
421             if (keyAlgorithm == null || "".equals(keyAlgorithm)) {
422                 keyAlgorithm = JCEMapper.translateURItoJCEID(symEncAlgo);
423             }
424             KeyGenerator keyGen = KeyGenerator.getInstance(keyAlgorithm);
425             if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_128)
426                 || symEncAlgo.equalsIgnoreCase(WSConstants.AES_128_GCM)) {
427                 keyGen.init(128);
428             } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_192)
429                 || symEncAlgo.equalsIgnoreCase(WSConstants.AES_192_GCM)) {
430                 keyGen.init(192);
431             } else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_256)
432                 || symEncAlgo.equalsIgnoreCase(WSConstants.AES_256_GCM)) {
433                 keyGen.init(256);
434             }
435             return keyGen;
436         } catch (NoSuchAlgorithmException e) {
437             throw new WSSecurityException(
438                 WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e
439             );
440         }
441     }
442 
443     /**
444      * Create DOM subtree for <code>xenc:EncryptedKey</code>
445      * 
446      * @param doc the SOAP envelope parent document
447      * @param keyTransportAlgo specifies which algorithm to use to encrypt the symmetric key
448      * @return an <code>xenc:EncryptedKey</code> element
449      */
450     protected Element createEncryptedKey(Document doc, String keyTransportAlgo) {
451         Element encryptedKey = 
452             doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":EncryptedKey");
453 
454         WSSecurityUtil.setNamespace(encryptedKey, WSConstants.ENC_NS, WSConstants.ENC_PREFIX);
455         Element encryptionMethod = 
456             doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":EncryptionMethod");
457         encryptionMethod.setAttributeNS(null, "Algorithm", keyTransportAlgo);
458         
459         if (digestAlgo != null) {
460             Element digestElement = 
461                 XMLUtils.createElementInSignatureSpace(doc, Constants._TAG_DIGESTMETHOD);
462             digestElement.setAttributeNS(null, "Algorithm", digestAlgo);
463             encryptionMethod.appendChild(digestElement);
464         }
465         
466         encryptedKey.appendChild(encryptionMethod);
467         return encryptedKey;
468     }
469     
470     protected Element createCipherValue(Document doc, Element encryptedKey) {
471         Element cipherData = 
472             doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":CipherData");
473         Element cipherValue = 
474             doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":CipherValue");
475         cipherData.appendChild(cipherValue);
476         encryptedKey.appendChild(cipherData);
477         return cipherValue;
478     }
479 
480     /**
481      * Prepend the EncryptedKey element to the elements already in the Security
482      * header.
483      * 
484      * The method can be called any time after <code>prepare()</code>. This
485      * allows to insert the EncryptedKey element at any position in the Security
486      * header.
487      * 
488      * @param secHeader The security header that holds the Signature element.
489      */
490     public void prependToHeader(WSSecHeader secHeader) {
491         WSSecurityUtil.prependChildElement(secHeader.getSecurityHeader(), encryptedKeyElement);
492     }
493 
494     /**
495      * Append the EncryptedKey element to the elements already in the Security
496      * header.
497      * 
498      * The method can be called any time after <code>prepare()</code>. This
499      * allows to insert the EncryptedKey element at any position in the Security
500      * header.
501      * 
502      * @param secHeader The security header that holds the Signature element.
503      */
504     public void appendToHeader(WSSecHeader secHeader) {
505         Element secHeaderElement = secHeader.getSecurityHeader();
506         secHeaderElement.appendChild(encryptedKeyElement);
507     }
508     
509     /**
510      * Prepend the BinarySecurityToken to the elements already in the Security
511      * header.
512      * 
513      * The method can be called any time after <code>prepare()</code>. This
514      * allows to insert the BST element at any position in the Security header.
515      * 
516      * @param secHeader The security header that holds the BST element.
517      */
518     public void prependBSTElementToHeader(WSSecHeader secHeader) {
519         if (bstToken != null) {
520             WSSecurityUtil.prependChildElement(
521                 secHeader.getSecurityHeader(), bstToken.getElement()
522             );
523         }
524         bstToken = null;
525     }
526 
527     /**
528      * Append the BinarySecurityToken to the elements already in the Security
529      * header.
530      * 
531      * The method can be called any time after <code>prepare()</code>. This
532      * allows to insert the BST element at any position in the Security header.
533      * 
534      * @param secHeader The security header that holds the BST element.
535      */
536     public void appendBSTElementToHeader(WSSecHeader secHeader) {
537         if (bstToken != null) {
538             Element secHeaderElement = secHeader.getSecurityHeader();
539             secHeaderElement.appendChild(bstToken.getElement());
540         }
541         bstToken = null;
542     }
543     
544     /**
545      * @return Returns the ephemeralKey.
546      */
547     public byte[] getEphemeralKey() {
548         return ephemeralKey;
549     }
550     
551     /**
552      * Set the X509 Certificate to use for encryption.
553      * 
554      * If this is set <b>and</b> the key identifier is set to
555      * <code>DirectReference</code> then use this certificate to get the
556      * public key for encryption.
557      * 
558      * @param cert is the X509 certificate to use for encryption
559      */
560     public void setUseThisCert(X509Certificate cert) {
561         useThisCert = cert;
562     }
563 
564     /**
565      * @return Returns the encryptedKeyElement.
566      */
567     public Element getEncryptedKeyElement() {
568         return encryptedKeyElement;
569     }
570     
571     /**
572      * Set the encrypted key element when a pre prepared encrypted key is used
573      * @param encryptedKeyElement EncryptedKey element of the encrypted key used
574      */
575     public void setEncryptedKeyElement(Element encryptedKeyElement) {
576         this.encryptedKeyElement = encryptedKeyElement;
577     }
578     
579     /**
580      * @return Returns the BinarySecurityToken element.
581      */
582     public Element getBinarySecurityTokenElement() {
583         if (bstToken != null) {
584             return bstToken.getElement();
585         }
586         return null;
587     }
588     
589     public void setKeyEncAlgo(String keyEncAlgo) {
590         this.keyEncAlgo = keyEncAlgo;
591     }
592 
593     /**
594      * @param ephemeralKey The ephemeralKey to set.
595      */
596     public void setEphemeralKey(byte[] ephemeralKey) {
597         this.ephemeralKey = ephemeralKey;
598     }
599     
600     /**
601      * Get the id of the BSt generated  during <code>prepare()</code>.
602      * 
603      * @return Returns the the value of wsu:Id attribute of the 
604      * BinaruSecurityToken element.
605      */
606     public String getBSTTokenId() {
607         if (bstToken == null) {
608             return null;
609         }
610         
611         return bstToken.getID();
612     }
613 
614     /**
615      * @param document The document to set.
616      */
617     public void setDocument(Document document) {
618         this.document = document;
619     }
620 
621     /**
622      * @param encKeyId The encKeyId to set.
623      */
624     public void setEncKeyId(String encKeyId) {
625         this.encKeyId = encKeyId;
626     }
627     
628     public boolean isCertSet() {
629         if (useThisCert == null) {
630             return false;
631         }
632         return true;
633     }
634 
635     public byte[] getEncryptedEphemeralKey() {
636         return encryptedEphemeralKey;
637     }
638     
639     public void setCustomEKTokenValueType(String customEKTokenValueType) {
640         this.customEKTokenValueType = customEKTokenValueType;
641     }
642 
643     public void setCustomEKTokenId(String customEKTokenId) {
644         this.customEKTokenId = customEKTokenId;
645     }
646     
647     /**
648      * Set the name of the symmetric encryption algorithm to use.
649      * 
650      * This encryption algorithm is used to encrypt the data. If the algorithm
651      * is not set then AES128 is used. Refer to WSConstants which algorithms are
652      * supported.
653      * 
654      * @param algo Is the name of the encryption algorithm
655      * @see WSConstants#TRIPLE_DES
656      * @see WSConstants#AES_128
657      * @see WSConstants#AES_192
658      * @see WSConstants#AES_256
659      */
660     public void setSymmetricEncAlgorithm(String algo) {
661         symEncAlgo = algo;
662     }
663 
664     
665     /**
666      * Get the name of symmetric encryption algorithm to use.
667      * 
668      * The name of the encryption algorithm to encrypt the data, i.e. the SOAP
669      * Body. Refer to WSConstants which algorithms are supported.
670      * 
671      * @return the name of the currently selected symmetric encryption algorithm
672      * @see WSConstants#TRIPLE_DES
673      * @see WSConstants#AES_128
674      * @see WSConstants#AES_192
675      * @see WSConstants#AES_256
676      */
677     public String getSymmetricEncAlgorithm() {
678         return symEncAlgo;
679     }
680     
681     /**
682      * Set the digest algorithm to use with the RSA-OAEP key transport algorithm. The
683      * default is SHA-1.
684      * 
685      * @param digestAlgorithm the digest algorithm to use with the RSA-OAEP key transport algorithm
686      */
687     public void setDigestAlgorithm(String digestAlgorithm) {
688         this.digestAlgo = digestAlgorithm;
689     }
690     
691     /**
692      * Get the digest algorithm to use with the RSA-OAEP key transport algorithm. The
693      * default is SHA-1.
694      */
695     public String getDigestAlgorithm() {
696         return digestAlgo;
697     }
698     
699     /**
700      * @return The symmetric key
701      */
702     public SecretKey getSymmetricKey() {
703         return symmetricKey;
704     }
705 
706     /**
707      * Set the symmetric key to be used for encryption
708      * 
709      * @param key
710      */
711     public void setSymmetricKey(SecretKey key) {
712         this.symmetricKey = key;
713     }
714 
715 
716 }