summaryrefslogtreecommitdiffstats
path: root/pki/base/kra/src
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/kra/src')
-rw-r--r--pki/base/kra/src/com/netscape/kra/ArchiveOptions.java154
-rw-r--r--pki/base/kra/src/com/netscape/kra/EncryptionUnit.java347
-rw-r--r--pki/base/kra/src/com/netscape/kra/EnrollmentService.java117
-rw-r--r--pki/base/kra/src/com/netscape/kra/KRAService.java7
-rw-r--r--pki/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java389
-rw-r--r--pki/base/kra/src/com/netscape/kra/SecurityDataService.java170
6 files changed, 965 insertions, 219 deletions
diff --git a/pki/base/kra/src/com/netscape/kra/ArchiveOptions.java b/pki/base/kra/src/com/netscape/kra/ArchiveOptions.java
new file mode 100644
index 000000000..c4650f17e
--- /dev/null
+++ b/pki/base/kra/src/com/netscape/kra/ArchiveOptions.java
@@ -0,0 +1,154 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.mozilla.jss.asn1.ANY;
+import org.mozilla.jss.asn1.BIT_STRING;
+import org.mozilla.jss.asn1.InvalidBERException;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SET;
+import org.mozilla.jss.pkix.cms.EncryptedContentInfo;
+import org.mozilla.jss.pkix.cms.EnvelopedData;
+import org.mozilla.jss.pkix.cms.RecipientInfo;
+import org.mozilla.jss.pkix.crmf.EncryptedKey;
+import org.mozilla.jss.pkix.crmf.EncryptedValue;
+import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+
+class ArchiveOptions {
+ private String mSymmAlgOID = null;
+ private byte mSymmAlgParams[] = null;
+ private byte mEncSymmKey[] = null;
+ private byte mEncValue[] = null;
+
+ public ArchiveOptions(PKIArchiveOptions opts) throws EBaseException {
+ try {
+ EncryptedKey key = opts.getEncryptedKey();
+ ANY enveloped_val = null;
+ EncryptedValue val = null;
+ AlgorithmIdentifier symmAlg = null;
+
+ if (key.getType() == org.mozilla.jss.pkix.crmf.EncryptedKey.ENVELOPED_DATA) {
+ CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENVELOPED_DATA");
+ // this is the new RFC4211 EncryptedKey that should
+ // have EnvelopedData to replace the deprecated EncryptedValue
+ enveloped_val = key.getEnvelopedData();
+ byte[] env_b = enveloped_val.getEncoded();
+ EnvelopedData.Template env_template = new EnvelopedData.Template();
+ EnvelopedData env_data =
+ (EnvelopedData) env_template.decode(new ByteArrayInputStream(env_b));
+ EncryptedContentInfo eCI = env_data.getEncryptedContentInfo();
+ symmAlg = eCI.getContentEncryptionAlgorithm();
+ mSymmAlgOID = symmAlg.getOID().toString();
+ mSymmAlgParams =
+ ((OCTET_STRING) ((ANY) symmAlg.getParameters()).decodeWith(OCTET_STRING.getTemplate()))
+ .toByteArray();
+
+ SET recipients = env_data.getRecipientInfos();
+ if (recipients.size() <= 0) {
+ CMS.debug("EnrollService: ArchiveOptions() - missing recipient information ");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
+ "[PKIArchiveOptions] missing recipient information "));
+ }
+ //check recpient - later
+ //we only handle one recipient here anyways. so, either the key
+ //can be decrypted or it can't. No risk here.
+ RecipientInfo ri = (RecipientInfo) recipients.elementAt(0);
+ OCTET_STRING key_o = ri.getEncryptedKey();
+ mEncSymmKey = key_o.toByteArray();
+
+ OCTET_STRING oString = eCI.getEncryptedContent();
+ BIT_STRING encVal = new BIT_STRING(oString.toByteArray(), 0);
+ mEncValue = encVal.getBits();
+ CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENVELOPED_DATA done");
+ } else if (key.getType() == org.mozilla.jss.pkix.crmf.EncryptedKey.ENCRYPTED_VALUE) {
+ CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENCRYPTED_VALUE");
+ // this is deprecated: EncryptedValue
+ val = key.getEncryptedValue();
+ symmAlg = val.getSymmAlg();
+ mSymmAlgOID = symmAlg.getOID().toString();
+ mSymmAlgParams =
+ ((OCTET_STRING) ((ANY) symmAlg.getParameters()).decodeWith(OCTET_STRING.getTemplate()))
+ .toByteArray();
+ BIT_STRING encSymmKey = val.getEncSymmKey();
+
+ mEncSymmKey = encSymmKey.getBits();
+ BIT_STRING encVal = val.getEncValue();
+
+ mEncValue = encVal.getBits();
+ CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENCRYPTED_VALUE done");
+ } else {
+ CMS.debug("EnrollService: ArchiveOptions() invalid EncryptedKey type");
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "[PKIArchiveOptions] type "
+ + key.getType()));
+ }
+
+ } catch (InvalidBERException e) {
+ CMS.debug("EnrollService: ArchiveOptions(): " + e.toString());
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
+ "[PKIArchiveOptions]" + e.toString()));
+ } catch (IOException e) {
+ CMS.debug("EnrollService: ArchiveOptions(): " + e.toString());
+ throw new EBaseException("ArchiveOptions() exception caught: " +
+ e.toString());
+ } catch (Exception e) {
+ CMS.debug("EnrollService: ArchiveOptions(): " + e.toString());
+ throw new EBaseException("ArchiveOptions() exception caught: " +
+ e.toString());
+ }
+
+ }
+
+ static public ArchiveOptions toArchiveOptions(byte options[]) throws
+ EBaseException {
+ ByteArrayInputStream bis = new ByteArrayInputStream(options);
+ PKIArchiveOptions archOpts = null;
+
+ try {
+ archOpts = (PKIArchiveOptions)
+ (new PKIArchiveOptions.Template()).decode(bis);
+ } catch (Exception e) {
+ throw new EBaseException("Failed to decode input PKIArchiveOptions.");
+ }
+
+ return new ArchiveOptions(archOpts);
+
+ }
+
+ public String getSymmAlgOID() {
+ return mSymmAlgOID;
+ }
+
+ public byte[] getSymmAlgParams() {
+ return mSymmAlgParams;
+ }
+
+ public byte[] getEncSymmKey() {
+ return mEncSymmKey;
+ }
+
+ public byte[] getEncValue() {
+ return mEncValue;
+ }
+}
diff --git a/pki/base/kra/src/com/netscape/kra/EncryptionUnit.java b/pki/base/kra/src/com/netscape/kra/EncryptionUnit.java
index d90afd726..32c17b08a 100644
--- a/pki/base/kra/src/com/netscape/kra/EncryptionUnit.java
+++ b/pki/base/kra/src/com/netscape/kra/EncryptionUnit.java
@@ -54,6 +54,7 @@ import com.netscape.cmscore.util.Debug;
* @author thomask
* @version $Revision$, $Date$
*/
+@SuppressWarnings("deprecation")
public abstract class EncryptionUnit implements IEncryptionUnit {
/* Establish one constant IV for base class, to be used for
@@ -168,96 +169,13 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
}
}
- /**
- * Wraps the data using transport public key.
- */
- public byte[] wrap(PrivateKey priKey) throws EBaseException {
- try {
-
- CMS.debug("EncryptionUnit.wrap");
- CryptoToken token = getToken();
-
- // (1) generate session key
- org.mozilla.jss.crypto.KeyGenerator kg =
- token.getKeyGenerator(KeyGenAlgorithm.DES3);
- // internalToken.getKeyGenerator(KeyGenAlgorithm.DES3);
- SymmetricKey.Usage usages[] = new SymmetricKey.Usage[2];
- usages[0] = SymmetricKey.Usage.WRAP;
- usages[1] = SymmetricKey.Usage.UNWRAP;
- kg.setKeyUsages(usages);
- kg.temporaryKeys(true);
- SymmetricKey sk = kg.generate();
- CMS.debug("EncryptionUnit:wrap() session key generated on slot: " + token.getName());
-
- // (2) wrap private key with session key
- // KeyWrapper wrapper = internalToken.getKeyWrapper(
- KeyWrapper wrapper = token.getKeyWrapper(
- KeyWrapAlgorithm.DES3_CBC_PAD);
-
- wrapper.initWrap(sk, IV);
- byte pri[] = wrapper.wrap(priKey);
- CMS.debug("EncryptionUnit:wrap() privKey wrapped");
-
- // (3) wrap session with transport public
- KeyWrapper rsaWrap = token.getKeyWrapper(
- KeyWrapAlgorithm.RSA);
-
- rsaWrap.initWrap(getPublicKey(), null);
- byte session[] = rsaWrap.wrap(sk);
- CMS.debug("EncryptionUnit:wrap() sessin key wrapped");
-
- // use MY own structure for now:
- // SEQUENCE {
- // encryptedSession OCTET STRING,
- // encryptedPrivate OCTET STRING
- // }
-
- DerOutputStream tmp = new DerOutputStream();
- DerOutputStream out = new DerOutputStream();
-
- tmp.putOctetString(session);
- tmp.putOctetString(pri);
- out.write(DerValue.tag_Sequence, tmp);
-
- return out.toByteArray();
- } catch (TokenException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
- Debug.trace("EncryptionUnit::wrap " + e.toString());
- return null;
- } catch (NoSuchAlgorithmException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
- Debug.trace("EncryptionUnit::wrap " + e.toString());
- return null;
- } catch (CharConversionException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
- Debug.trace("EncryptionUnit::wrap " + e.toString());
- return null;
- } catch (InvalidAlgorithmParameterException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
- Debug.trace("EncryptionUnit::wrap " + e.toString());
- return null;
- } catch (InvalidKeyException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
- Debug.trace("EncryptionUnit::wrap " + e.toString());
- return null;
- } catch (IOException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
- Debug.trace("EncryptionUnit::wrap " + e.toString());
- return null;
- } catch (Exception e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
- Debug.trace("EncryptionUnit::wrap " + e.toString());
- return null;
- }
+ public byte[] wrap(PrivateKey privKey) throws EBaseException {
+ return _wrap(privKey,null);
}
+ public byte[] wrap(SymmetricKey symmKey) throws EBaseException {
+ return _wrap(null,symmKey);
+ }
/**
* External unwrapping. Unwraps the data using
* the transport private key.
@@ -367,13 +285,70 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
}
/**
+ * External unwrapping. Unwraps the symmetric key using
+ * the transport private key.
+ */
+ public SymmetricKey unwrap_symmetric(byte encSymmKey[],
+ String symmAlgOID, byte symmAlgParams[],
+ byte encValue[])
+ throws EBaseException {
+ try {
+ CryptoToken token = getToken();
+
+ // (1) unwrap the session
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initUnwrap(getPrivateKey(), null);
+ SymmetricKey sk = rsaWrap.unwrapSymmetric(encSymmKey,
+ SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP,
+ 0);
+
+ // (2) unwrap the sym key
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD // XXX
+ );
+
+ wrapper.initUnwrap(sk, new IVParameterSpec(
+ symmAlgParams));
+
+ SymmetricKey symKey = wrapper.unwrapSymmetric(encValue, SymmetricKey.DES3, SymmetricKey.Usage.DECRYPT, 0);
+
+ return symKey;
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (Exception e) {
+ CMS.debug("EncryptionUnit.unwrap : Exception:" + e.toString());
+ return null;
+ }
+ }
+
+ /**
* External unwrapping. Unwraps the data using
* the transport private key.
*/
public PrivateKey unwrap(byte encSymmKey[],
- String symmAlgOID, byte symmAlgParams[],
- byte encValue[], PublicKey pubKey)
- throws EBaseException {
+ String symmAlgOID, byte symmAlgParams[],
+ byte encValue[], PublicKey pubKey)
+ throws EBaseException {
try {
CryptoToken token = getToken();
@@ -389,12 +364,12 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
// (2) unwrap the pri
KeyWrapper wrapper = token.getKeyWrapper(
KeyWrapAlgorithm.DES3_CBC_PAD // XXX
- );
+ );
wrapper.initUnwrap(sk, new IVParameterSpec(
symmAlgParams));
- PrivateKey.Type keytype = null;
+ PrivateKey.Type keytype = null;
String alg = pubKey.getAlgorithm();
if (alg.equals("DSA")) {
keytype = PrivateKey.DSA;
@@ -404,35 +379,36 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
keytype = PrivateKey.RSA;
}
PrivateKey pk = wrapper.unwrapTemporaryPrivate(encValue,
- keytype, pubKey);
+ keytype , pubKey);
return pk;
} catch (TokenException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
Debug.trace("EncryptionUnit::unwrap " + e.toString());
return null;
} catch (NoSuchAlgorithmException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
Debug.trace("EncryptionUnit::unwrap " + e.toString());
return null;
} catch (InvalidAlgorithmParameterException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
Debug.trace("EncryptionUnit::unwrap " + e.toString());
return null;
} catch (InvalidKeyException e) {
- CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
- CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE, CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
Debug.trace("EncryptionUnit::unwrap " + e.toString());
return null;
} catch (Exception e) {
- CMS.debug("EncryptionUnit.unwrap : Exception:" + e.toString());
+ CMS.debug("EncryptionUnit.unwrap : Exception:"+e.toString());
return null;
}
}
+ /**
+ * External unwrapping. Unwraps the data using
+ * the transport private key.
+ */
+
public byte[] decryptInternalPrivate(byte wrappedKeyData[])
throws EBaseException {
try {
@@ -506,6 +482,72 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
}
/**
+ * External unwrapping of stored symmetric key.
+ */
+ public SymmetricKey unwrap(byte wrappedKeyData[])
+ throws EBaseException {
+ try {
+ DerValue val = new DerValue(wrappedKeyData);
+ // val.tag == DerValue.tag_Sequence
+ DerInputStream in = val.data;
+ DerValue dSession = in.getDerValue();
+ byte session[] = dSession.getOctetString();
+ DerValue dPri = in.getDerValue();
+ byte pri[] = dPri.getOctetString();
+
+ CryptoToken token = getToken();
+ // (1) unwrap the session key
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initUnwrap(getPrivateKey(), null);
+ SymmetricKey sk = rsaWrap.unwrapSymmetric(session,
+ SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP, 0);
+
+ // (2) unwrap the symmetric key
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+
+ wrapper.initUnwrap(sk, IV);
+
+ SymmetricKey sk_ret = wrapper.unwrapSymmetric(pri,
+ SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP,
+ 0);
+
+ return sk_ret;
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ CMS.debug(e);
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.printStackTrace(e);
+ return null;
+ } catch (IOException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_UNWRAP", e.toString()));
+ Debug.trace("EncryptionUnit::unwrap " + e.toString());
+ return null;
+ } catch (Exception e) {
+ Debug.printStackTrace(e);
+ return null;
+ }
+ }
+
+ /**
* Internal unwrapping.
*/
public PrivateKey unwrap_temp(byte wrappedKeyData[], PublicKey pubKey)
@@ -592,6 +634,105 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
}
}
+ /***
+ * Internal wrap, accounts for either private or symmetric key
+ */
+ private byte[] _wrap(PrivateKey priKey, SymmetricKey symmKey) throws EBaseException {
+ try {
+ if ((priKey == null && symmKey == null) || (priKey != null && symmKey != null)) {
+ return null;
+ }
+ CMS.debug("EncryptionUnit.wrap interal.");
+ CryptoToken token = getToken();
+
+ // (1) generate session key
+ org.mozilla.jss.crypto.KeyGenerator kg =
+ token.getKeyGenerator(KeyGenAlgorithm.DES3);
+ // internalToken.getKeyGenerator(KeyGenAlgorithm.DES3);
+ SymmetricKey.Usage usages[] = new SymmetricKey.Usage[2];
+ usages[0] = SymmetricKey.Usage.WRAP;
+ usages[1] = SymmetricKey.Usage.UNWRAP;
+ kg.setKeyUsages(usages);
+ kg.temporaryKeys(true);
+ SymmetricKey sk = kg.generate();
+ CMS.debug("EncryptionUnit:wrap() session key generated on slot: " + token.getName());
+
+ // (2) wrap private key with session key
+ // KeyWrapper wrapper = internalToken.getKeyWrapper(
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+
+ wrapper.initWrap(sk, IV);
+
+ byte pri[] = null;
+
+ if ( priKey != null) {
+ pri = wrapper.wrap(priKey);
+ } else if ( symmKey != null) {
+ pri = wrapper.wrap(symmKey);
+ }
+ CMS.debug("EncryptionUnit:wrap() privKey wrapped");
+
+ // (3) wrap session with transport public
+ KeyWrapper rsaWrap = token.getKeyWrapper(
+ KeyWrapAlgorithm.RSA);
+
+ rsaWrap.initWrap(getPublicKey(), null);
+ byte session[] = rsaWrap.wrap(sk);
+ CMS.debug("EncryptionUnit:wrap() sessin key wrapped");
+
+ // use MY own structure for now:
+ // SEQUENCE {
+ // encryptedSession OCTET STRING,
+ // encryptedPrivate OCTET STRING
+ // }
+
+ DerOutputStream tmp = new DerOutputStream();
+ DerOutputStream out = new DerOutputStream();
+
+ tmp.putOctetString(session);
+ tmp.putOctetString(pri);
+ out.write(DerValue.tag_Sequence, tmp);
+
+ return out.toByteArray();
+ } catch (TokenException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (NoSuchAlgorithmException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (CharConversionException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (InvalidAlgorithmParameterException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (InvalidKeyException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (IOException e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ } catch (Exception e) {
+ CMS.getLogger().log(ILogger.EV_SYSTEM, null, ILogger.S_KRA, ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_ENCRYPTION_WRAP", e.toString()));
+ Debug.trace("EncryptionUnit::wrap " + e.toString());
+ return null;
+ }
+ }
+
/**
* Verify the given key pair.
*/
diff --git a/pki/base/kra/src/com/netscape/kra/EnrollmentService.java b/pki/base/kra/src/com/netscape/kra/EnrollmentService.java
index b9df360b0..c2705e1e4 100644
--- a/pki/base/kra/src/com/netscape/kra/EnrollmentService.java
+++ b/pki/base/kra/src/com/netscape/kra/EnrollmentService.java
@@ -35,25 +35,15 @@ import netscape.security.x509.CertificateX509Key;
import netscape.security.x509.X509CertInfo;
import netscape.security.x509.X509Key;
-import org.mozilla.jss.asn1.ANY;
import org.mozilla.jss.asn1.ASN1Util;
import org.mozilla.jss.asn1.ASN1Value;
-import org.mozilla.jss.asn1.BIT_STRING;
import org.mozilla.jss.asn1.InvalidBERException;
import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
-import org.mozilla.jss.asn1.OCTET_STRING;
import org.mozilla.jss.asn1.SEQUENCE;
-import org.mozilla.jss.asn1.SET;
-import org.mozilla.jss.pkix.cms.EncryptedContentInfo;
-import org.mozilla.jss.pkix.cms.EnvelopedData;
-import org.mozilla.jss.pkix.cms.RecipientInfo;
import org.mozilla.jss.pkix.crmf.CertReqMsg;
import org.mozilla.jss.pkix.crmf.CertRequest;
-import org.mozilla.jss.pkix.crmf.EncryptedKey;
-import org.mozilla.jss.pkix.crmf.EncryptedValue;
import org.mozilla.jss.pkix.crmf.PKIArchiveOptions;
import org.mozilla.jss.pkix.primitive.AVA;
-import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.authentication.AuthToken;
@@ -73,6 +63,7 @@ import com.netscape.certsrv.security.ITransportKeyUnit;
import com.netscape.certsrv.util.IStatsSubsystem;
import com.netscape.cmscore.crmf.CRMFParser;
import com.netscape.cmscore.crmf.PKIArchiveOptionsContainer;
+import com.netscape.kra.ArchiveOptions;
import com.netscape.cmscore.dbs.KeyRecord;
/**
@@ -553,7 +544,7 @@ public class EnrollmentService implements IService {
*/
public static PKIArchiveOptionsContainer[] getPKIArchiveOptions(String crmfBlob)
throws EBaseException {
- Vector options = new Vector();
+ Vector<Object> options = new Vector<Object>();
if (CMS.debugOn())
CMS.debug("EnrollmentService::getPKIArchiveOptions> crmfBlob=" + crmfBlob);
@@ -876,107 +867,3 @@ public class EnrollmentService implements IService {
msg);
}
}
-
-/**
- * Parsed and Flattened structure of PKIArchiveOptions.
- */
-class ArchiveOptions {
- private String mSymmAlgOID = null;
- private byte mSymmAlgParams[] = null;
- private byte mEncSymmKey[] = null;
- private byte mEncValue[] = null;
-
- public ArchiveOptions(PKIArchiveOptions opts) throws EBaseException {
- try {
- EncryptedKey key = opts.getEncryptedKey();
- ANY enveloped_val = null;
- EncryptedValue val = null;
- AlgorithmIdentifier symmAlg = null;
-
- if (key.getType() == org.mozilla.jss.pkix.crmf.EncryptedKey.ENVELOPED_DATA) {
- CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENVELOPED_DATA");
- // this is the new RFC4211 EncryptedKey that should
- // have EnvelopedData to replace the deprecated EncryptedValue
- enveloped_val = key.getEnvelopedData();
- byte[] env_b = enveloped_val.getEncoded();
- EnvelopedData.Template env_template = new EnvelopedData.Template();
- EnvelopedData env_data =
- (EnvelopedData) env_template.decode(new ByteArrayInputStream(env_b));
- EncryptedContentInfo eCI = env_data.getEncryptedContentInfo();
- symmAlg = eCI.getContentEncryptionAlgorithm();
- mSymmAlgOID = symmAlg.getOID().toString();
- mSymmAlgParams =
- ((OCTET_STRING) ((ANY) symmAlg.getParameters()).decodeWith(OCTET_STRING.getTemplate()))
- .toByteArray();
-
- SET recipients = env_data.getRecipientInfos();
- if (recipients.size() <= 0) {
- CMS.debug("EnrollService: ArchiveOptions() - missing recipient information ");
- throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
- "[PKIArchiveOptions] missing recipient information "));
- }
- //check recpient - later
- //we only handle one recipient here anyways. so, either the key
- //can be decrypted or it can't. No risk here.
- RecipientInfo ri = (RecipientInfo) recipients.elementAt(0);
- OCTET_STRING key_o = ri.getEncryptedKey();
- mEncSymmKey = key_o.toByteArray();
-
- OCTET_STRING oString = eCI.getEncryptedContent();
- BIT_STRING encVal = new BIT_STRING(oString.toByteArray(), 0);
- mEncValue = encVal.getBits();
- CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENVELOPED_DATA done");
- } else if (key.getType() == org.mozilla.jss.pkix.crmf.EncryptedKey.ENCRYPTED_VALUE) {
- CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENCRYPTED_VALUE");
- // this is deprecated: EncryptedValue
- val = key.getEncryptedValue();
- symmAlg = val.getSymmAlg();
- mSymmAlgOID = symmAlg.getOID().toString();
- mSymmAlgParams =
- ((OCTET_STRING) ((ANY) symmAlg.getParameters()).decodeWith(OCTET_STRING.getTemplate()))
- .toByteArray();
- BIT_STRING encSymmKey = val.getEncSymmKey();
-
- mEncSymmKey = encSymmKey.getBits();
- BIT_STRING encVal = val.getEncValue();
-
- mEncValue = encVal.getBits();
- CMS.debug("EnrollService: ArchiveOptions() EncryptedKey type= ENCRYPTED_VALUE done");
- } else {
- CMS.debug("EnrollService: ArchiveOptions() invalid EncryptedKey type");
- throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", "[PKIArchiveOptions] type "
- + key.getType()));
- }
-
- } catch (InvalidBERException e) {
- CMS.debug("EnrollService: ArchiveOptions(): " + e.toString());
- throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE",
- "[PKIArchiveOptions]" + e.toString()));
- } catch (IOException e) {
- CMS.debug("EnrollService: ArchiveOptions(): " + e.toString());
- throw new EBaseException("ArchiveOptions() exception caught: " +
- e.toString());
- } catch (Exception e) {
- CMS.debug("EnrollService: ArchiveOptions(): " + e.toString());
- throw new EBaseException("ArchiveOptions() exception caught: " +
- e.toString());
- }
-
- }
-
- public String getSymmAlgOID() {
- return mSymmAlgOID;
- }
-
- public byte[] getSymmAlgParams() {
- return mSymmAlgParams;
- }
-
- public byte[] getEncSymmKey() {
- return mEncSymmKey;
- }
-
- public byte[] getEncValue() {
- return mEncValue;
- }
-}
diff --git a/pki/base/kra/src/com/netscape/kra/KRAService.java b/pki/base/kra/src/com/netscape/kra/KRAService.java
index 916ebe3bb..1a351e061 100644
--- a/pki/base/kra/src/com/netscape/kra/KRAService.java
+++ b/pki/base/kra/src/com/netscape/kra/KRAService.java
@@ -46,10 +46,13 @@ public class KRAService implements IService {
public final static String RECOVERY = IRequest.KEYRECOVERY_REQUEST;
public final static String NETKEY_KEYGEN = IRequest.NETKEY_KEYGEN_REQUEST;
public final static String NETKEY_KEYRECOVERY = IRequest.NETKEY_KEYRECOVERY_REQUEST;
+ public final static String SECURITY_DATA_ENROLLMENT = IRequest.SECURITY_DATA_ENROLLMENT_REQUEST;
+ public final static String SECURITY_DATA_RECOVERY = IRequest.SECURITY_DATA_RECOVERY_REQUEST;
+
// private variables
private IKeyRecoveryAuthority mKRA = null;
- private Hashtable mServices = new Hashtable();
+ private Hashtable<String,IService> mServices = new Hashtable<String,IService>();
/**
* Constructs KRA service.
@@ -60,6 +63,8 @@ public class KRAService implements IService {
mServices.put(RECOVERY, new RecoveryService(kra));
mServices.put(NETKEY_KEYGEN, new NetkeyKeygenService(kra));
mServices.put(NETKEY_KEYRECOVERY, new TokenKeyRecoveryService(kra));
+ mServices.put(SECURITY_DATA_ENROLLMENT, new SecurityDataService(kra));
+ mServices.put(SECURITY_DATA_RECOVERY, new SecurityDataRecoveryService(kra));
}
/**
diff --git a/pki/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java b/pki/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java
new file mode 100644
index 000000000..b38730949
--- /dev/null
+++ b/pki/base/kra/src/com/netscape/kra/SecurityDataRecoveryService.java
@@ -0,0 +1,389 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.io.ByteArrayOutputStream;
+import java.io.CharConversionException;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Hashtable;
+import java.util.Random;
+
+import javax.crypto.spec.RC2ParameterSpec;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.crypto.Cipher;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.EncryptionAlgorithm;
+import org.mozilla.jss.crypto.IVParameterSpec;
+import org.mozilla.jss.crypto.KeyGenerator;
+import org.mozilla.jss.crypto.KeyWrapAlgorithm;
+import org.mozilla.jss.crypto.KeyWrapper;
+import org.mozilla.jss.crypto.PBEAlgorithm;
+import org.mozilla.jss.crypto.PBEKeyGenParams;
+import org.mozilla.jss.crypto.SymmetricKey;
+import org.mozilla.jss.crypto.TokenException;
+import org.mozilla.jss.pkcs12.PasswordConverter;
+import org.mozilla.jss.pkcs7.ContentInfo;
+import org.mozilla.jss.pkcs7.EncryptedContentInfo;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+import org.mozilla.jss.pkix.primitive.PBEParameter;
+import org.mozilla.jss.util.Password;
+
+import com.netscape.certsrv.kra.EKRAException;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.cms.servlet.request.KeyRequestResource;
+import com.netscape.cmscore.dbs.KeyRecord;
+
+/**
+ * This implementation services SecurityData Recovery requests.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+@SuppressWarnings("deprecation")
+public class SecurityDataRecoveryService implements IService {
+
+ private IKeyRecoveryAuthority mKRA = null;
+
+ private IKeyRepository mStorage = null;
+ private IStorageKeyUnit mStorageUnit = null;
+ private ITransportKeyUnit mTransportUnit = null;
+
+ public static final String ATTR_SERIALNO = "serialNumber";
+ public static final String ATTR_SESS_WRAPPED_DATA = "sessWrappedSecData";
+ public static final String ATTR_PASS_WRAPPED_DATA = "passPhraseWrappedData";
+ public static final String ATTR_KEY_RECORD = "keyRecord";
+
+ public SecurityDataRecoveryService(IKeyRecoveryAuthority kra) {
+ mKRA = kra;
+ mStorage = mKRA.getKeyRepository();
+ mStorageUnit = mKRA.getStorageKeyUnit();
+ mTransportUnit = mKRA.getTransportKeyUnit();
+
+ }
+
+ /**
+ * Performs the service (such as certificate generation)
+ * represented by this request.
+ * <p>
+ *
+ * @param request
+ * The SecurityData recovery request that needs service. The service may use
+ * attributes stored in the request, and may update the
+ * values, or store new ones.
+ * @return
+ * an indication of whether this request is still pending.
+ * 'false' means the request will wait for further notification.
+ * @exception EBaseException indicates major processing failure.
+ */
+ public boolean serviceRequest(IRequest request)
+ throws EBaseException {
+
+ //Pave the way for allowing generated IV vector
+ byte iv[]= null;
+ byte iv_default[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 };
+ byte iv_in[] = null;
+
+ Hashtable<String, Object> params = mKRA.getVolatileRequest(
+ request.getRequestId());
+
+ if (params == null) {
+ CMS.debug("Can't get volatile params.");
+ throw new EBaseException("Can't obtain volatile params!");
+ }
+
+ BigInteger serialno = request.getExtDataInBigInteger(ATTR_SERIALNO);
+
+ request.setExtData(ATTR_KEY_RECORD, serialno);
+
+ byte[] wrappedPassPhrase = null;
+ byte[] wrappedSessKey = null;
+
+ String transWrappedSessKeyStr = (String) params.get(IRequest.SECURITY_DATA_TRANS_SESS_KEY);
+ if (transWrappedSessKeyStr != null) {
+ wrappedSessKey = com.netscape.osutil.OSUtil.AtoB(transWrappedSessKeyStr);
+ }
+
+ String sessWrappedPassPhraseStr = (String) params.get(IRequest.SECURITY_DATA_SESS_PASS_PHRASE);
+ if (sessWrappedPassPhraseStr != null) {
+ wrappedPassPhrase = com.netscape.osutil.OSUtil.AtoB(sessWrappedPassPhraseStr);
+ }
+
+ String ivInStr = (String) params.get(IRequest.SECURITY_DATA_IV_STRING_IN);
+ if (ivInStr != null) {
+ iv_in = com.netscape.osutil.OSUtil.AtoB(ivInStr);
+ }
+
+ if (transWrappedSessKeyStr == null && sessWrappedPassPhraseStr == null) {
+ //We may be in recovery case where no params were initially submitted.
+ return false;
+ }
+
+ //Create the return IV if needed.
+ iv = new byte[8];
+
+ try {
+ Random rnd = new Random();
+ rnd.nextBytes(iv);
+ } catch (Exception e) {
+ iv = iv_default;
+ }
+
+ String ivStr = com.netscape.osutil.OSUtil.BtoA(iv);
+
+ KeyRecord keyRecord = (KeyRecord) mStorage.readKeyRecord(serialno);
+
+ SymmetricKey unwrappedSess = null;
+
+ String dataType = (String) keyRecord.get(IKeyRecord.ATTR_DATA_TYPE);
+ SymmetricKey symKey = null;
+ byte[] unwrappedSecData = null;
+ if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
+ symKey = recoverSymKey(keyRecord);
+ } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) {
+ unwrappedSecData = recoverSecurityData(keyRecord);
+ }
+
+ CryptoToken ct = mTransportUnit.getToken();
+
+ byte[] key_data = null;
+ String pbeWrappedData = null;
+
+ if (sessWrappedPassPhraseStr != null) { //We have a trans wrapped pass phrase, we will be doing PBE packaging
+ byte[] unwrappedPass = null;
+ Password pass = null;
+
+ try {
+ unwrappedSess = mTransportUnit.unwrap_sym(wrappedSessKey, SymmetricKey.Usage.DECRYPT);
+ Cipher decryptor = ct.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
+ decryptor.initDecrypt(unwrappedSess, new IVParameterSpec(iv_in));
+ unwrappedPass = decryptor.doFinal(wrappedPassPhrase);
+ String passStr = new String(unwrappedPass, "UTF-8");
+
+ pass = new Password(passStr.toCharArray());
+ passStr = null;
+
+ if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
+ pbeWrappedData = createEncryptedContentInfo(ct, symKey, null,
+ pass);
+ } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) {
+ pbeWrappedData = createEncryptedContentInfo(ct, null, unwrappedSecData,
+ pass);
+ }
+
+ params.put(ATTR_PASS_WRAPPED_DATA, pbeWrappedData);
+
+ } catch (Exception e) {
+ throw new EBaseException("Can't unwrap pass phase! " + e.toString());
+ } finally {
+ if ( pass != null) {
+ pass.clear();
+ }
+
+ if ( unwrappedPass != null) {
+ java.util.Arrays.fill(unwrappedPass, (byte) 0);
+ }
+ }
+
+ } else { // No trans wrapped pass phrase, return session wrapped data.
+ if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
+ //wrap the key with session key
+ try {
+ unwrappedSess = mTransportUnit.unwrap_sym(wrappedSessKey, SymmetricKey.Usage.WRAP);
+ KeyWrapper wrapper = ct.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD);
+ wrapper.initWrap(unwrappedSess, new IVParameterSpec(iv));
+ key_data = wrapper.wrap(symKey);
+ } catch (Exception e) {
+ throw new EBaseException("Can't wrap symmetric key! " + e.toString());
+ }
+
+ } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) {
+ try {
+ unwrappedSess = mTransportUnit.unwrap_sym(wrappedSessKey, SymmetricKey.Usage.ENCRYPT);
+ Cipher encryptor = ct.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD);
+ if (encryptor != null) {
+ encryptor.initEncrypt(unwrappedSess, new IVParameterSpec(iv));
+ key_data = encryptor.doFinal(unwrappedSecData);
+ } else {
+ throw new IOException("Failed to create cipher");
+ }
+ } catch (Exception e) {
+ throw new EBaseException("Can't wrap pass phrase!");
+ }
+ }
+
+ String wrappedKeyData = com.netscape.osutil.OSUtil.BtoA(key_data);
+ params.put(ATTR_SESS_WRAPPED_DATA, wrappedKeyData);
+ params.put(IRequest.SECURITY_DATA_IV_STRING_OUT, ivStr);
+
+ }
+ return false;
+ }
+
+ public SymmetricKey recoverSymKey(KeyRecord keyRecord)
+ throws EBaseException {
+
+ try {
+ SymmetricKey symKey =
+ mStorageUnit.unwrap(
+ keyRecord.getPrivateKeyData());
+
+ if (symKey == null) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "symmetric key unwrapping failure"));
+ }
+
+ return symKey;
+ } catch (Exception e) {
+
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "recoverSymKey() " + e.toString()));
+ }
+ }
+
+ public byte[] recoverSecurityData(KeyRecord keyRecord)
+ throws EBaseException {
+
+ byte[] decodedData = null;
+
+ try {
+ decodedData = mStorageUnit.decryptInternalPrivate(
+ keyRecord.getPrivateKeyData());
+
+ if (decodedData == null) {
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "security data unwrapping failure"));
+ }
+
+ return decodedData;
+ } catch (Exception e) {
+
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_RECOVERY_FAILED_1",
+ "recoverSecurityData() " + e.toString()));
+ }
+ }
+
+ //ToDo: This might fit in JSS.
+ private static EncryptedContentInfo
+ createEncryptedContentInfoPBEOfSymmKey(PBEAlgorithm keyGenAlg, Password password, byte[] salt,
+ int iterationCount,
+ KeyGenerator.CharToByteConverter charToByteConverter,
+ SymmetricKey symKey, CryptoToken token)
+ throws CryptoManager.NotInitializedException, NoSuchAlgorithmException,
+ InvalidKeyException, InvalidAlgorithmParameterException, TokenException,
+ CharConversionException {
+
+ if (!(keyGenAlg instanceof PBEAlgorithm)) {
+ throw new NoSuchAlgorithmException("Key generation algorithm" +
+ " is not a PBE algorithm");
+ }
+ PBEAlgorithm pbeAlg = (PBEAlgorithm) keyGenAlg;
+
+ KeyGenerator kg = token.getKeyGenerator(keyGenAlg);
+ PBEKeyGenParams pbekgParams = new PBEKeyGenParams(
+ password, salt, iterationCount);
+ if (charToByteConverter != null) {
+ kg.setCharToByteConverter(charToByteConverter);
+ }
+ kg.initialize(pbekgParams);
+ SymmetricKey key = kg.generate();
+
+ EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg();
+ AlgorithmParameterSpec params = null;
+ if (encAlg.getParameterClass().equals(IVParameterSpec.class)) {
+ params = new IVParameterSpec(kg.generatePBE_IV());
+ } else if (encAlg.getParameterClass().equals(
+ RC2ParameterSpec.class)) {
+ params = new RC2ParameterSpec(key.getStrength(),
+ kg.generatePBE_IV());
+ }
+
+ KeyWrapper wrapper = token.getKeyWrapper(
+ KeyWrapAlgorithm.DES3_CBC_PAD);
+ wrapper.initWrap(key, params);
+ byte encrypted[] = wrapper.wrap(symKey);
+
+ PBEParameter pbeParam = new PBEParameter(salt, iterationCount);
+ AlgorithmIdentifier encAlgID = new AlgorithmIdentifier(
+ keyGenAlg.toOID(), pbeParam);
+
+ EncryptedContentInfo encCI = new EncryptedContentInfo(
+ ContentInfo.DATA,
+ encAlgID,
+ new OCTET_STRING(encrypted));
+
+ return encCI;
+
+ }
+
+ private static String createEncryptedContentInfo(CryptoToken ct, SymmetricKey symKey, byte[] securityData,
+ Password password)
+ throws EBaseException {
+
+ EncryptedContentInfo cInfo = null;
+ String retData = null;
+ PBEAlgorithm keyGenAlg = PBEAlgorithm.PBE_SHA1_DES3_CBC;
+
+ byte[] encoded = null;
+ try {
+ PasswordConverter passConverter = new
+ PasswordConverter();
+ byte salt[] = { 0x01, 0x01, 0x01, 0x01 };
+ if (symKey != null) {
+
+ cInfo = createEncryptedContentInfoPBEOfSymmKey(keyGenAlg, password, salt,
+ 1,
+ passConverter,
+ symKey, ct);
+
+ } else if (securityData != null) {
+
+ cInfo = EncryptedContentInfo.createPBE(keyGenAlg, password, salt, 1, passConverter, securityData);
+ }
+
+ if(cInfo == null) {
+ throw new EBaseException("Can't create a PBE wrapped EncryptedContentInfo!");
+ }
+
+ ByteArrayOutputStream oStream = new ByteArrayOutputStream();
+ cInfo.encode(oStream);
+ encoded = oStream.toByteArray();
+ retData = com.netscape.osutil.OSUtil.BtoA(encoded);
+
+ } catch (Exception e) {
+ throw new EBaseException("Can't create a PBE wrapped EncryptedContentInfo! " + e.toString());
+ }
+
+ return retData;
+ }
+
+}
diff --git a/pki/base/kra/src/com/netscape/kra/SecurityDataService.java b/pki/base/kra/src/com/netscape/kra/SecurityDataService.java
new file mode 100644
index 000000000..7f9902eda
--- /dev/null
+++ b/pki/base/kra/src/com/netscape/kra/SecurityDataService.java
@@ -0,0 +1,170 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.kra;
+
+import java.math.BigInteger;
+import org.mozilla.jss.crypto.SymmetricKey;
+import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.profile.IEnrollProfile;
+import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.security.IStorageKeyUnit;
+import com.netscape.certsrv.security.ITransportKeyUnit;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.dbs.keydb.IKeyRecord;
+import com.netscape.certsrv.dbs.keydb.IKeyRepository;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.cms.servlet.request.KeyRequestResource;
+import com.netscape.cmscore.dbs.KeyRecord;
+
+/**
+ * This implementation implements SecurityData archival operations.
+ * <p>
+ *
+ * @version $Revision$, $Date$
+ */
+public class SecurityDataService implements IService {
+
+ private final static String DEFAULT_OWNER = "IPA Agent";
+ public final static String ATTR_KEY_RECORD = "keyRecord";
+ private final static String STATUS_ACTIVE = "active";
+
+ private IKeyRecoveryAuthority mKRA = null;
+ private ITransportKeyUnit mTransportUnit = null;
+ private IStorageKeyUnit mStorageUnit = null;
+
+ public SecurityDataService(IKeyRecoveryAuthority kra) {
+ mKRA = kra;
+ mTransportUnit = kra.getTransportKeyUnit();
+ mStorageUnit = kra.getStorageKeyUnit();
+ }
+
+ /**
+ * Performs the service of archiving Security Data.
+ * represented by this request.
+ * <p>
+ *
+ * @param request
+ * The request that needs service. The service may use
+ * attributes stored in the request, and may update the
+ * values, or store new ones.
+ * @return
+ * an indication of whether this request is still pending.
+ * 'false' means the request will wait for further notification.
+ * @exception EBaseException indicates major processing failure.
+ */
+ public boolean serviceRequest(IRequest request)
+ throws EBaseException {
+ String id = request.getRequestId().toString();
+ String clientId = request.getExtDataInString(IRequest.SECURITY_DATA_CLIENT_ID);
+ String wrappedSecurityData = request.getExtDataInString(IEnrollProfile.REQUEST_ARCHIVE_OPTIONS);
+ String dataType = request.getExtDataInString(IRequest.SECURITY_DATA_TYPE);
+
+ CMS.debug("SecurityDataService.serviceRequest. Request id: " + id);
+ CMS.debug("SecurityDataService.serviceRequest wrappedSecurityData: " + wrappedSecurityData);
+
+ String owner = getOwnerName(request);
+
+ //Check here even though restful layer checks for this.
+ if(wrappedSecurityData == null || clientId == null || dataType == null) {
+ throw new EBaseException("Bad data in SecurityDataService.serviceRequest");
+ }
+ //We need some info from the PKIArchiveOptions wrapped security data
+
+ byte[] encoded = com.netscape.osutil.OSUtil.AtoB(wrappedSecurityData);
+
+ ArchiveOptions options = ArchiveOptions.toArchiveOptions(encoded);
+
+ //Check here just in case a null ArchiveOptions makes it this far
+ if(options == null) {
+ throw new EBaseException("Problem decofing PKIArchiveOptions.");
+ }
+
+ String algStr = options.getSymmAlgOID();
+
+ SymmetricKey securitySymKey = null;
+ byte[] securityData = null;
+
+ String keyType = null;
+ if (dataType.equals(KeyRequestResource.SYMMETRIC_KEY_TYPE)) {
+ // Symmetric Key
+ keyType = KeyRequestResource.SYMMETRIC_KEY_TYPE;
+ securitySymKey = mTransportUnit.unwrap_symmetric(options.getEncSymmKey(),
+ options.getSymmAlgOID(),
+ options.getSymmAlgParams(),
+ options.getEncValue());
+
+ } else if (dataType.equals(KeyRequestResource.PASS_PHRASE_TYPE)) {
+ keyType = KeyRequestResource.PASS_PHRASE_TYPE;
+ securityData = mTransportUnit.decryptExternalPrivate(options.getEncSymmKey(),
+ options.getSymmAlgOID(),
+ options.getSymmAlgParams(),
+ options.getEncValue());
+
+ }
+
+ byte[] publicKey = null;
+ byte privateSecurityData[] = null;
+
+ if (securitySymKey != null) {
+ privateSecurityData = mStorageUnit.wrap(securitySymKey);
+ } else if (securityData != null) {
+ privateSecurityData = mStorageUnit.encryptInternalPrivate(securityData);
+ } else { // We have no data.
+ throw new EBaseException("Failed to create security data to archive!");
+ }
+ // create key record
+ KeyRecord rec = new KeyRecord(null, publicKey,
+ privateSecurityData, owner,
+ algStr, owner);
+
+ rec.set(IKeyRecord.ATTR_CLIENT_ID, clientId);
+
+ //Now we need a serial number for our new key.
+
+ if (rec.getSerialNumber() != null) {
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
+ }
+
+ IKeyRepository storage = mKRA.getKeyRepository();
+ BigInteger serialNo = storage.getNextSerialNumber();
+
+ if (serialNo == null) {
+ mKRA.log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CMSCORE_KRA_GET_NEXT_SERIAL"));
+ throw new EBaseException(CMS.getUserMessage("CMS_KRA_INVALID_STATE"));
+ }
+
+ rec.set(KeyRecord.ATTR_ID, serialNo);
+ rec.set(KeyRecord.ATTR_DATA_TYPE, keyType);
+ rec.set(KeyRecord.ATTR_STATUS, STATUS_ACTIVE);
+ request.setExtData(ATTR_KEY_RECORD, serialNo);
+
+ CMS.debug("KRA adding Security Data key record " + serialNo);
+
+ storage.addKeyRecord(rec);
+
+ return true;
+
+ }
+ //ToDo: return real owner with auth
+ private String getOwnerName(IRequest request) {
+ return DEFAULT_OWNER;
+ }
+} \ No newline at end of file