You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by co...@apache.org on 2015/06/24 11:39:01 UTC
svn commit: r1687219 - in /webservices/wss4j/trunk:
ws-security-common/src/main/java/org/apache/wss4j/common/
ws-security-common/src/main/java/org/apache/wss4j/common/ext/
ws-security-dom/src/main/java/org/apache/wss4j/dom/action/
ws-security-dom/src/m...
Author: coheigea
Date: Wed Jun 24 09:39:00 2015
New Revision: 1687219
URL: http://svn.apache.org/r1687219
Log:
Allow the retrieval of a secret key for encryption from a CallbackHandler
Modified:
webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ConfigurationConstants.java
webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/EncryptionActionToken.java
webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ext/WSPasswordCallback.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/EncryptionAction.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java
webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncryptedKey.java
Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ConfigurationConstants.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ConfigurationConstants.java?rev=1687219&r1=1687218&r2=1687219&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ConfigurationConstants.java (original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ConfigurationConstants.java Wed Jun 24 09:39:00 2015
@@ -532,6 +532,14 @@ public class ConfigurationConstants {
*/
public static final String USE_2005_12_NAMESPACE = "use200512Namespace";
+ /**
+ * Whether to get a secret key from a CallbackHandler or not for encryption only. The default is
+ * false. If set to true WSS4J attempts to get the secret key from the CallbackHandler instead of
+ * generating a random key internally. This allows the user more control over the symmetric key
+ * if required.
+ */
+ public static final String GET_SECRET_KEY_FROM_CALLBACK_HANDLER = "getSecretKeyFromCallbackHandler";
+
//
// (Non-boolean) Configuration parameters for the actions/processors
//
Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/EncryptionActionToken.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/EncryptionActionToken.java?rev=1687219&r1=1687218&r2=1687219&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/EncryptionActionToken.java (original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/EncryptionActionToken.java Wed Jun 24 09:39:00 2015
@@ -28,6 +28,7 @@ public class EncryptionActionToken exten
private String mgfAlgorithm;
private String symmetricAlgorithm;
private String keyTransportAlgorithm;
+ private boolean getSymmetricKeyFromCallbackHandler;
public boolean isEncSymmetricEncryptionKey() {
return encSymmetricEncryptionKey;
@@ -53,6 +54,12 @@ public class EncryptionActionToken exten
public void setKeyTransportAlgorithm(String keyTransportAlgorithm) {
this.keyTransportAlgorithm = keyTransportAlgorithm;
}
+ public boolean isGetSymmetricKeyFromCallbackHandler() {
+ return getSymmetricKeyFromCallbackHandler;
+ }
+ public void setGetSymmetricKeyFromCallbackHandler(boolean getSymmetricKeyFromCallbackHandler) {
+ this.getSymmetricKeyFromCallbackHandler = getSymmetricKeyFromCallbackHandler;
+ }
}
Modified: webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ext/WSPasswordCallback.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ext/WSPasswordCallback.java?rev=1687219&r1=1687218&r2=1687219&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ext/WSPasswordCallback.java (original)
+++ webservices/wss4j/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/ext/WSPasswordCallback.java Wed Jun 24 09:39:00 2015
@@ -138,10 +138,12 @@ public class WSPasswordCallback implemen
private String identifier;
private String password;
private byte[] secret;
+ private byte[] encryptedSecret;
private Key key;
private int usage;
private String type;
private Element customToken;
+ private String algorithm;
/**
* Constructor.
@@ -264,5 +266,43 @@ public class WSPasswordCallback implemen
public void setCustomToken(Element customToken) {
this.customToken = customToken;
}
+
+ /**
+ * Get the Encrypted Secret. The CallbackHandler may return an encrypted version of the secret key
+ * to be used, instead of having WSS4J explicitly encrypt the key. Alternatively, the recipient can
+ * call this with the cipher content of the EncryptedKey, if a symmetric key wrap algorithm is used.
+ *
+ */
+ public byte[] getEncryptedSecret() {
+ return encryptedSecret;
+ }
+
+ /**
+ * Set the Encrypted Secret. The CallbackHandler may return an encrypted version of the secret key
+ * to be used, instead of having WSS4J explicitly encrypt the key. Alternatively, the recipient can
+ * call this with the cipher content of the EncryptedKey, if a symmetric key wrap algorithm is used.
+ *
+ * @param encryptedSecret
+ */
+ public void setEncryptedSecret(byte[] encryptedSecret) {
+ this.encryptedSecret = encryptedSecret;
+ }
+
+ /**
+ * Get the algorithm to be used. For example, a different secret key might be returned depending
+ * on the algorithm.
+ */
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ /**
+ * Specify an algorithm to be used. For example, a different secret key might be returned depending
+ * on the algorithm.
+ */
+ public void setAlgorithm(String algorithm) {
+ this.algorithm = algorithm;
+ }
+
}
\ No newline at end of file
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/EncryptionAction.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/EncryptionAction.java?rev=1687219&r1=1687218&r2=1687219&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/EncryptionAction.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/action/EncryptionAction.java Wed Jun 24 09:39:00 2015
@@ -88,13 +88,17 @@ public class EncryptionAction implements
}
wsEncrypt.setEncryptSymmKey(encryptionToken.isEncSymmetricEncryptionKey());
+
byte[] ephemeralKey = encryptionToken.getKey();
- if (!encryptionToken.isEncSymmetricEncryptionKey() && ephemeralKey == null) {
+ if (encryptionToken.isGetSymmetricKeyFromCallbackHandler()
+ || !encryptionToken.isEncSymmetricEncryptionKey() && ephemeralKey == null) {
CallbackHandler callbackHandler =
handler.getPasswordCallbackHandler(reqData);
WSPasswordCallback passwordCallback =
handler.getPasswordCB(encryptionToken.getUser(), WSConstants.ENCR, callbackHandler, reqData);
ephemeralKey = passwordCallback.getKey();
+ byte[] encryptedKey = passwordCallback.getEncryptedSecret();
+ wsEncrypt.setEncryptedEphemeralKey(encryptedKey);
}
wsEncrypt.setEphemeralKey(ephemeralKey);
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java?rev=1687219&r1=1687218&r2=1687219&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/handler/WSHandler.java Wed Jun 24 09:39:00 2015
@@ -709,6 +709,10 @@ public abstract class WSHandler {
decodeBooleanConfigValue(mc, WSHandlerConstants.USE_2005_12_NAMESPACE, true);
reqData.setUse200512Namespace(use200512Namespace);
+ boolean getSecretKeyFromCallbackHandler =
+ decodeBooleanConfigValue(mc, WSHandlerConstants.GET_SECRET_KEY_FROM_CALLBACK_HANDLER, false);
+ actionToken.setGetSymmetricKeyFromCallbackHandler(getSecretKeyFromCallbackHandler);
+
String digestAlgo = getString(WSHandlerConstants.ENC_DIGEST_ALGO, mc);
actionToken.setDigestAlgorithm(digestAlgo);
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java?rev=1687219&r1=1687218&r2=1687219&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncrypt.java Wed Jun 24 09:39:00 2015
@@ -133,7 +133,7 @@ public class WSSecEncrypt extends WSSecE
// Get the certificate that contains the public key for the public key
// algorithm that will encrypt the generated symmetric (session) key.
//
- if (encryptSymmKey) {
+ if (encryptSymmKey && encryptedEphemeralKey == null) {
X509Certificate remoteCert = getUseThisCert();
if (remoteCert == null) {
CryptoType cryptoType = null;
@@ -154,6 +154,8 @@ public class WSSecEncrypt extends WSSecE
remoteCert = certs[0];
}
prepareInternal(symmetricKey, remoteCert, crypto);
+ } else if (encryptedEphemeralKey != null) {
+ prepareInternal(symmetricKey);
} else {
encryptedEphemeralKey = symmetricKey.getEncoded();
}
@@ -197,6 +199,7 @@ public class WSSecEncrypt extends WSSecE
prependBSTElementToHeader(secHeader);
+ clean();
LOG.debug("Encryption complete.");
return doc;
}
Modified: webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncryptedKey.java
URL: http://svn.apache.org/viewvc/webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncryptedKey.java?rev=1687219&r1=1687218&r2=1687219&view=diff
==============================================================================
--- webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncryptedKey.java (original)
+++ webservices/wss4j/trunk/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/WSSecEncryptedKey.java Wed Jun 24 09:39:00 2015
@@ -164,6 +164,13 @@ public class WSSecEncryptedKey extends W
return encKeyId;
}
+ public void clean() {
+ ephemeralKey = null;
+ symmetricKey = null;
+ encryptedEphemeralKey = null;
+ }
+
+
/**
* Prepare the ephemeralKey and the tokens required to be added to the
* security header
@@ -189,31 +196,35 @@ public class WSSecEncryptedKey extends W
}
}
- //
- // Get the certificate that contains the public key for the public key
- // algorithm that will encrypt the generated symmetric (session) key.
- //
- X509Certificate remoteCert = useThisCert;
- if (remoteCert == null) {
- CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
- cryptoType.setAlias(user);
- if (crypto == null) {
- throw new WSSecurityException(
- WSSecurityException.ErrorCode.FAILURE,
- "noUserCertsFound",
- new Object[] {user, "encryption"});
- }
- X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
- if (certs == null || certs.length <= 0) {
- throw new WSSecurityException(
- WSSecurityException.ErrorCode.FAILURE,
- "noUserCertsFound",
- new Object[] {user, "encryption"});
+ if (encryptedEphemeralKey == null) {
+ //
+ // Get the certificate that contains the public key for the public key
+ // algorithm that will encrypt the generated symmetric (session) key.
+ //
+ X509Certificate remoteCert = useThisCert;
+ if (remoteCert == null) {
+ CryptoType cryptoType = new CryptoType(CryptoType.TYPE.ALIAS);
+ cryptoType.setAlias(user);
+ if (crypto == null) {
+ throw new WSSecurityException(
+ WSSecurityException.ErrorCode.FAILURE,
+ "noUserCertsFound",
+ new Object[] {user, "encryption"});
+ }
+ X509Certificate[] certs = crypto.getX509Certificates(cryptoType);
+ if (certs == null || certs.length <= 0) {
+ throw new WSSecurityException(
+ WSSecurityException.ErrorCode.FAILURE,
+ "noUserCertsFound",
+ new Object[] {user, "encryption"});
+ }
+ remoteCert = certs[0];
}
- remoteCert = certs[0];
+
+ prepareInternal(symmetricKey, remoteCert, crypto);
+ } else {
+ prepareInternal(symmetricKey);
}
-
- prepareInternal(symmetricKey, remoteCert, crypto);
}
/**
@@ -420,6 +431,88 @@ public class WSSecEncryptedKey extends W
xencCipherValue.appendChild(keyText);
}
+ protected void prepareInternal(SecretKey secretKey) throws WSSecurityException {
+ Text keyText =
+ WSSecurityUtil.createBase64EncodedTextNode(document, encryptedEphemeralKey);
+
+ encryptedKeyElement = createEncryptedKey(document, keyEncAlgo);
+ if (encKeyId == null || "".equals(encKeyId)) {
+ encKeyId = IDGenerator.generateID("EK-");
+ }
+ encryptedKeyElement.setAttributeNS(null, "Id", encKeyId);
+
+ if (keyIdentifierType == WSConstants.CUSTOM_SYMM_SIGNING
+ || keyIdentifierType == WSConstants.CUSTOM_SYMM_SIGNING_DIRECT
+ || keyIdentifierType == WSConstants.CUSTOM_KEY_IDENTIFIER) {
+ SecurityTokenReference secToken = new SecurityTokenReference(document);
+
+ switch (keyIdentifierType) {
+
+ case WSConstants.CUSTOM_SYMM_SIGNING :
+ Reference refCust = new Reference(document);
+ if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
+ refCust.setValueType(customEKTokenValueType);
+ } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
+ } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
+ refCust.setValueType(customEKTokenValueType);
+ } else {
+ refCust.setValueType(customEKTokenValueType);
+ }
+ refCust.setURI("#" + customEKTokenId);
+ secToken.setReference(refCust);
+ break;
+
+ case WSConstants.CUSTOM_SYMM_SIGNING_DIRECT :
+ Reference refCustd = new Reference(document);
+ if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
+ refCustd.setValueType(customEKTokenValueType);
+ } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
+ } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
+ refCustd.setValueType(customEKTokenValueType);
+ } else {
+ refCustd.setValueType(customEKTokenValueType);
+ }
+ refCustd.setURI(customEKTokenId);
+ secToken.setReference(refCustd);
+ break;
+
+ case WSConstants.CUSTOM_KEY_IDENTIFIER:
+ secToken.setKeyIdentifier(customEKTokenValueType, customEKTokenId);
+ if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_SAML_TOKEN_TYPE);
+ } else if (WSConstants.WSS_SAML2_KI_VALUE_TYPE.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_SAML2_TOKEN_TYPE);
+ } else if (WSConstants.WSS_ENC_KEY_VALUE_TYPE.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
+ } else if (SecurityTokenReference.ENC_KEY_SHA1_URI.equals(customEKTokenValueType)) {
+ secToken.addTokenType(WSConstants.WSS_ENC_KEY_VALUE_TYPE);
+ }
+ break;
+
+ default:
+ throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "unsupportedKeyId");
+ }
+ Element keyInfoElement =
+ document.createElementNS(
+ WSConstants.SIG_NS, WSConstants.SIG_PREFIX + ":" + WSConstants.KEYINFO_LN
+ );
+ keyInfoElement.setAttributeNS(
+ WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
+ );
+ keyInfoElement.appendChild(secToken.getElement());
+ encryptedKeyElement.appendChild(keyInfoElement);
+ }
+
+ Element xencCipherValue = createCipherValue(document, encryptedKeyElement);
+ xencCipherValue.appendChild(keyText);
+ }
+
/**
* Add a BinarySecurityToken
*/
@@ -641,6 +734,10 @@ public class WSSecEncryptedKey extends W
return encryptedEphemeralKey;
}
+ public void setEncryptedEphemeralKey(byte[] encryptedKey) {
+ encryptedEphemeralKey = encryptedKey;
+ }
+
public void setCustomEKTokenValueType(String customEKTokenValueType) {
this.customEKTokenValueType = customEKTokenValueType;
}