summaryrefslogtreecommitdiffstats
path: root/base/kra/src/com
diff options
context:
space:
mode:
authorAndrew Wnuk <awnuk@redhat.com>2013-09-27 19:32:35 -0400
committerAndrew Wnuk <awnuk@redhat.com>2013-09-30 19:47:20 -0400
commit2b9fcdae818eded53ab64e5b86b947c80a262722 (patch)
tree527b0977700ebcdfdfdd723e37667456d46532af /base/kra/src/com
parentd042f57747ed314030de70ee09c13d3aa7f8855c (diff)
downloadpki-2b9fcdae818eded53ab64e5b86b947c80a262722.tar.gz
pki-2b9fcdae818eded53ab64e5b86b947c80a262722.tar.xz
pki-2b9fcdae818eded53ab64e5b86b947c80a262722.zip
DRM Transport Key Rotation
This patch provides basic support for DRM Transport Key Rotation described in http://pki.fedoraproject.org/wiki/DRM_Transport_Key_Rotation This patch provides implementation for tickets: - 729 - CA to include transport certificate when submitting archival request to DRM - 730 - DRM to detect presence of transport certificate attribute in submitted archival request and validate transport certificate against DRM's transport key list - 731 - DRM to provide handling for alternative transport key based on detected and validated transport certificate arriving as a part of extended archival request
Diffstat (limited to 'base/kra/src/com')
-rw-r--r--base/kra/src/com/netscape/kra/EncryptionUnit.java39
-rw-r--r--base/kra/src/com/netscape/kra/EnrollmentService.java25
-rw-r--r--base/kra/src/com/netscape/kra/KRAService.java13
-rw-r--r--base/kra/src/com/netscape/kra/StorageKeyUnit.java8
-rw-r--r--base/kra/src/com/netscape/kra/TransportKeyUnit.java63
5 files changed, 136 insertions, 12 deletions
diff --git a/base/kra/src/com/netscape/kra/EncryptionUnit.java b/base/kra/src/com/netscape/kra/EncryptionUnit.java
index 78f6e2719..c082a784f 100644
--- a/base/kra/src/com/netscape/kra/EncryptionUnit.java
+++ b/base/kra/src/com/netscape/kra/EncryptionUnit.java
@@ -70,12 +70,16 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
public abstract CryptoToken getToken();
+ public abstract CryptoToken getToken(org.mozilla.jss.crypto.X509Certificate cert);
+
public abstract CryptoToken getInternalToken();
public abstract PublicKey getPublicKey();
public abstract PrivateKey getPrivateKey();
+ public abstract PrivateKey getPrivateKey(org.mozilla.jss.crypto.X509Certificate cert);
+
/**
* Protects the private key so that it can be stored in
* internal database.
@@ -218,19 +222,29 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
* Decrypts the user private key.
*/
public byte[] decryptExternalPrivate(byte encSymmKey[],
- String symmAlgOID, byte symmAlgParams[],
- byte encValue[])
+ String symmAlgOID, byte symmAlgParams[], byte encValue[])
+ throws EBaseException {
+ return decryptExternalPrivate(encSymmKey, symmAlgOID, symmAlgParams,
+ encValue, null);
+ }
+
+ /**
+ * Decrypts the user private key.
+ */
+ public byte[] decryptExternalPrivate(byte encSymmKey[],
+ String symmAlgOID, byte symmAlgParams[], byte encValue[],
+ org.mozilla.jss.crypto.X509Certificate transCert)
throws EBaseException {
try {
CMS.debug("EncryptionUnit.decryptExternalPrivate");
- CryptoToken token = getToken();
+ CryptoToken token = getToken(transCert);
// (1) unwrap the session
KeyWrapper rsaWrap = token.getKeyWrapper(
KeyWrapAlgorithm.RSA);
- rsaWrap.initUnwrap(getPrivateKey(), null);
+ rsaWrap.initUnwrap(getPrivateKey(transCert), null);
SymmetricKey sk = rsaWrap.unwrapSymmetric(encSymmKey,
SymmetricKey.DES3, SymmetricKey.Usage.DECRYPT,
0);
@@ -346,14 +360,27 @@ public abstract class EncryptionUnit implements IEncryptionUnit {
String symmAlgOID, byte symmAlgParams[],
byte encValue[], PublicKey pubKey)
throws EBaseException {
+ return unwrap (encSymmKey, symmAlgOID, symmAlgParams,
+ encValue, pubKey, null);
+ }
+
+ /**
+ * External unwrapping. Unwraps the data using
+ * the transport private key.
+ */
+ public PrivateKey unwrap(byte encSymmKey[],
+ String symmAlgOID, byte symmAlgParams[],
+ byte encValue[], PublicKey pubKey,
+ org.mozilla.jss.crypto.X509Certificate transCert)
+ throws EBaseException {
try {
- CryptoToken token = getToken();
+ CryptoToken token = getToken(transCert);
// (1) unwrap the session
KeyWrapper rsaWrap = token.getKeyWrapper(
KeyWrapAlgorithm.RSA);
- rsaWrap.initUnwrap(getPrivateKey(), null);
+ rsaWrap.initUnwrap(getPrivateKey(transCert), null);
SymmetricKey sk = rsaWrap.unwrapSymmetric(encSymmKey,
SymmetricKey.DES3, SymmetricKey.Usage.UNWRAP,
0);
diff --git a/base/kra/src/com/netscape/kra/EnrollmentService.java b/base/kra/src/com/netscape/kra/EnrollmentService.java
index 666619cdb..3ce37d6ae 100644
--- a/base/kra/src/com/netscape/kra/EnrollmentService.java
+++ b/base/kra/src/com/netscape/kra/EnrollmentService.java
@@ -169,6 +169,17 @@ public class EnrollmentService implements IService {
if (CMS.debugOn())
CMS.debug("EnrollmentServlet: KRA services enrollment request");
+ String transportCert = request.getExtDataInString(IEnrollProfile.REQUEST_TRANSPORT_CERT);
+ if (transportCert != null && transportCert.length() > 0) {
+ CMS.debug("EnrollmentService: serviceRequest: transportCert=" + transportCert);
+ request.deleteExtData(IEnrollProfile.REQUEST_TRANSPORT_CERT);
+ } else {
+ CMS.debug("EnrollmentService: serviceRequest: Missing transport certificate");
+ }
+ org.mozilla.jss.crypto.X509Certificate tCert = mTransportUnit.verifyCertificate(transportCert);
+ CMS.debug("EnrollmentService: tCert=" + ((tCert != null)?tCert.getSerialNumber().toString()+":"+
+ tCert.getSubjectDN().toString()+":":"Invalid transport certificate"));
+
SessionContext sContext = SessionContext.getContext();
String agentId = (String) sContext.get(SessionContext.USER_ID);
AuthToken authToken = (AuthToken) sContext.get(SessionContext.AUTH_TOKEN);
@@ -214,6 +225,10 @@ public class EnrollmentService implements IService {
ArchiveOptions opts = new ArchiveOptions(aOpts[i].mAO);
if (allowEncDecrypt_archival == true) {
+ if (tCert == null) {
+ CMS.debug("EnrollmentService: Invalid transport certificate: "+transportCert);
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_INVALID_TRANSPORT_CERT"));
+ }
if (statsSub != null) {
statsSub.startTiming("decrypt_user_key");
}
@@ -224,7 +239,8 @@ public class EnrollmentService implements IService {
opts.getEncSymmKey(),
opts.getSymmAlgOID(),
opts.getSymmAlgParams(),
- opts.getEncValue());
+ opts.getEncValue(),
+ tCert);
if (statsSub != null) {
statsSub.endTiming("decrypt_user_key");
}
@@ -282,6 +298,10 @@ public class EnrollmentService implements IService {
PublicKey pubkey = null;
org.mozilla.jss.crypto.PrivateKey entityPrivKey = null;
if ( allowEncDecrypt_archival == false) {
+ if (tCert == null) {
+ CMS.debug("EnrollmentService: Invalid transport certificate: "+transportCert);
+ throw new EKRAException(CMS.getUserMessage("CMS_KRA_INVALID_TRANSPORT_CERT"));
+ }
try {
pubkey = X509Key.parsePublicKey (new DerValue(publicKeyData));
} catch (Exception e) {
@@ -295,7 +315,8 @@ public class EnrollmentService implements IService {
opts.getSymmAlgOID(),
opts.getSymmAlgParams(),
opts.getEncValue(),
- pubkey);
+ pubkey,
+ tCert);
} // !allowEncDecrypt_archival
/* Bugscape #54948 - verify public and private key before archiving key */
diff --git a/base/kra/src/com/netscape/kra/KRAService.java b/base/kra/src/com/netscape/kra/KRAService.java
index 987d17b6b..216f2ff6a 100644
--- a/base/kra/src/com/netscape/kra/KRAService.java
+++ b/base/kra/src/com/netscape/kra/KRAService.java
@@ -25,6 +25,7 @@ import com.netscape.certsrv.kra.IKeyRecoveryAuthority;
import com.netscape.certsrv.logging.ILogger;
import com.netscape.certsrv.request.IRequest;
import com.netscape.certsrv.request.IService;
+import com.netscape.certsrv.request.RequestStatus;
import com.netscape.cmscore.util.Debug;
/**
@@ -93,9 +94,15 @@ public class KRAService implements IService {
} catch (EBaseException e) {
r.setExtData(IRequest.RESULT, IRequest.RES_ERROR);
r.setExtData(IRequest.ERROR, e);
- // return true;
- // #546508
- return false;
+ CMS.debug("KRAService serviceRequest EBaseException:" + e.getMessage());
+ if ((e.getMessage()).equals(CMS.getUserMessage("CMS_KRA_INVALID_TRANSPORT_CERT"))) {
+ r.setRequestStatus(RequestStatus.REJECTED);
+ return true;
+ } else {
+ // return true;
+ // #546508
+ return false;
+ }
}
}
}
diff --git a/base/kra/src/com/netscape/kra/StorageKeyUnit.java b/base/kra/src/com/netscape/kra/StorageKeyUnit.java
index 387e20bf7..30a0317ac 100644
--- a/base/kra/src/com/netscape/kra/StorageKeyUnit.java
+++ b/base/kra/src/com/netscape/kra/StorageKeyUnit.java
@@ -696,6 +696,10 @@ public class StorageKeyUnit extends EncryptionUnit implements
}
}
+ public CryptoToken getToken(org.mozilla.jss.crypto.X509Certificate cert) {
+ return getToken();
+ }
+
/**
* Returns the certificate blob.
*/
@@ -723,6 +727,10 @@ public class StorageKeyUnit extends EncryptionUnit implements
}
}
+ public PrivateKey getPrivateKey(org.mozilla.jss.crypto.X509Certificate cert) {
+ return getPrivateKey();
+ }
+
/**
* Verifies the integrity of the given key pairs.
*/
diff --git a/base/kra/src/com/netscape/kra/TransportKeyUnit.java b/base/kra/src/com/netscape/kra/TransportKeyUnit.java
index e2077212a..2efdac7ad 100644
--- a/base/kra/src/com/netscape/kra/TransportKeyUnit.java
+++ b/base/kra/src/com/netscape/kra/TransportKeyUnit.java
@@ -45,12 +45,14 @@ public class TransportKeyUnit extends EncryptionUnit implements
ISubsystem, ITransportKeyUnit {
public static final String PROP_NICKNAME = "nickName";
+ public static final String PROP_NEW_NICKNAME = "newNickName";
public static final String PROP_SIGNING_ALGORITHM = "signingAlgorithm";
// private RSAPublicKey mPublicKey = null;
// private RSAPrivateKey mPrivateKey = null;
private IConfigStore mConfig = null;
private org.mozilla.jss.crypto.X509Certificate mCert = null;
+ private org.mozilla.jss.crypto.X509Certificate mNewCert = null;
private CryptoManager mManager = null;
/**
@@ -91,6 +93,11 @@ public class TransportKeyUnit extends EncryptionUnit implements
Signature signer = token.getSignatureContext(sigalg);
signer.initSign(getPrivateKey());
+ String newNickName = getNewNickName();
+ if (newNickName != null && newNickName.length() > 0) {
+ mNewCert = mManager.findCertByNickname(newNickName);
+ }
+
} catch (org.mozilla.jss.CryptoManager.NotInitializedException e) {
throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
@@ -117,6 +124,10 @@ public class TransportKeyUnit extends EncryptionUnit implements
return getPrivateKey().getOwningToken();
}
+ public CryptoToken getToken(org.mozilla.jss.crypto.X509Certificate cert) {
+ return getPrivateKey(cert).getOwningToken();
+ }
+
/**
* Starts up this subsystem.
*/
@@ -144,6 +155,15 @@ public class TransportKeyUnit extends EncryptionUnit implements
mConfig.putString(PROP_NICKNAME, str);
}
+ private String getNewNickName() {
+ String newNickName = null;
+ try {
+ newNickName = mConfig.getString(PROP_NEW_NICKNAME);
+ } catch (Exception e) {
+ }
+ return newNickName;
+ }
+
public String getSigningAlgorithm() throws EBaseException {
return mConfig.getString(PROP_SIGNING_ALGORITHM);
}
@@ -171,13 +191,54 @@ public class TransportKeyUnit extends EncryptionUnit implements
return mCert;
}
+ public org.mozilla.jss.crypto.X509Certificate getNewCertificate() {
+ return mNewCert;
+ }
+
+ public org.mozilla.jss.crypto.X509Certificate verifyCertificate(String transportCert) {
+ org.mozilla.jss.crypto.X509Certificate cert = null;
+ if (transportCert != null && transportCert.length() > 0) {
+ String certB64 = null;
+ if (mCert != null) {
+ try {
+ certB64 = ((CMS.BtoA(mCert.getEncoded())).replaceAll("\n", "")).replaceAll("\r", "");
+ if (transportCert.equals(certB64)) {
+ cert = mCert;
+ CMS.debug("TransportKeyUnit: Transport certificate verified");
+ }
+ } catch (Exception e) {
+ }
+ }
+ if (cert == null && mNewCert != null) {
+ try {
+ certB64 = ((CMS.BtoA(mNewCert.getEncoded())).replaceAll("\n", "")).replaceAll("\r", "");
+ if (transportCert.equals(certB64)) {
+ cert = mNewCert;
+ CMS.debug("TransportKeyUnit: New transport certificate verified");
+ }
+ } catch (Exception e) {
+ }
+ }
+ } else {
+ cert = mCert;
+ }
+ return cert;
+ }
+
public PublicKey getPublicKey() {
return mCert.getPublicKey();
}
public PrivateKey getPrivateKey() {
+ return getPrivateKey(mCert);
+ }
+
+ public PrivateKey getPrivateKey(org.mozilla.jss.crypto.X509Certificate cert) {
+ if (cert == null) {
+ cert = mCert;
+ }
try {
- return mManager.findPrivKeyByCert(mCert);
+ return mManager.findPrivKeyByCert(cert);
} catch (TokenException e) {
return null;
} catch (ObjectNotFoundException e) {