[maven-release-plugin] copy for tag wss4j-2.1.5
diff --git a/bindings/pom.xml b/bindings/pom.xml
index ae3415d..4c26598 100644
--- a/bindings/pom.xml
+++ b/bindings/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.wss4j</groupId>
         <artifactId>wss4j-parent</artifactId>
-        <version>2.2.0-SNAPSHOT</version>
+        <version>2.1.5</version>
         <relativePath>../parent/pom.xml</relativePath>
     </parent>
     <modelVersion>4.0.0</modelVersion>
diff --git a/integration/pom.xml b/integration/pom.xml
index 5c70ddb..6209eb3 100644
--- a/integration/pom.xml
+++ b/integration/pom.xml
@@ -23,7 +23,7 @@
         <groupId>org.apache.wss4j</groupId>
         <artifactId>wss4j-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>2.2.0-SNAPSHOT</version>
+        <version>2.1.5</version>
     </parent>
     <artifactId>wss4j-integration</artifactId>
     <name>Apache WSS4J WS-Security Integration</name>
diff --git a/parent/pom.xml b/parent/pom.xml
index a2464d0..2253dae 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.wss4j</groupId>
         <artifactId>wss4j</artifactId>
-        <version>2.2.0-SNAPSHOT</version>
+        <version>2.1.5</version>
     </parent>
     <artifactId>wss4j-parent</artifactId>
     <packaging>pom</packaging>
diff --git a/policy/pom.xml b/policy/pom.xml
index 3336cea..2a4ef8b 100644
--- a/policy/pom.xml
+++ b/policy/pom.xml
@@ -24,7 +24,7 @@
         <groupId>org.apache.wss4j</groupId>
         <artifactId>wss4j-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>2.2.0-SNAPSHOT</version>
+        <version>2.1.5</version>
     </parent>
     <artifactId>wss4j-policy</artifactId>
     <name>Apache WSS4J WS-SecurityPolicy model</name>
diff --git a/pom.xml b/pom.xml
index bf44894..bf0b652 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
 
     <groupId>org.apache.wss4j</groupId>
     <artifactId>wss4j</artifactId>
-    <version>2.2.0-SNAPSHOT</version>
+    <version>2.1.5</version>
     <packaging>pom</packaging>
     <name>Apache WSS4J</name>
     <description>
@@ -79,12 +79,12 @@
     </licenses>
     <scm>
         <connection>
-            scm:svn:http://svn.apache.org/repos/asf/webservices/wss4j/trunk/
+            scm:svn:http://svn.apache.org/repos/asf/webservices/wss4j/tags/wss4j-2.1.5
         </connection>
         <developerConnection>
-            scm:svn:https://svn.apache.org/repos/asf/webservices/wss4j/trunk/
+            scm:svn:https://svn.apache.org/repos/asf/webservices/wss4j/tags/wss4j-2.1.5
         </developerConnection>
-        <url>http://svn.apache.org/repos/asf/webservices/wss4j/trunk</url>
+        <url>http://svn.apache.org/repos/asf/webservices/wss4j/tags/wss4j-2.1.5</url>
     </scm>
     <organization>
         <name>The Apache Software Foundation</name>
@@ -108,7 +108,7 @@
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <targetJdk>1.8</targetJdk>
+        <targetJdk>1.7</targetJdk>
         <buildtools.dir>${basedir}/build-tools</buildtools.dir>
     </properties>
 
diff --git a/src/site/xdoc/config.xml b/src/site/xdoc/config.xml
index 917f960..e4d3708 100644
--- a/src/site/xdoc/config.xml
+++ b/src/site/xdoc/config.xml
@@ -114,10 +114,6 @@
 <td>${PREFIX}.merlin.truststore.type</td>
 <td>The truststore type. Defaults to: java.security.KeyStore.getDefaultType().</td>
 </tr>
-<tr>
-<td>${PREFIX}.merlin.truststore.provider</td>
-<td><b>WSS4J 2.1.5</b> The provider used to load truststores. By default it's the same as the keystore provider. Set to an empty value to force use of the JRE's default provider.</td>
-</tr>
 </table>
  
 </subsection>
diff --git a/ws-security-common/pom.xml b/ws-security-common/pom.xml
index 182dcea..ee53aaf 100644
--- a/ws-security-common/pom.xml
+++ b/ws-security-common/pom.xml
@@ -23,7 +23,7 @@
         <groupId>org.apache.wss4j</groupId>
         <artifactId>wss4j-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>2.2.0-SNAPSHOT</version>
+        <version>2.1.5</version>
     </parent>
     <artifactId>wss4j-ws-security-common</artifactId>
     <name>Apache WSS4J WS-Security Common</name>
@@ -145,6 +145,17 @@
             <scope>compile</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.directory.server</groupId>
+            <artifactId>apacheds-kerberos-codec</artifactId>
+            <optional>true</optional>
+            <exclusions>
+                <exclusion>
+                    <groupId>net.sf.ehcache</groupId>
+                    <artifactId>ehcache-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
             <groupId>net.sf.ehcache</groupId>
             <artifactId>ehcache</artifactId>
             <scope>compile</scope>
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Crypto.java b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Crypto.java
index e15ce17..394d369 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Crypto.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/Crypto.java
@@ -181,18 +181,6 @@
     ) throws WSSecurityException;
     
     /**
-     * Gets the private key corresponding to the given PublicKey.
-     *
-     * @param publicKey The PublicKey corresponding to the private key
-     * @param callbackHandler The callbackHandler needed to get the password
-     * @return The private key
-     */
-    PrivateKey getPrivateKey(
-        PublicKey publicKey,
-        CallbackHandler callbackHandler
-    ) throws WSSecurityException;
-
-    /**
      * Gets the private key corresponding to the identifier.
      *
      * @param identifier The implementation-specific identifier corresponding to the key
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/WSProviderConfig.java b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/WSProviderConfig.java
index 071de03..e82af0c 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/WSProviderConfig.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/crypto/WSProviderConfig.java
@@ -67,6 +67,16 @@
                 AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                     public Boolean run() {
                         addXMLDSigRIInternal();
+                        String bcProviderStr =
+                            addJceProvider("BC", "org.bouncycastle.jce.provider.BouncyCastleProvider");
+                        // If we have BouncyCastle v1.49 installed then use IvParameterSpec in
+                        // Santuario. This can be removed when we pick up BouncyCastle 1.51+
+                        if (bcProviderStr != null) {
+                            Provider bcProvider = Security.getProvider(bcProviderStr);
+                            if (bcProvider.getVersion() < 1.50) {
+                                useIvParameterSpec();
+                            }
+                        }
                         return true;
                     }
                 });
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosClientAction.java b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosClientAction.java
new file mode 100644
index 0000000..780d72b
--- /dev/null
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosClientAction.java
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.wss4j.common.kerberos;
+
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+/**
+ * This class represents a PrivilegedAction implementation to obtain a service ticket from a Kerberos
+ * Key Distribution Center.
+ */
+public class KerberosClientAction implements PrivilegedAction<byte[]> {
+    private static final org.slf4j.Logger LOG =
+        org.slf4j.LoggerFactory.getLogger(KerberosClientAction.class);
+
+    private Principal clientPrincipal;
+    private String serviceName;
+    private boolean isUsernameServiceNameForm;
+
+    public KerberosClientAction(Principal clientPrincipal, String serviceName) {
+        this(clientPrincipal, serviceName, false);
+    }
+
+    public KerberosClientAction(Principal clientPrincipal, String serviceName, boolean isUsernameServiceNameForm) {
+        this.clientPrincipal = clientPrincipal;
+        this.serviceName = serviceName;
+        this.isUsernameServiceNameForm = isUsernameServiceNameForm;
+    }
+
+    public byte[] run() {
+        try {
+            KerberosContext krbCtx =
+                (KerberosContext)new KerberosClientExceptionAction(clientPrincipal, serviceName,
+                                                                   isUsernameServiceNameForm, false).run();
+            return krbCtx.getKerberosToken();
+        } catch (Exception e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Error in obtaining a Kerberos token", e);
+            }
+        }
+
+        return null;
+
+    }
+
+}
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosClientExceptionAction.java b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosClientExceptionAction.java
index 3a88939..f59e938 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosClientExceptionAction.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosClientExceptionAction.java
@@ -39,7 +39,11 @@
  * Key Distribution Center.
  */
 public class KerberosClientExceptionAction implements PrivilegedExceptionAction<KerberosContext> {
-    private static final boolean IS_IBM_VENDOR = System.getProperty("java.vendor").startsWith("IBM");
+    private static final String JAVA_VERSION = System.getProperty("java.version");
+    private static final boolean IS_JAVA_5_OR_6 = JAVA_VERSION.startsWith("1.5") || JAVA_VERSION.startsWith("1.6");
+    private static final boolean IS_ORACLE_JAVA_VENDOR = System.getProperty("java.vendor").startsWith("Oracle");
+    private static final boolean IS_IBM_JAVA_VENDOR = System.getProperty("java.vendor").startsWith("IBM");
+    private static final boolean IS_HP_JAVA_VENDOR = System.getProperty("java.vendor").startsWith("Hewlett-Packard");
 
     private static final String SUN_JGSS_INQUIRE_TYPE_CLASS = "com.sun.security.jgss.InquireType";
     private static final String SUN_JGSS_EXT_GSSCTX_CLASS = "com.sun.security.jgss.ExtendedGSSContext";
@@ -113,27 +117,27 @@
         krbCtx.setGssContext(secContext);
         krbCtx.setKerberosToken(returnedToken);
 
-        try {
-            @SuppressWarnings("rawtypes")
-            Class inquireType = Class.forName(IS_IBM_VENDOR ? IBM_JGSS_INQUIRE_TYPE_CLASS 
-                : SUN_JGSS_INQUIRE_TYPE_CLASS);
+        if (!IS_JAVA_5_OR_6 && (IS_ORACLE_JAVA_VENDOR || IS_IBM_JAVA_VENDOR  || IS_HP_JAVA_VENDOR)) {
+            try {
+                @SuppressWarnings("rawtypes")
+                Class inquireType = Class.forName(IS_IBM_JAVA_VENDOR ? IBM_JGSS_INQUIRE_TYPE_CLASS : SUN_JGSS_INQUIRE_TYPE_CLASS);
 
-            @SuppressWarnings("rawtypes")
-            Class extendedGSSContext = Class.forName(IS_IBM_VENDOR ? IBM_JGSS_EXT_GSSCTX_CLASS 
-                : SUN_JGSS_EXT_GSSCTX_CLASS);
+                @SuppressWarnings("rawtypes")
+                Class extendedGSSContext = Class.forName(IS_IBM_JAVA_VENDOR ? IBM_JGSS_EXT_GSSCTX_CLASS : SUN_JGSS_EXT_GSSCTX_CLASS);
 
-            @SuppressWarnings("unchecked")
-            Method inquireSecContext = extendedGSSContext.getMethod("inquireSecContext", inquireType);
+                @SuppressWarnings("unchecked")
+                Method inquireSecContext = extendedGSSContext.getMethod("inquireSecContext", inquireType);
 
-            @SuppressWarnings("unchecked")
-            Key key = (Key) inquireSecContext.invoke(secContext, Enum.valueOf(inquireType, "KRB5_GET_SESSION_KEY"));
+                @SuppressWarnings("unchecked")
+                Key key = (Key) inquireSecContext.invoke(secContext, Enum.valueOf(inquireType, "KRB5_GET_SESSION_KEY"));
 
-            krbCtx.setSecretKey(key);
-        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
-            | InvocationTargetException e) {
-            throw new WSSecurityException(
-                ErrorCode.FAILURE, e, "kerberosServiceTicketError"
-            );
+                krbCtx.setSecretKey(key);
+            } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
+                | InvocationTargetException e) {
+                throw new WSSecurityException(
+                    ErrorCode.FAILURE, e, "kerberosServiceTicketError"
+                );
+            }
         }
 
         return krbCtx;
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosServiceAction.java b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosServiceAction.java
new file mode 100644
index 0000000..2d72af3
--- /dev/null
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosServiceAction.java
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.wss4j.common.kerberos;
+
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+/**
+ * This class represents a PrivilegedAction implementation to validate a received ticket to a KDC.
+ */
+public class KerberosServiceAction implements PrivilegedAction<Principal> {
+    private static final org.slf4j.Logger LOG =
+            org.slf4j.LoggerFactory.getLogger(KerberosServiceAction.class);
+
+    private byte[] ticket;
+    private String serviceName;
+    private boolean isUsernameServiceNameForm;
+
+    public KerberosServiceAction(byte[] ticket, String serviceName) {
+        this(ticket, serviceName, false);
+    }
+
+    public KerberosServiceAction(byte[] ticket, String serviceName, boolean isUsernameServiceNameForm) {
+        this.ticket = ticket;
+        this.serviceName = serviceName;
+        this.isUsernameServiceNameForm = isUsernameServiceNameForm;
+    }
+
+    public Principal run() {
+        try {
+            KerberosServiceExceptionAction action =
+                new KerberosServiceExceptionAction(this.ticket, this.serviceName,
+                                                   this.isUsernameServiceNameForm, false);
+            KerberosServiceContext krbServiceCtx = action.run();
+            return krbServiceCtx.getPrincipal();
+        } catch (Exception e) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Error in validating a Kerberos token", e);
+            }
+        }
+
+        return null;
+
+    }
+
+}
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosServiceExceptionAction.java b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosServiceExceptionAction.java
index e7a1055..7d7264c 100644
--- a/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosServiceExceptionAction.java
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosServiceExceptionAction.java
@@ -37,7 +37,11 @@
 
 public class KerberosServiceExceptionAction implements PrivilegedExceptionAction<KerberosServiceContext> {
 
-    private static final boolean IS_IBM_VENDOR = System.getProperty("java.vendor").startsWith("IBM");
+    private static final String JAVA_VERSION = System.getProperty("java.version");
+    private static final boolean IS_JAVA_5_OR_6 = JAVA_VERSION.startsWith("1.5") || JAVA_VERSION.startsWith("1.6");
+    private static final boolean IS_ORACLE_JAVA_VENDOR = System.getProperty("java.vendor").startsWith("Oracle");
+    private static final boolean IS_IBM_JAVA_VENDOR = System.getProperty("java.vendor").startsWith("IBM");
+    private static final boolean IS_HP_JAVA_VENDOR = System.getProperty("java.vendor").startsWith("Hewlett-Packard");
 
     private static final String SUN_JGSS_INQUIRE_TYPE_CLASS = "com.sun.security.jgss.InquireType";
     private static final String SUN_JGSS_EXT_GSSCTX_CLASS = "com.sun.security.jgss.ExtendedGSSContext";
@@ -105,29 +109,29 @@
             krbServiceCtx.setGssContext(secContext);
             krbServiceCtx.setKerberosToken(returnedToken);
 
-            try {
-                @SuppressWarnings("rawtypes")
-                Class inquireType = Class.forName(IS_IBM_VENDOR ? IBM_JGSS_INQUIRE_TYPE_CLASS 
-                    : SUN_JGSS_INQUIRE_TYPE_CLASS);
+            if (!IS_JAVA_5_OR_6 && (IS_ORACLE_JAVA_VENDOR || IS_IBM_JAVA_VENDOR || IS_HP_JAVA_VENDOR)) {
+                try {
+                    @SuppressWarnings("rawtypes")
+                    Class inquireType = Class.forName(IS_IBM_JAVA_VENDOR ? IBM_JGSS_INQUIRE_TYPE_CLASS : SUN_JGSS_INQUIRE_TYPE_CLASS);
 
-                @SuppressWarnings("rawtypes")
-                Class extendedGSSContext = Class.forName(IS_IBM_VENDOR ? IBM_JGSS_EXT_GSSCTX_CLASS 
-                    : SUN_JGSS_EXT_GSSCTX_CLASS);
+                    @SuppressWarnings("rawtypes")
+                    Class extendedGSSContext = Class.forName(IS_IBM_JAVA_VENDOR ? IBM_JGSS_EXT_GSSCTX_CLASS : SUN_JGSS_EXT_GSSCTX_CLASS);
 
-                @SuppressWarnings("unchecked")
-                Method inquireSecContext = 
-                extendedGSSContext.getMethod(EXTENDED_JGSS_CONTEXT_INQUIRE_SEC_CONTEXT_METHOD_NAME, inquireType);
+                    @SuppressWarnings("unchecked")
+                    Method inquireSecContext = 
+                        extendedGSSContext.getMethod(EXTENDED_JGSS_CONTEXT_INQUIRE_SEC_CONTEXT_METHOD_NAME, inquireType);
 
-                @SuppressWarnings("unchecked")
-                Object obj = Enum.valueOf(inquireType, EXTENDED_JGSS_CONTEXT_INQUIRE_TYPE_KRB5_GET_SESSION_KEY);
-                Key key = (Key) inquireSecContext.invoke(secContext, obj);
+                    @SuppressWarnings("unchecked")
+                    Object args = Enum.valueOf(inquireType, EXTENDED_JGSS_CONTEXT_INQUIRE_TYPE_KRB5_GET_SESSION_KEY);
+                    Key key = (Key) inquireSecContext.invoke(secContext, args);
 
-                krbServiceCtx.setSessionKey(key);
-            } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
-                | InvocationTargetException e) {
-                throw new WSSecurityException(
-                    ErrorCode.FAILURE, e, KERBEROS_TICKET_VALIDATION_ERROR_MSG_ID
-                );
+                    krbServiceCtx.setSessionKey(key);
+                } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
+                    | InvocationTargetException e) {
+                    throw new WSSecurityException(
+                        ErrorCode.FAILURE, e, KERBEROS_TICKET_VALIDATION_ERROR_MSG_ID
+                    );
+                }
             }
         } finally {
             if (null != secContext && !spnego) {
diff --git a/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosTokenDecoderImpl.java b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosTokenDecoderImpl.java
new file mode 100644
index 0000000..4e9bd65
--- /dev/null
+++ b/ws-security-common/src/main/java/org/apache/wss4j/common/kerberos/KerberosTokenDecoderImpl.java
@@ -0,0 +1,185 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.wss4j.common.kerberos;
+
+import org.apache.directory.shared.kerberos.codec.KerberosDecoder;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
+import org.apache.directory.shared.kerberos.components.EncTicketPart;
+import org.apache.directory.shared.kerberos.components.EncryptionKey;
+import org.apache.directory.shared.kerberos.exceptions.KerberosException;
+import org.apache.directory.shared.kerberos.messages.ApReq;
+import org.apache.directory.server.kerberos.shared.crypto.encryption.CipherTextHandler;
+import org.apache.directory.server.kerberos.shared.crypto.encryption.KeyUsage;
+
+import javax.security.auth.Subject;
+import javax.security.auth.kerberos.KerberosKey;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Set;
+
+public class KerberosTokenDecoderImpl implements KerberosTokenDecoder {
+
+    private static final String KERBEROS_OID = "1.2.840.113554.1.2.2";
+
+    private byte[] serviceTicket;
+    private Subject subject;
+
+    private boolean decoded = false;
+    private EncTicketPart encTicketPart;
+
+    /**
+     * Clear all internal information
+     */
+    public void clear() {
+        serviceTicket = null;
+        subject = null;
+        decoded = false;
+        encTicketPart = null;
+    }
+
+    /**
+     * Set the AP-REQ Kerberos Token
+     *
+     * @param token the AP-REQ Kerberos Token
+     */
+    public void setToken(byte[] token) {
+        serviceTicket = token;
+    }
+
+    /**
+     * Set the Subject
+     *
+     * @param subject the Subject
+     */
+    public void setSubject(Subject subject) {
+        this.subject = subject;
+    }
+
+    /**
+     * Get the session key from the token
+     *
+     * @return the session key from the token
+     */
+    public byte[] getSessionKey() throws KerberosTokenDecoderException {
+        if (!decoded) {
+            decodeServiceTicket();
+        }
+        if (encTicketPart != null && encTicketPart.getKey() != null) {
+            return encTicketPart.getKey().getKeyValue();
+        }
+        return null;
+    }
+
+    /**
+     * Get the client principal name from the decoded service ticket.
+     *
+     * @return the client principal name
+     */
+    public String getClientPrincipalName() throws KerberosTokenDecoderException {
+        if (!decoded) {
+            decodeServiceTicket();
+        }
+        return encTicketPart.getCName().toString();
+    }
+
+    // Decode the service ticket.
+    private synchronized void decodeServiceTicket() throws KerberosTokenDecoderException {
+        parseServiceTicket(serviceTicket);
+        decoded = true;
+    }
+
+    // Parses the service ticket (GSS AP-REQ token)
+    private void parseServiceTicket(byte[] ticket) throws KerberosTokenDecoderException {
+        try {
+            // I didn't find a better way how to parse this Kerberos Message...
+            org.bouncycastle.asn1.ASN1InputStream asn1InputStream =
+                    new org.bouncycastle.asn1.ASN1InputStream(new ByteArrayInputStream(ticket));
+            org.bouncycastle.asn1.DERApplicationSpecific derToken =
+                    (org.bouncycastle.asn1.DERApplicationSpecific) asn1InputStream.readObject();
+            if (derToken == null || !derToken.isConstructed()) {
+                asn1InputStream.close();
+                throw new KerberosTokenDecoderException("invalid kerberos token");
+            }
+            asn1InputStream.close();
+
+            asn1InputStream = new org.bouncycastle.asn1.ASN1InputStream(new ByteArrayInputStream(derToken.getContents()));
+            org.bouncycastle.asn1.ASN1ObjectIdentifier kerberosOid =
+                    (org.bouncycastle.asn1.ASN1ObjectIdentifier) asn1InputStream.readObject();
+            if (!kerberosOid.getId().equals(KERBEROS_OID)) {
+                asn1InputStream.close();
+                throw new KerberosTokenDecoderException("invalid kerberos token");
+            }
+
+            int readLowByte = asn1InputStream.read() & 0xff;
+            int readHighByte = asn1InputStream.read() & 0xff;
+            int read = (readHighByte << 8) + readLowByte; //NOPMD
+            if (read != 0x01) {
+                throw new KerberosTokenDecoderException("invalid kerberos token");
+            }
+
+            ApReq applicationRequest =
+                KerberosDecoder.decodeApReq(toByteArray(asn1InputStream));
+
+            final int encryptionType = applicationRequest.getTicket().getEncPart().getEType().getValue();
+            KerberosKey kerberosKey = getKrbKey(subject, encryptionType);
+
+            EncryptionKey encryptionKey =
+                    new EncryptionKey(EncryptionType.getTypeByValue(encryptionType), kerberosKey.getEncoded());
+
+            CipherTextHandler cipherTextHandler = new CipherTextHandler();
+            byte[] dec = cipherTextHandler.decrypt(
+                         encryptionKey, applicationRequest.getTicket().getEncPart(),
+                                                      KeyUsage.getTypeByOrdinal(2));
+
+            this.encTicketPart = KerberosDecoder.decodeEncTicketPart(dec);
+        } catch (KerberosException | IOException e) {
+            throw new KerberosTokenDecoderException(e);
+        }
+    }
+
+    private KerberosKey getKrbKey(Subject sub, int keyType) {
+        Set<Object> creds = sub.getPrivateCredentials(Object.class);
+        for (Iterator<Object> i = creds.iterator(); i.hasNext();) {
+            Object cred = i.next();
+            if (cred instanceof KerberosKey) {
+                KerberosKey key = (KerberosKey) cred;
+                if (key.getKeyType() == keyType) {
+                    return (KerberosKey) cred;
+                }
+            }
+        }
+        return null;
+    }
+
+    private static byte[] toByteArray(InputStream inputStream) throws IOException {
+        try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
+            int read;
+            byte[] buf = new byte[1024];
+            while ((read = inputStream.read(buf)) != -1) {
+                byteArrayOutputStream.write(buf, 0, read);
+            }
+            return byteArrayOutputStream.toByteArray();
+        }
+    }
+}
diff --git a/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/SKITest.java b/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/SKITest.java
index 5158204..325b494 100644
--- a/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/SKITest.java
+++ b/ws-security-common/src/test/java/org/apache/wss4j/common/crypto/SKITest.java
@@ -21,12 +21,10 @@
 
 import java.io.InputStream;
 import java.security.KeyStore;
-import java.security.Security;
 import java.security.cert.X509Certificate;
 
 import org.apache.wss4j.common.util.Loader;
 import org.apache.xml.security.utils.Base64;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.junit.Test;
 
 /**
@@ -80,14 +78,8 @@
 
     @Test
     public void testBouncyCastlePKCS12() throws Exception {
-        try {
-            Security.addProvider(new BouncyCastleProvider());
-
-            // Load the keystore
-            Crypto crypto = CryptoFactory.getInstance("alice_bouncycastle.properties");
-            assertNotNull(crypto);
-        } finally {
-            Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
-        }
+        // Load the keystore
+        Crypto crypto = CryptoFactory.getInstance("alice_bouncycastle.properties");
+        assertNotNull(crypto);
     }
 }
diff --git a/ws-security-dom/pom.xml b/ws-security-dom/pom.xml
index 15458e2..cfd0731 100644
--- a/ws-security-dom/pom.xml
+++ b/ws-security-dom/pom.xml
@@ -23,7 +23,7 @@
         <groupId>org.apache.wss4j</groupId>
         <artifactId>wss4j-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>2.2.0-SNAPSHOT</version>
+        <version>2.1.5</version>
     </parent>
     <artifactId>wss4j-ws-security-dom</artifactId>
     <name>Apache WSS4J DOM WS-Security</name>
diff --git a/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java b/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
index 242bf21..6183767 100644
--- a/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
+++ b/ws-security-dom/src/main/java/org/apache/wss4j/dom/processor/EncryptedKeyProcessor.java
@@ -47,6 +47,7 @@
 import org.apache.wss4j.common.crypto.AlgorithmSuite;
 import org.apache.wss4j.common.crypto.AlgorithmSuiteValidator;
 import org.apache.wss4j.common.crypto.CryptoType;
+import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.token.DOMX509IssuerSerial;
 import org.apache.wss4j.common.token.SecurityTokenReference;
@@ -252,8 +253,10 @@
         try {
             if (certs != null) {
                 return data.getDecCrypto().getPrivateKey(certs[0], data.getCallbackHandler());
+            } else if (data.getDecCrypto() instanceof Merlin) {
+                return ((Merlin)data.getDecCrypto()).getPrivateKey(publicKey, data.getCallbackHandler());
             }
-            return data.getDecCrypto().getPrivateKey(publicKey, data.getCallbackHandler());
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK);
         } catch (WSSecurityException ex) {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILED_CHECK, ex);
         }
diff --git a/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/KerberosTokenValidator.java b/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/KerberosTokenValidator.java
index c3ed126..161be17 100644
--- a/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/KerberosTokenValidator.java
+++ b/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/KerberosTokenValidator.java
@@ -35,6 +35,7 @@
 import org.apache.wss4j.common.kerberos.KerberosServiceExceptionAction;
 import org.apache.wss4j.common.kerberos.KerberosTokenDecoder;
 import org.apache.wss4j.common.kerberos.KerberosTokenDecoderException;
+import org.apache.wss4j.common.kerberos.KerberosTokenDecoderImpl;
 import org.apache.wss4j.common.token.BinarySecurity;
 import org.apache.wss4j.dom.handler.RequestData;
 import org.apache.wss4j.dom.message.token.KerberosSecurity;
@@ -223,7 +224,12 @@
 
         // Otherwise, try to extract the session key from the token if a KerberosTokenDecoder implementation is
         // available
-        if (null == credential.getSecretKey() && kerberosTokenDecoder != null) {
+        if (null == credential.getSecretKey()) {
+            KerberosTokenDecoder kerberosTokenDecoder = this.kerberosTokenDecoder;
+            if (kerberosTokenDecoder == null) {
+                kerberosTokenDecoder = new KerberosTokenDecoderImpl();
+            }
+
             LOG.debug("KerberosTokenDecoder is set.Trying to obtain the session key from it.");
             kerberosTokenDecoder.clear();
             kerberosTokenDecoder.setToken(token);
diff --git a/ws-security-dom/src/test/java/org/apache/wss4j/dom/components/crypto/CryptoProviderTest.java b/ws-security-dom/src/test/java/org/apache/wss4j/dom/components/crypto/CryptoProviderTest.java
index a1711e2..c503762 100644
--- a/ws-security-dom/src/test/java/org/apache/wss4j/dom/components/crypto/CryptoProviderTest.java
+++ b/ws-security-dom/src/test/java/org/apache/wss4j/dom/components/crypto/CryptoProviderTest.java
@@ -32,7 +32,6 @@
 import org.apache.wss4j.dom.message.WSSecHeader;
 import org.apache.wss4j.dom.message.WSSecSignature;
 import org.apache.xml.security.utils.Base64;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.junit.Test;
 import org.w3c.dom.Document;
 
@@ -41,7 +40,6 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.security.Security;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 
@@ -182,32 +180,26 @@
                 + "UyZ50HRroKJx1PPCE+OTO5JYPNQB2rauK63RHGGC94mY2ySCE2KP/yaWhkDJ60X2JKgnTLKUZxLP"
                 + "9IioeHVeUzGIccIicoiZR5kqaiqoEk82V81R+VA="
             );
+        CertificateFactory factory =
+            CertificateFactory.getInstance("X.509", "BC");
+        X509Certificate cert =
+            (X509Certificate)factory.generateCertificate(
+                new ByteArrayInputStream(certBytes)
+            );
 
-        try {
-            Security.addProvider(new BouncyCastleProvider());
-            CertificateFactory factory =
-                CertificateFactory.getInstance("X.509", "BC");
-            X509Certificate cert =
-                (X509Certificate)factory.generateCertificate(
-                    new ByteArrayInputStream(certBytes)
-                );
+        WSSecEncrypt encrypt = new WSSecEncrypt();
+        encrypt.setUseThisCert(cert);
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader(doc);
+        secHeader.insertSecurityHeader();
+        Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
 
-            WSSecEncrypt encrypt = new WSSecEncrypt();
-            encrypt.setUseThisCert(cert);
-            Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
-            WSSecHeader secHeader = new WSSecHeader(doc);
-            secHeader.insertSecurityHeader();
-            Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
-
-            if (LOG.isDebugEnabled()) {
-                String outputString =
-                    XMLUtils.prettyDocumentToString(encryptedDoc);
-                LOG.debug(outputString);
-            }
-            verify(encryptedDoc);
-        } finally {
-            Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
+        if (LOG.isDebugEnabled()) {
+            String outputString =
+                XMLUtils.prettyDocumentToString(encryptedDoc);
+            LOG.debug(outputString);
         }
+        verify(encryptedDoc);
 
     }
 
@@ -237,37 +229,32 @@
                 + "HapMIIWiJRclIAiA8Hnb0Sv/puuHYD4G4NWFdiVjRord90eZJe40NMGruRmlqIRIGGKCv+wv3E6U"
                 + "x1cWW862f5H9Eyrcocke2P+3GNAGy83vghA="
             );
+        CertificateFactory factory =
+            CertificateFactory.getInstance("X.509", "BC");
+        X509Certificate cert =
+            (X509Certificate)factory.generateCertificate(
+                new ByteArrayInputStream(certBytes)
+            );
 
-        try {
-            Security.addProvider(new BouncyCastleProvider());
-            CertificateFactory factory =
-                CertificateFactory.getInstance("X.509", "BC");
-            X509Certificate cert =
-                (X509Certificate)factory.generateCertificate(
-                    new ByteArrayInputStream(certBytes)
-                );
+        WSSecEncrypt encrypt = new WSSecEncrypt();
+        encrypt.setUseThisCert(cert);
+        Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
+        WSSecHeader secHeader = new WSSecHeader(doc);
+        secHeader.insertSecurityHeader();
+        Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
 
-            WSSecEncrypt encrypt = new WSSecEncrypt();
-            encrypt.setUseThisCert(cert);
-            Document doc = SOAPUtil.toSOAPPart(SOAPUtil.SAMPLE_SOAP_MSG);
-            WSSecHeader secHeader = new WSSecHeader(doc);
-            secHeader.insertSecurityHeader();
-            Document encryptedDoc = encrypt.build(doc, crypto, secHeader);
-
-            if (LOG.isDebugEnabled()) {
-                String outputString =
-                    XMLUtils.prettyDocumentToString(encryptedDoc);
-                LOG.debug(outputString);
-            }
-            try {
-                verify(encryptedDoc);
-                fail("Failure expected on encryption with a key that does not exist in the keystore");
-            } catch (WSSecurityException ex) {
-                assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
-            }
-        } finally {
-            Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
+        if (LOG.isDebugEnabled()) {
+            String outputString =
+                XMLUtils.prettyDocumentToString(encryptedDoc);
+            LOG.debug(outputString);
         }
+        try {
+            verify(encryptedDoc);
+            fail("Failure expected on encryption with a key that does not exist in the keystore");
+        } catch (WSSecurityException ex) {
+            assertTrue(ex.getErrorCode() == WSSecurityException.ErrorCode.FAILURE);
+        }
+
     }
 
     /**
diff --git a/ws-security-policy-stax/pom.xml b/ws-security-policy-stax/pom.xml
index a6500ad..eed03ef 100644
--- a/ws-security-policy-stax/pom.xml
+++ b/ws-security-policy-stax/pom.xml
@@ -24,7 +24,7 @@
         <groupId>org.apache.wss4j</groupId>
         <artifactId>wss4j-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>2.2.0-SNAPSHOT</version>
+        <version>2.1.5</version>
     </parent>
     <artifactId>wss4j-ws-security-policy-stax</artifactId>
     <name>Apache WSS4J Streaming WS-SecurityPolicy</name>
diff --git a/ws-security-stax/pom.xml b/ws-security-stax/pom.xml
index f0a4c49..3ecaab4 100644
--- a/ws-security-stax/pom.xml
+++ b/ws-security-stax/pom.xml
@@ -24,7 +24,7 @@
         <groupId>org.apache.wss4j</groupId>
         <artifactId>wss4j-parent</artifactId>
         <relativePath>../parent/pom.xml</relativePath>
-        <version>2.2.0-SNAPSHOT</version>
+        <version>2.1.5</version>
     </parent>
     <artifactId>wss4j-ws-security-stax</artifactId>
     <name>Apache WSS4J Streaming WS-Security</name>
diff --git a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/DsaKeyValueSecurityTokenImpl.java b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/DsaKeyValueSecurityTokenImpl.java
index b162833..6fc3d80 100644
--- a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/DsaKeyValueSecurityTokenImpl.java
+++ b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/DsaKeyValueSecurityTokenImpl.java
@@ -26,6 +26,7 @@
 import javax.security.auth.callback.CallbackHandler;
 
 import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.principal.PublicKeyPrincipalImpl;
 import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
@@ -66,18 +67,21 @@
     @Override
     public Key getKey(String algorithmURI, XMLSecurityConstants.AlgorithmUsage algorithmUsage,
                       String correlationID) throws XMLSecurityException {
-        PublicKey publicKey = getPublicKey();
-        
-        try {
-            return crypto.getPrivateKey(publicKey, callbackHandler);
-        } catch (WSSecurityException ex) {
-            // Check to see if we are decrypting rather than signature verification
-            Crypto decCrypto = securityProperties.getDecryptionCrypto();
-            if (decCrypto != null && decCrypto != crypto) {
-                return decCrypto.getPrivateKey(publicKey, callbackHandler);
+        if (crypto instanceof Merlin) {
+            PublicKey publicKey = getPublicKey();
+            
+            try {
+                return ((Merlin)crypto).getPrivateKey(publicKey, callbackHandler);
+            } catch (WSSecurityException ex) {
+                // Check to see if we are decrypting rather than signature verification
+                Crypto decCrypto = securityProperties.getDecryptionCrypto();
+                if (decCrypto instanceof Merlin && decCrypto != crypto) {
+                    return ((Merlin)decCrypto).getPrivateKey(publicKey, callbackHandler);
+                }
+                throw ex;
             }
-            throw ex;
         }
+        return super.getKey(algorithmURI, algorithmUsage, correlationID);
     }
 
     @Override
diff --git a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/ECKeyValueSecurityTokenImpl.java b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/ECKeyValueSecurityTokenImpl.java
index 978ec36..1ba42f8 100644
--- a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/ECKeyValueSecurityTokenImpl.java
+++ b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/ECKeyValueSecurityTokenImpl.java
@@ -26,6 +26,7 @@
 import javax.security.auth.callback.CallbackHandler;
 
 import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.principal.PublicKeyPrincipalImpl;
 import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
@@ -67,18 +68,21 @@
     @Override
     public Key getKey(String algorithmURI, XMLSecurityConstants.AlgorithmUsage algorithmUsage,
                       String correlationID) throws XMLSecurityException {
-        PublicKey publicKey = getPublicKey();
-        
-        try {
-            return crypto.getPrivateKey(publicKey, callbackHandler);
-        } catch (WSSecurityException ex) {
-            // Check to see if we are decrypting rather than signature verification
-            Crypto decCrypto = securityProperties.getDecryptionCrypto();
-            if (decCrypto != null && decCrypto != crypto) {
-                return decCrypto.getPrivateKey(publicKey, callbackHandler);
+        if (crypto instanceof Merlin) {
+            PublicKey publicKey = getPublicKey();
+            
+            try {
+                return ((Merlin)crypto).getPrivateKey(publicKey, callbackHandler);
+            } catch (WSSecurityException ex) {
+                // Check to see if we are decrypting rather than signature verification
+                Crypto decCrypto = securityProperties.getDecryptionCrypto();
+                if (decCrypto instanceof Merlin && decCrypto != crypto) {
+                    return ((Merlin)decCrypto).getPrivateKey(publicKey, callbackHandler);
+                }
+                throw ex;
             }
-            throw ex;
         }
+        return super.getKey(algorithmURI, algorithmUsage, correlationID);
     }
 
     @Override
diff --git a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/KerberosServiceSecurityTokenImpl.java b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/KerberosServiceSecurityTokenImpl.java
index 9b13060..38fd939 100644
--- a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/KerberosServiceSecurityTokenImpl.java
+++ b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/KerberosServiceSecurityTokenImpl.java
@@ -38,6 +38,7 @@
 import org.apache.wss4j.common.kerberos.KerberosServiceExceptionAction;
 import org.apache.wss4j.common.kerberos.KerberosTokenDecoder;
 import org.apache.wss4j.common.kerberos.KerberosTokenDecoderException;
+import org.apache.wss4j.common.kerberos.KerberosTokenDecoderImpl;
 import org.apache.wss4j.common.util.KeyUtils;
 import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
 import org.apache.wss4j.stax.securityToken.KerberosServiceSecurityToken;
@@ -55,7 +56,6 @@
     private KerberosTokenDecoder kerberosTokenDecoder;
     private Subject subject;
     private Principal principal;
-    private byte[] sessionKey;
 
     public KerberosServiceSecurityTokenImpl(WSInboundSecurityContext wsInboundSecurityContext, CallbackHandler callbackHandler,
                                             byte[] binaryContent, String kerberosTokenValueType, String id,
@@ -76,10 +76,7 @@
         return WSSecurityTokenConstants.KERBEROS_TOKEN;
     }
 
-    protected byte[] getTGTSessionKey() throws WSSecurityException {
-        if (sessionKey != null) {
-            return sessionKey;
-        }
+    protected KerberosTokenDecoder getTGT() throws WSSecurityException {
         try {
             KerberosContextAndServiceNameCallback contextAndServiceNameCallback = new KerberosContextAndServiceNameCallback();
             callbackHandler.handle(new Callback[]{contextAndServiceNameCallback});
@@ -131,21 +128,25 @@
 
             this.principal = krbServiceCtx.getPrincipal();
 
-            Key key = krbServiceCtx.getSessionKey();
-            if (key != null) {
-                sessionKey = key.getEncoded();
-            } else if (kerberosTokenDecoder != null) {
-                kerberosTokenDecoder.clear();
+            final Key sessionKey = krbServiceCtx.getSessionKey();
+
+            if (null != sessionKey) {
+                return new KerberosTokenDecoder() {
+                    public void setToken(byte[] token) { }
+                    public void setSubject(Subject subject) { }
+                    public byte[] getSessionKey() throws KerberosTokenDecoderException {
+                        return sessionKey.getEncoded();
+                    }
+                    public void clear() { }
+                };
+            } else {
+                KerberosTokenDecoder kerberosTokenDecoder = new KerberosTokenDecoderImpl();
                 kerberosTokenDecoder.setToken(binaryContent);
                 kerberosTokenDecoder.setSubject(subject);
-                sessionKey = kerberosTokenDecoder.getSessionKey();
+                return kerberosTokenDecoder;
             }
-
-            return sessionKey;
         } catch (LoginException | UnsupportedCallbackException | IOException e) {
             throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
-        } catch (KerberosTokenDecoderException e) {
-            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, e);
         }
     }
 
@@ -158,7 +159,16 @@
             return key;
         }
 
-        byte[] sk = getTGTSessionKey();
+        if (this.kerberosTokenDecoder == null) {
+            this.kerberosTokenDecoder = getTGT();
+        }
+
+        byte[] sk;
+        try {
+            sk = this.kerberosTokenDecoder.getSessionKey();
+        } catch (KerberosTokenDecoderException e) {
+            throw new WSSecurityException(WSSecurityException.ErrorCode.INVALID_SECURITY_TOKEN, e);
+        }
 
         key = KeyUtils.prepareSecretKey(algorithmURI, sk);
         setSecretKey(algorithmURI, key);
diff --git a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/RsaKeyValueSecurityTokenImpl.java b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/RsaKeyValueSecurityTokenImpl.java
index 82ad3e9..aacf0cc 100644
--- a/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/RsaKeyValueSecurityTokenImpl.java
+++ b/ws-security-stax/src/main/java/org/apache/wss4j/stax/impl/securityToken/RsaKeyValueSecurityTokenImpl.java
@@ -26,6 +26,7 @@
 import javax.security.auth.callback.CallbackHandler;
 
 import org.apache.wss4j.common.crypto.Crypto;
+import org.apache.wss4j.common.crypto.Merlin;
 import org.apache.wss4j.common.ext.WSSecurityException;
 import org.apache.wss4j.common.principal.PublicKeyPrincipalImpl;
 import org.apache.wss4j.stax.ext.WSInboundSecurityContext;
@@ -66,18 +67,21 @@
     @Override
     public Key getKey(String algorithmURI, XMLSecurityConstants.AlgorithmUsage algorithmUsage,
                       String correlationID) throws XMLSecurityException {
-        PublicKey publicKey = getPublicKey();
-        
-        try {
-            return crypto.getPrivateKey(publicKey, callbackHandler);
-        } catch (WSSecurityException ex) {
-            // Check to see if we are decrypting rather than signature verification
-            Crypto decCrypto = securityProperties.getDecryptionCrypto();
-            if (decCrypto != null && decCrypto != crypto) {
-                return decCrypto.getPrivateKey(publicKey, callbackHandler);
+        if (crypto instanceof Merlin) {
+            PublicKey publicKey = getPublicKey();
+            
+            try {
+                return ((Merlin)crypto).getPrivateKey(publicKey, callbackHandler);
+            } catch (WSSecurityException ex) {
+                // Check to see if we are decrypting rather than signature verification
+                Crypto decCrypto = securityProperties.getDecryptionCrypto();
+                if (decCrypto instanceof Merlin && decCrypto != crypto) {
+                    return ((Merlin)decCrypto).getPrivateKey(publicKey, callbackHandler);
+                }
+                throw ex;
             }
-            throw ex;
         }
+        return super.getKey(algorithmURI, algorithmUsage, correlationID);
     }
 
     @Override
diff --git a/ws-security-stax/src/main/java/org/apache/wss4j/stax/utils/WSSUtils.java b/ws-security-stax/src/main/java/org/apache/wss4j/stax/utils/WSSUtils.java
index 26c7f0a..0e6a781 100644
--- a/ws-security-stax/src/main/java/org/apache/wss4j/stax/utils/WSSUtils.java
+++ b/ws-security-stax/src/main/java/org/apache/wss4j/stax/utils/WSSUtils.java
@@ -23,6 +23,7 @@
 import java.security.Key;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -257,12 +258,12 @@
                 abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, encodedCert);
             } else {
                 try {
-                    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+                    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC");
                     List<X509Certificate> certificates = Arrays.asList(x509Certificates);
                     String encodedCert = 
                         new Base64(76, new byte[]{'\n'}).encodeToString(certificateFactory.generateCertPath(certificates).getEncoded());
                     abstractOutputProcessor.createCharactersAndOutputAsEvent(outputProcessorChain, encodedCert);
-                } catch (CertificateException e) {
+                } catch (CertificateException | NoSuchProviderException e) {
                     throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e);
                 }
             }
diff --git a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/EncDecryptionTest.java b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/EncDecryptionTest.java
index bd22c2a..11c42d3 100644
--- a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/EncDecryptionTest.java
+++ b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/EncDecryptionTest.java
@@ -24,7 +24,6 @@
 import java.lang.reflect.Field;
 import java.nio.charset.StandardCharsets;
 import java.security.KeyStore;
-import java.security.Security;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -79,7 +78,6 @@
 import org.apache.xml.security.stax.securityEvent.SecurityEvent;
 import org.apache.xml.security.stax.securityEvent.SecurityEventConstants;
 import org.apache.xml.security.utils.Base64;
-import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.junit.Assert;
 import org.junit.Test;
 import org.w3c.dom.Document;
@@ -1828,61 +1826,56 @@
      */
     @Test
     public void testKeyWrappingRSAOAEPMGF1AESGCM128Outbound() throws Exception {
-        try {
-            Security.addProvider(new BouncyCastleProvider());
-            ByteArrayOutputStream baos;
-            {
-                WSSSecurityProperties securityProperties = new WSSSecurityProperties();
-                List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
-                actions.add(WSSConstants.ENCRYPT);
-                securityProperties.setActions(actions);
-                securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
-                securityProperties.setEncryptionUser("receiver");
-                securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes128-gcm");
-                securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
+        ByteArrayOutputStream baos;
+        {
+            WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+            List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
+            actions.add(WSSConstants.ENCRYPT);
+            securityProperties.setActions(actions);
+            securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
+            securityProperties.setEncryptionUser("receiver");
+            securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes128-gcm");
+            securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
 
-                InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-                baos = doOutboundSecurity(securityProperties, sourceDocument);
+            InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+            baos = doOutboundSecurity(securityProperties, sourceDocument);
 
-                Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
-                NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
-                Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
+            Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
+            NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
+            Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
 
-                XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
-                Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
+            Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
-                Assert.assertEquals(nodeList.getLength(), 1);
+            nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 1);
 
-                nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
-                Assert.assertEquals(nodeList.getLength(), 1);
+            nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 1);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes128-gcm']");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes128-gcm']");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                Assert.assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
-                NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
-                for (int i = 0; i < childNodes.getLength(); i++) {
-                    Node child = childNodes.item(i);
-                    if (child.getNodeType() == Node.TEXT_NODE) {
-                        Assert.assertEquals(child.getTextContent().trim(), "");
-                    } else if (child.getNodeType() == Node.ELEMENT_NODE) {
-                        Assert.assertEquals(child, nodeList.item(0));
-                    } else {
-                        Assert.fail("Unexpected Node encountered");
-                    }
+            Assert.assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
+            NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
+            for (int i = 0; i < childNodes.getLength(); i++) {
+                Node child = childNodes.item(i);
+                if (child.getNodeType() == Node.TEXT_NODE) {
+                    Assert.assertEquals(child.getTextContent().trim(), "");
+                } else if (child.getNodeType() == Node.ELEMENT_NODE) {
+                    Assert.assertEquals(child, nodeList.item(0));
+                } else {
+                    Assert.fail("Unexpected Node encountered");
                 }
             }
+        }
 
-            //done encryption; now test decryption:
-            {
-                String action = WSHandlerConstants.ENCRYPT;
-                doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
-            }
-        } finally {
-            Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
+        //done encryption; now test decryption:
+        {
+            String action = WSHandlerConstants.ENCRYPT;
+            doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
         }
     }
 
@@ -1934,65 +1927,60 @@
     */
     @Test
     public void testKeyWrappingRSAOAEPAESGCM192SHA256Outbound() throws Exception {
-        try {
-            Security.addProvider(new BouncyCastleProvider());
-            ByteArrayOutputStream baos;
-            {
-                WSSSecurityProperties securityProperties = new WSSSecurityProperties();
-                List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
-                actions.add(WSSConstants.ENCRYPT);
-                securityProperties.setActions(actions);
-                securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
-                securityProperties.setEncryptionUser("receiver");
-                securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes192-gcm");
-                securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
-                securityProperties.setEncryptionKeyTransportDigestAlgorithm("http://www.w3.org/2001/04/xmlenc#sha256");
+        ByteArrayOutputStream baos;
+        {
+            WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+            List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
+            actions.add(WSSConstants.ENCRYPT);
+            securityProperties.setActions(actions);
+            securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
+            securityProperties.setEncryptionUser("receiver");
+            securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes192-gcm");
+            securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
+            securityProperties.setEncryptionKeyTransportDigestAlgorithm("http://www.w3.org/2001/04/xmlenc#sha256");
 
-                InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-                baos = doOutboundSecurity(securityProperties, sourceDocument);
+            InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+            baos = doOutboundSecurity(securityProperties, sourceDocument);
 
-                Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
-                NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
-                Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
+            Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
+            NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
+            Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
 
-                XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
-                Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p']");
+            Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#sha256']");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmlenc#sha256']");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
-                Assert.assertEquals(nodeList.getLength(), 1);
+            nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 1);
 
-                nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
-                Assert.assertEquals(nodeList.getLength(), 1);
+            nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 1);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                Assert.assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
-                NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
-                for (int i = 0; i < childNodes.getLength(); i++) {
-                    Node child = childNodes.item(i);
-                    if (child.getNodeType() == Node.TEXT_NODE) {
-                        Assert.assertEquals(child.getTextContent().trim(), "");
-                    } else if (child.getNodeType() == Node.ELEMENT_NODE) {
-                        Assert.assertEquals(child, nodeList.item(0));
-                    } else {
-                        Assert.fail("Unexpected Node encountered");
-                    }
+            Assert.assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
+            NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
+            for (int i = 0; i < childNodes.getLength(); i++) {
+                Node child = childNodes.item(i);
+                if (child.getNodeType() == Node.TEXT_NODE) {
+                    Assert.assertEquals(child.getTextContent().trim(), "");
+                } else if (child.getNodeType() == Node.ELEMENT_NODE) {
+                    Assert.assertEquals(child, nodeList.item(0));
+                } else {
+                    Assert.fail("Unexpected Node encountered");
                 }
             }
-            //done encryption; now test decryption:
-            {
-                String action = WSHandlerConstants.ENCRYPT;
-                doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
-            }
-        } finally {
-            Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
+        }
+        //done encryption; now test decryption:
+        {
+            String action = WSHandlerConstants.ENCRYPT;
+            doInboundSecurityWithWSS4J(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
         }
     }
 
@@ -2049,71 +2037,65 @@
      */
     @Test
     public void testKeyWrappingRSAOAEPAES192GCMSHA384MGF1sha384Outbound() throws Exception {
-        try {
-            Security.addProvider(new BouncyCastleProvider());
+        ByteArrayOutputStream baos;
+        {
+            WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+            List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
+            actions.add(WSSConstants.ENCRYPT);
+            securityProperties.setActions(actions);
+            securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
+            securityProperties.setEncryptionUser("receiver");
+            securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes192-gcm");
+            securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2009/xmlenc11#rsa-oaep");
+            securityProperties.setEncryptionKeyTransportDigestAlgorithm("http://www.w3.org/2001/04/xmldsig-more#sha384");
+            securityProperties.setEncryptionKeyTransportMGFAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha384");
 
-            ByteArrayOutputStream baos;
-            {
-                WSSSecurityProperties securityProperties = new WSSSecurityProperties();
-                List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
-                actions.add(WSSConstants.ENCRYPT);
-                securityProperties.setActions(actions);
-                securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
-                securityProperties.setEncryptionUser("receiver");
-                securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes192-gcm");
-                securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2009/xmlenc11#rsa-oaep");
-                securityProperties.setEncryptionKeyTransportDigestAlgorithm("http://www.w3.org/2001/04/xmldsig-more#sha384");
-                securityProperties.setEncryptionKeyTransportMGFAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha384");
+            InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+            baos = doOutboundSecurity(securityProperties, sourceDocument);
 
-                InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-                baos = doOutboundSecurity(securityProperties, sourceDocument);
+            Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
+            NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
+            Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
 
-                Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
-                NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
-                Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
+            XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#rsa-oaep']");
+            Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#rsa-oaep']");
-                Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha384']");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha384']");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc11:MGF[@Algorithm='http://www.w3.org/2009/xmlenc11#mgf1sha384']");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc11:MGF[@Algorithm='http://www.w3.org/2009/xmlenc11#mgf1sha384']");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 1);
 
-                nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
-                Assert.assertEquals(nodeList.getLength(), 1);
+            nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 1);
 
-                nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
-                Assert.assertEquals(nodeList.getLength(), 1);
+            xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
-
-                Assert.assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
-                NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
-                for (int i = 0; i < childNodes.getLength(); i++) {
-                    Node child = childNodes.item(i);
-                    if (child.getNodeType() == Node.TEXT_NODE) {
-                        Assert.assertEquals(child.getTextContent().trim(), "");
-                    } else if (child.getNodeType() == Node.ELEMENT_NODE) {
-                        Assert.assertEquals(child, nodeList.item(0));
-                    } else {
-                        Assert.fail("Unexpected Node encountered");
-                    }
+            Assert.assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
+            NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
+            for (int i = 0; i < childNodes.getLength(); i++) {
+                Node child = childNodes.item(i);
+                if (child.getNodeType() == Node.TEXT_NODE) {
+                    Assert.assertEquals(child.getTextContent().trim(), "");
+                } else if (child.getNodeType() == Node.ELEMENT_NODE) {
+                    Assert.assertEquals(child, nodeList.item(0));
+                } else {
+                    Assert.fail("Unexpected Node encountered");
                 }
             }
-            //done encryption; now test decryption:
-            {
-                String action = WSHandlerConstants.ENCRYPT;
-                doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
-            }
-        } finally {
-            Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
+        }
+        //done encryption; now test decryption:
+        {
+            String action = WSHandlerConstants.ENCRYPT;
+            doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
         }
     }
 
@@ -2175,75 +2157,70 @@
 
     @Test
     public void testKeyWrappingRSAOAEPAESGCM192SHA384MGF1SHA384PSourceOutbound() throws Exception {
-        try {
-            Security.addProvider(new BouncyCastleProvider());
-            ByteArrayOutputStream baos;
-            {
-                WSSSecurityProperties securityProperties = new WSSSecurityProperties();
-                List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
-                actions.add(WSSConstants.ENCRYPT);
-                securityProperties.setActions(actions);
-                securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
-                securityProperties.setEncryptionUser("receiver");
-                securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes192-gcm");
-                securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2009/xmlenc11#rsa-oaep");
-                securityProperties.setEncryptionKeyTransportDigestAlgorithm("http://www.w3.org/2001/04/xmldsig-more#sha384");
-                securityProperties.setEncryptionKeyTransportMGFAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha384");
-                securityProperties.setEncryptionKeyTransportOAEPParams(Base64.decode("ZHVtbXkxMjM=".getBytes(StandardCharsets.UTF_8)));
+        ByteArrayOutputStream baos;
+        {
+            WSSSecurityProperties securityProperties = new WSSSecurityProperties();
+            List<WSSConstants.Action> actions = new ArrayList<WSSConstants.Action>();
+            actions.add(WSSConstants.ENCRYPT);
+            securityProperties.setActions(actions);
+            securityProperties.loadEncryptionKeystore(this.getClass().getClassLoader().getResource("transmitter.jks"), "default".toCharArray());
+            securityProperties.setEncryptionUser("receiver");
+            securityProperties.setEncryptionSymAlgorithm("http://www.w3.org/2009/xmlenc11#aes192-gcm");
+            securityProperties.setEncryptionKeyTransportAlgorithm("http://www.w3.org/2009/xmlenc11#rsa-oaep");
+            securityProperties.setEncryptionKeyTransportDigestAlgorithm("http://www.w3.org/2001/04/xmldsig-more#sha384");
+            securityProperties.setEncryptionKeyTransportMGFAlgorithm("http://www.w3.org/2009/xmlenc11#mgf1sha384");
+            securityProperties.setEncryptionKeyTransportOAEPParams(Base64.decode("ZHVtbXkxMjM=".getBytes(StandardCharsets.UTF_8)));
 
-                InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
-                baos = doOutboundSecurity(securityProperties, sourceDocument);
+            InputStream sourceDocument = this.getClass().getClassLoader().getResourceAsStream("testdata/plain-soap-1.1.xml");
+            baos = doOutboundSecurity(securityProperties, sourceDocument);
 
-                Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
-                NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
-                Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
+            Document document = documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray()));
+            NodeList nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedKey.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedKey.getLocalPart());
+            Assert.assertEquals(nodeList.item(0).getParentNode().getLocalName(), WSSConstants.TAG_WSSE_SECURITY.getLocalPart());
 
-                XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#rsa-oaep']");
-                Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            XPathExpression xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#rsa-oaep']");
+            Node node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha384']");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod[@Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha384']");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc11:MGF[@Algorithm='http://www.w3.org/2009/xmlenc11#mgf1sha384']");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            xPathExpression = getXPath("/soap:Envelope/soap:Header/wsse:Security/xenc:EncryptedKey/xenc:EncryptionMethod/xenc11:MGF[@Algorithm='http://www.w3.org/2009/xmlenc11#mgf1sha384']");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
-                Assert.assertEquals(nodeList.getLength(), 1);
+            nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_DataReference.getNamespaceURI(), WSSConstants.TAG_xenc_DataReference.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 1);
 
-                nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
-                Assert.assertEquals(nodeList.getLength(), 1);
+            nodeList = document.getElementsByTagNameNS(WSSConstants.TAG_xenc_EncryptedData.getNamespaceURI(), WSSConstants.TAG_xenc_EncryptedData.getLocalPart());
+            Assert.assertEquals(nodeList.getLength(), 1);
 
-                xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
-                node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
-                Assert.assertNotNull(node);
+            xPathExpression = getXPath("/soap:Envelope/soap:Body/xenc:EncryptedData/xenc:EncryptionMethod[@Algorithm='http://www.w3.org/2009/xmlenc11#aes192-gcm']");
+            node = (Node) xPathExpression.evaluate(document, XPathConstants.NODE);
+            Assert.assertNotNull(node);
 
-                Assert.assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
-                NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
-                for (int i = 0; i < childNodes.getLength(); i++) {
-                    Node child = childNodes.item(i);
-                    if (child.getNodeType() == Node.TEXT_NODE) {
-                        Assert.assertEquals(child.getTextContent().trim(), "");
-                    } else if (child.getNodeType() == Node.ELEMENT_NODE) {
-                        Assert.assertEquals(child, nodeList.item(0));
-                    } else {
-                        Assert.fail("Unexpected Node encountered");
-                    }
+            Assert.assertEquals(node.getParentNode().getParentNode().getLocalName(), "Body");
+            NodeList childNodes = node.getParentNode().getParentNode().getChildNodes();
+            for (int i = 0; i < childNodes.getLength(); i++) {
+                Node child = childNodes.item(i);
+                if (child.getNodeType() == Node.TEXT_NODE) {
+                    Assert.assertEquals(child.getTextContent().trim(), "");
+                } else if (child.getNodeType() == Node.ELEMENT_NODE) {
+                    Assert.assertEquals(child, nodeList.item(0));
+                } else {
+                    Assert.fail("Unexpected Node encountered");
                 }
             }
-            //done encryption; now test decryption:
-            {
-                String action = WSHandlerConstants.ENCRYPT;
-                doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
-            }
-        } finally {
-            Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
+        }
+        //done encryption; now test decryption:
+        {
+            String action = WSHandlerConstants.ENCRYPT;
+            doInboundSecurityWithWSS4J_1(documentBuilderFactory.newDocumentBuilder().parse(new ByteArrayInputStream(baos.toByteArray())), action);
         }
     }
 
diff --git a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/PrincipalTest.java b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/PrincipalTest.java
index cf0fd6d..c1ca3d7 100644
--- a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/PrincipalTest.java
+++ b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/PrincipalTest.java
@@ -308,7 +308,8 @@
         //
         if ("IBM Corporation".equals(System.getProperty("java.vendor"))
             || System.getProperty("java.version") != null
-                && System.getProperty("java.version").startsWith("1.8")) {
+                &&  (System.getProperty("java.version").startsWith("1.8")
+                    || System.getProperty("java.version").startsWith("1.6"))) {
             return;
         }
 
diff --git a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/SignatureTest.java b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/SignatureTest.java
index e14f415..92009dd 100644
--- a/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/SignatureTest.java
+++ b/ws-security-stax/src/test/java/org/apache/wss4j/stax/test/SignatureTest.java
@@ -1440,7 +1440,8 @@
         //
         if ("IBM Corporation".equals(System.getProperty("java.vendor"))
             || System.getProperty("java.version") != null
-                && System.getProperty("java.version").startsWith("1.8")) {
+                &&  (System.getProperty("java.version").startsWith("1.8")
+                    || System.getProperty("java.version").startsWith("1.6"))) {
             return;
         }