summaryrefslogtreecommitdiffstats
path: root/base/kra
diff options
context:
space:
mode:
authorAde Lee <alee@redhat.com>2017-04-06 17:09:39 -0400
committerAde Lee <alee@redhat.com>2017-04-13 17:20:51 -0400
commit716dca464943a22eb6588187fba9fad85e1c1345 (patch)
tree0bcdb9ed7892fb6c4e0d4c05c10fc3e0d70c18d4 /base/kra
parentc381566ddf1f4f05330063bb012d59e5c1753b13 (diff)
downloadpki-716dca464943a22eb6588187fba9fad85e1c1345.tar.gz
pki-716dca464943a22eb6588187fba9fad85e1c1345.tar.xz
pki-716dca464943a22eb6588187fba9fad85e1c1345.zip
Fix symkey retrieval in python client
Keys (like symmetric keys and asymmetric keys) are returned from the KRA either encrypted or key wrapped. Because the AES keywrapping algorithm cannot be decrypted using AES CBC, we need special logic to unwrap the keys. The flow here is as follows: 1. When a key retrieval request is sent to the server, the client sends the encryption and key wrapping algorithms it requires the key to be wrapped along with the wrapping key. 2. If no encryption algorithm or key wrap algorithm is recieved, the server assumes its talking to an old client and uses DES3. 3. The key is retrieved and (on server's choice) is wrapped or encrypted. The return package will have either encryption or key wrap algorithm set (depending on how the key was encrypted/wrapped.) 4. client uses that to determine how to unwrap key. This patch: 1. Makes sure the key wrap algorithm requested by client is passed through and used to wrap the retrieved key. 2. Adds logic in the python client to unwrap/decrypt. 3. As python-cryptography does not yet support AES KeyWrap with padding, the python client is configured to request AES-CBC by default. Change-Id: I4ba219bade821249b81e4e9a088959c27827ece1
Diffstat (limited to 'base/kra')
-rw-r--r--base/kra/src/com/netscape/kra/SecurityDataProcessor.java79
1 files changed, 65 insertions, 14 deletions
diff --git a/base/kra/src/com/netscape/kra/SecurityDataProcessor.java b/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
index 05dccb9c0..4659901ac 100644
--- a/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
+++ b/base/kra/src/com/netscape/kra/SecurityDataProcessor.java
@@ -402,26 +402,34 @@ public class SecurityDataProcessor {
String transportKeyAlgo = transportUnit.getCertificate().getPublicKey().getAlgorithm();
byte[] iv = null;
+ byte[] iv_wrap = null;
try {
- iv = generate_iv(payloadEncryptOID, transportUnit.getOldWrappingParams());
+ iv = generate_iv(
+ payloadEncryptOID,
+ transportUnit.getOldWrappingParams().getPayloadEncryptionAlgorithm());
+ iv_wrap = generate_wrap_iv(
+ payloadWrapName,
+ transportUnit.getOldWrappingParams().getPayloadWrapAlgorithm());
} catch (Exception e1) {
throw new EBaseException("Failed to generate IV when wrapping secret", e1);
}
- String ivStr = Utils.base64encode(iv);
+ String ivStr = iv != null? Utils.base64encode(iv): null;
+ String ivStr_wrap = iv_wrap != null ? Utils.base64encode(iv_wrap): null;
WrappingParams wrapParams = null;
if (payloadEncryptOID == null) {
+ // talking to an old server, use 3DES
wrapParams = transportUnit.getOldWrappingParams();
wrapParams.setPayloadEncryptionIV(new IVParameterSpec(iv));
- wrapParams.setPayloadWrappingIV(new IVParameterSpec(iv));
+ wrapParams.setPayloadWrappingIV(new IVParameterSpec(iv_wrap));
} else {
try {
wrapParams = new WrappingParams(
payloadEncryptOID,
payloadWrapName,
transportKeyAlgo,
- new IVParameterSpec(iv),
- null);
+ iv != null? new IVParameterSpec(iv): null,
+ iv_wrap != null? new IVParameterSpec(iv_wrap): null);
} catch (Exception e) {
auditRecoveryRequestProcessed(auditSubjectID, ILogger.FAILURE, requestID, serialno.toString(),
"Cannot generate wrapping params");
@@ -597,7 +605,7 @@ public class SecurityDataProcessor {
//secret has wrapped using a key wrapping algorithm
params.put(IRequest.SECURITY_DATA_PL_WRAPPED, Boolean.toString(true));
if (wrapParams.getPayloadWrappingIV() != null) {
- params.put(IRequest.SECURITY_DATA_IV_STRING_OUT, ivStr);
+ params.put(IRequest.SECURITY_DATA_IV_STRING_OUT, ivStr_wrap);
}
}
@@ -614,17 +622,60 @@ public class SecurityDataProcessor {
return false; //return true ? TODO
}
- private byte[] generate_iv(String oid, WrappingParams old) throws Exception {
+ /***
+ * This method returns an IV for the Encryption Algorithm referenced in OID.
+ * If the oid is null, we return an IV for the default encryption algorithm.
+ * The method checks to see if the encryption algorithm requires an IV by checking
+ * the parameterClasses() for the encryption algorithm.
+ *
+ * @param oid -- OID of encryption algorithm (as a string)
+ * @param defaultAlg -- default encryption algorithm
+ * @return -- initialization vector or null if none needed
+ * @throws Exception if algorithm is not found, or if default and OID are null.
+ * (ie. algorithm is unknown)
+ */
+ private byte[] generate_iv(String oid, EncryptionAlgorithm defaultAlg) throws Exception {
int numBytes = 0;
- if (oid != null) {
- numBytes = EncryptionAlgorithm.fromOID(new OBJECT_IDENTIFIER(oid)).getIVLength();
- } else {
- // old client (OID not provided)
- numBytes = old.getPayloadEncryptionAlgorithm().getIVLength();
+ EncryptionAlgorithm alg = oid != null? EncryptionAlgorithm.fromOID(new OBJECT_IDENTIFIER(oid)):
+ defaultAlg;
+
+ if (alg == null) {
+ throw new EBaseException("Cannot determine encryption algorithm to generate IV");
+ };
+
+ if (alg.getParameterClasses() == null)
+ return null;
+
+ numBytes = alg.getIVLength();
+ return (new SecureRandom()).generateSeed(numBytes);
+ }
+
+ /***
+ * This method returns an IV for the KeyWrap algorithm referenced in wrapName.
+ * If the wrapName is null, we return an IV for the default wrap algorithm.
+ * The method checks to see if the key wrap algorithm requires an IV by checking
+ * the parameterClasses() for the key wrap algorithm.
+ *
+ * @param wrapName -- name of the key wrap algorithm (as defined in JSS)
+ * @param defaultAlg -- default wrapping parameters
+ * @return -- initialization vector or null if none needed
+ * @throws Exception if algorithm is not found, or if default and OID are null.
+ * (ie. algorithm is unknown)
+ */
+ private byte[] generate_wrap_iv(String wrapName, KeyWrapAlgorithm defaultAlg) throws Exception {
+ int numBytes = 0;
+ KeyWrapAlgorithm alg = wrapName != null ? KeyWrapAlgorithm.fromString(wrapName) :
+ defaultAlg;
+
+ if (alg == null) {
+ throw new EBaseException("Cannot determine keywrap algorithm to generate IV");
}
- SecureRandom rnd = new SecureRandom();
- return rnd.generateSeed(numBytes);
+ if (alg.getParameterClasses() == null)
+ return null;
+
+ numBytes = alg.getBlockSize();
+ return (new SecureRandom()).generateSeed(numBytes);
}
public SymmetricKey recoverSymKey(KeyRecord keyRecord)