diff options
author | Andrew Wnuk <awnuk@redhat.com> | 2013-09-27 19:32:35 -0400 |
---|---|---|
committer | Andrew Wnuk <awnuk@redhat.com> | 2013-09-30 19:47:20 -0400 |
commit | 2b9fcdae818eded53ab64e5b86b947c80a262722 (patch) | |
tree | 527b0977700ebcdfdfdd723e37667456d46532af /base/kra/src/com | |
parent | d042f57747ed314030de70ee09c13d3aa7f8855c (diff) | |
download | pki-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.java | 39 | ||||
-rw-r--r-- | base/kra/src/com/netscape/kra/EnrollmentService.java | 25 | ||||
-rw-r--r-- | base/kra/src/com/netscape/kra/KRAService.java | 13 | ||||
-rw-r--r-- | base/kra/src/com/netscape/kra/StorageKeyUnit.java | 8 | ||||
-rw-r--r-- | base/kra/src/com/netscape/kra/TransportKeyUnit.java | 63 |
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) { |