Details
-
Bug
-
Status: Closed
-
Critical
-
Resolution: Fixed
-
1.6.17, 1.6.18, 2.0.3
-
None
Description
org.apache.ws.security.util.WSSecurityUtil.getCipherInstance looks like below:
public static Cipher getCipherInstance(String cipherAlgo) throws WSSecurityException { try { String keyAlgorithm = JCEMapper.translateURItoJCEID(cipherAlgo); return Cipher.getInstance(keyAlgorithm); } catch (NoSuchPaddingException ex) { throw new WSSecurityException( WSSecurityException.UNSUPPORTED_ALGORITHM, "unsupportedKeyTransp", new Object[] { "No such padding: " + cipherAlgo }, ex ); } catch (NoSuchAlgorithmException ex) { // Check to see if an RSA OAEP MGF-1 with SHA-1 algorithm was requested // Some JDKs don't support RSA/ECB/OAEPPadding if (WSConstants.KEYTRANSPORT_RSAOEP.equals(cipherAlgo)) { try { return Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); } catch (Exception e) { throw new WSSecurityException( WSSecurityException.UNSUPPORTED_ALGORITHM, "unsupportedKeyTransp", new Object[] { "No such algorithm: " + cipherAlgo }, e ); } } else { throw new WSSecurityException( WSSecurityException.UNSUPPORTED_ALGORITHM, "unsupportedKeyTransp", new Object[] { "No such algorithm: " + cipherAlgo }, ex ); } } }
It uses JCEMapper to translate an URL to a JCE cipher name, but it does not use the JCE provider ID available in JCEMapper.getProviderId() - this has the consequence that it will always chose the default JCE provider.
The code should have been similar to this:
if (JCEMapper.getProviderId() != null) return Cipher.getInstance(keyAlgorithm, JCEMapper.getProviderId()); else return Cipher.getInstance(keyAlgorithm);
The code above is similar to the signature handling code in the xmldsig project, found in org.apache.xml.security.algorithms.implementations.SignatureBaseRSA
Our current behaviour, is that signature checks work with the Luna provider, but encrypted WS-Security fails since the wrong JCE provider is used for the Cipher.