diff options
Diffstat (limited to 'pki')
31 files changed, 1764 insertions, 305 deletions
diff --git a/pki/base/ca/shared/conf/index.ldif b/pki/base/ca/shared/conf/index.ldif index c1eecc19d..4bc8aebf9 100644 --- a/pki/base/ca/shared/conf/index.ldif +++ b/pki/base/ca/shared/conf/index.ldif @@ -19,6 +19,27 @@ nsIndexType: eq nsSystemIndex: false cn: publicKeyData +dn: cn=clientId,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: clientId + +dn: cn=dataType,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: dataType + +dn: cn=status,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: status + dn: cn=description,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config objectClass: top objectClass: nsIndex diff --git a/pki/base/ca/shared/conf/schema.ldif b/pki/base/ca/shared/conf/schema.ldif index caf71e965..70578e21c 100644 --- a/pki/base/ca/shared/conf/schema.ldif +++ b/pki/base/ca/shared/conf/schema.ldif @@ -161,6 +161,21 @@ attributeTypes: ( keySize-oid NAME 'keySize' DESC 'CMS defined attribute' SYNTAX dn: cn=schema changetype: modify add: attributeTypes +attributeTypes: ( clientId-oid NAME 'clientId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( dataType-oid NAME 'dataType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( status-oid NAME 'status' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes attributeTypes: ( keyState-oid NAME 'keyState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema @@ -446,7 +461,7 @@ objectClasses: ( userDetails-oid NAME 'userDetails' DESC 'CMS defined class' SUP dn: cn=schema changetype: modify add: objectClasses -objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy ) X-ORIGIN 'user defined' ) +objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy $ clientId $ dataType $ status ) X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java index 010661d8b..7da212469 100644 --- a/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java +++ b/pki/base/common/src/com/netscape/certsrv/dbs/keydb/IKeyRecord.java @@ -40,6 +40,10 @@ public interface IKeyRecord { public static final String ATTR_MODIFY_TIME = "keyModifyTime"; public static final String ATTR_META_INFO = "keyMetaInfo"; public static final String ATTR_ARCHIVED_BY = "keyArchivedBy"; + public static final String ATTR_CLIENT_ID = "clientId"; + public static final String ATTR_DATA_TYPE = "dataType"; + public static final String ATTR_STATUS = "status"; + // key state public static final String STATUS_ANY = "ANY"; @@ -86,10 +90,35 @@ public interface IKeyRecord { public Integer getKeySize() throws EBaseException; /** + * Retrieves client ID. + * + * @return client id + * @exception EBaseException failed to retrieve client id + */ + public String getClientId() throws EBaseException; + + /** + * Retrieves key data type. + * + * @return data type + * @exception EBaseException failed to retrieve data type + */ + public String getDataType() throws EBaseException; + + /** + * Retrieves key status. + * + * @return key status + * @exception EBaseException failed to retrieve key status + */ + public String getKeyStatus() throws EBaseException; + + /** * Retrieves archiver identifier. * * @return archiver uid */ + public String getArchivedBy(); /** diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequest.java b/pki/base/common/src/com/netscape/certsrv/request/IRequest.java index 19b830898..ec1f43fb3 100644 --- a/pki/base/common/src/com/netscape/certsrv/request/IRequest.java +++ b/pki/base/common/src/com/netscape/certsrv/request/IRequest.java @@ -69,8 +69,6 @@ public interface IRequest { public static final String CLA_UNCERT4CRL_REQUEST = "uncert4crl"; public static final String NETKEY_KEYGEN_REQUEST = "netkeyKeygen"; public static final String NETKEY_KEYRECOVERY_REQUEST = "netkeyKeyRecovery"; - public static final String SECURITY_DATA_ENROLLMENT_REQUEST = "securityDataEnrollment"; - public static final String SECURITY_DATA_RECOVERY_REQUEST = "securityDataRecovery"; public static final String REQUESTOR_NAME = "csrRequestorName"; public static final String REQUESTOR_PHONE = "csrRequestorPhone"; @@ -152,6 +150,18 @@ public interface IRequest { public final static String NETKEY_ATTR_USER_CERT = "cert"; public final static String NETKEY_ATTR_KEY_SIZE = "keysize"; + //Security Data request attributes + public static final String SECURITY_DATA_ENROLLMENT_REQUEST = "securityDataEnrollment"; + public static final String SECURITY_DATA_RECOVERY_REQUEST = "securityDataRecovery"; + public static final String SECURITY_DATA_CLIENT_ID = "clientID"; + public static final String SECURITY_DATA_TYPE = "dataType"; + public static final String SECURITY_DATA_STATUS = "status"; + public static final String SECURITY_DATA_TRANS_SESS_KEY = "transWrappedSessionKey"; + public static final String SECURITY_DATA_SESS_PASS_PHRASE = "sessionWrappedPassphrase"; + public static final String SECURITY_DATA_IV_STRING_IN = "iv_in"; + public static final String SECURITY_DATA_IV_STRING_OUT = "iv_out"; + + // requestor type values. public static final String REQUESTOR_EE = "EE"; public static final String REQUESTOR_RA = "RA"; diff --git a/pki/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java b/pki/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java index e318188a6..0a526e582 100644 --- a/pki/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java +++ b/pki/base/common/src/com/netscape/certsrv/security/IEncryptionUnit.java @@ -20,6 +20,7 @@ package com.netscape.certsrv.security; import java.security.PublicKey; import org.mozilla.jss.crypto.PrivateKey; +import org.mozilla.jss.crypto.SymmetricKey; import com.netscape.certsrv.base.EBaseException; @@ -48,6 +49,16 @@ public interface IEncryptionUnit extends IToken { public byte[] wrap(PrivateKey priKey) throws EBaseException; /** + * Wraps data. The given key will be wrapped by the + * private key in this unit. + * + * @param symKey symmetric key to be wrapped + * @return wrapped data + * @exception EBaseException failed to wrap + */ + public byte[] wrap(SymmetricKey symKey) throws EBaseException; + + /** * Verifies the given key pair. * * @param publicKey public key @@ -74,6 +85,46 @@ public interface IEncryptionUnit extends IToken { throws EBaseException; /** + * Unwraps symmetric key data. This method rebuilds the symmetric key by + * unwrapping the private data blob. + * + * @param wrappedKeyData symmetric key data wrapped up with session key + * @return Symmetric key object + * @exception EBaseException failed to unwrap + */ + + public SymmetricKey unwrap(byte wrappedKeyData[]) + throws EBaseException; + + /** + * Unwraps symmetric key . This method + * unwraps the symmetric key. + * + * @param sessionKey session key that unwrap the symmetric key + * @param symmAlgOID symmetric algorithm + * @param symmAlgParams symmetric algorithm parameters + * @param symmetricKey symmetric key data + * @return Symmetric key object + * @exception EBaseException failed to unwrap + */ + + public SymmetricKey unwrap_symmetric(byte sessionKey[], String symmAlgOID, + byte symmAlgParams[], byte symmetricKey[]) + throws EBaseException; + + /** + * Unwraps symmetric key . This method + * unwraps the symmetric key. + * + * @param encSymmKey wrapped symmetric key to be unwrapped + * @return Symmetric key object + * @exception EBaseException failed to unwrap + */ + + public SymmetricKey unwrap_sym(byte encSymmKey[], + SymmetricKey.Usage usage); + + /** * Unwraps data. This method rebuilds the private key by * unwrapping the private key data. * diff --git a/pki/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java b/pki/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java index 0a012e8a6..6e1c7ab4a 100644 --- a/pki/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java +++ b/pki/base/common/src/com/netscape/certsrv/security/ITransportKeyUnit.java @@ -41,16 +41,71 @@ public interface ITransportKeyUnit extends IEncryptionUnit { */ public org.mozilla.jss.crypto.X509Certificate getCertificate(); + /** + * Unwraps symmetric key . This method + * unwraps the symmetric key. + * + * @param encSymmKey wrapped symmetric key to be unwrapped + * @param usage Key usage for unwrapped key. + * @return Symmetric key object + * @exception EBaseException failed to unwrap + */ + + public SymmetricKey unwrap_sym(byte encSymmKey[], SymmetricKey.Usage usage); + + /** + * Unwraps symmetric key . This method + * unwraps the symmetric key. + * + * @param encSymmKey wrapped symmetric key to be unwrapped + * @return Symmetric key object + * @exception EBaseException failed to unwrap + */ + public SymmetricKey unwrap_sym(byte encSymmKey[]); + /** + * Unwraps symmetric key for encrypton . This method + * unwraps the symmetric key. + * + * @param encSymmKey wrapped symmetric key to be unwrapped + * @return Symmetric key object + * @exception EBaseException failed to unwrap + */ + public SymmetricKey unwrap_encrypt_sym(byte encSymmKey[]); + /** + * Unwraps temporary private key . This method + * unwraps the temporary private key. + * + * @param wrappedKeyData wrapped private key to be unwrapped + * @param pubKey public key + * @return Private key object + * @exception EBaseException failed to unwrap + */ + public PrivateKey unwrap_temp(byte wrappedKeyData[], PublicKey pubKey) throws EBaseException; + /** + * Returns this Unit's crypto token object. + * @return CryptoToken object. + */ public CryptoToken getToken(); + /** + * Returns this Unit's signing algorithm in String format. + * @return String of signing algorithm + * @throws EBaseException + */ + public String getSigningAlgorithm() throws EBaseException; + /** + * Sets this Unit's signing algorithm. + * @param str String of signing algorithm to set. + * @throws EBaseException + */ public void setSigningAlgorithm(String str) throws EBaseException; } diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java b/pki/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java index 887820c3f..4888d609f 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java +++ b/pki/base/common/src/com/netscape/cms/servlet/key/KeyResourceService.java @@ -18,6 +18,7 @@ package com.netscape.cms.servlet.key; + import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; @@ -73,11 +74,6 @@ public class KeyResourceService extends CMSResourceService implements KeyResourc } private String validateRequest(RecoveryRequestData data) { - // confirm that at least one wrapping method exists - if ((data.getTransWrappedSessionKey() == null) && (data.getTransWrappedSessionKey() == null)) { - // log error - throw new WebApplicationException(Response.Status.BAD_REQUEST); - } // confirm request exists String reqId = data.getRequestId(); @@ -85,6 +81,14 @@ public class KeyResourceService extends CMSResourceService implements KeyResourc // log error throw new WebApplicationException(Response.Status.BAD_REQUEST); } + + // confirm that at least one wrapping method exists + // There must be at least the wrapped session key method. + if ((data.getTransWrappedSessionKey() == null)) { + // log error + throw new WebApplicationException(Response.Status.BAD_REQUEST); + } + KeyRequestDAO reqDAO = new KeyRequestDAO(); KeyRequestInfo reqInfo; try { @@ -117,7 +121,7 @@ public class KeyResourceService extends CMSResourceService implements KeyResourc } String keyURL = reqInfo.getKeyURL(); - return keyURL.substring(keyURL.lastIndexOf("/")); + return keyURL.substring(keyURL.lastIndexOf("/") + 1); } } diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java b/pki/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java index 471abc161..b5032fa86 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java +++ b/pki/base/common/src/com/netscape/cms/servlet/key/KeysResourceService.java @@ -76,7 +76,7 @@ public class KeysResourceService extends CMSResourceService implements KeysResou } if (clientID != null) { - filter += "(clientID=\'" + clientID + "\')"; + filter += "(clientID=" + clientID + ")"; matches ++; } diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java index 5fd17a333..fd9d2d2c0 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java +++ b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyDAO.java @@ -20,8 +20,11 @@ package com.netscape.cms.servlet.key.model; import java.math.BigInteger; import java.util.ArrayList; import java.util.Enumeration; +import java.util.Hashtable; import java.util.List; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; import com.netscape.certsrv.apps.CMS; @@ -29,7 +32,12 @@ import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.dbs.keydb.IKeyRecord; import com.netscape.certsrv.dbs.keydb.IKeyRepository; import com.netscape.certsrv.kra.IKeyRecoveryAuthority; +import com.netscape.certsrv.request.IRequest; +import com.netscape.certsrv.request.IRequestQueue; +import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestStatus; import com.netscape.cms.servlet.request.model.RecoveryRequestData; +import com.netscape.kra.SecurityDataRecoveryService; /** * @author alee @@ -38,11 +46,13 @@ import com.netscape.cms.servlet.request.model.RecoveryRequestData; public class KeyDAO { private IKeyRepository repo; + private IKeyRecoveryAuthority kra; + private IRequestQueue queue; public KeyDAO() { - IKeyRecoveryAuthority kra = null; kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( "kra" ); repo = kra.getKeyRepository(); + queue = kra.getRequestQueue(); } /** * Returns list of keys meeting specified search filter. @@ -79,18 +89,100 @@ public class KeyDAO { } public KeyData getKey(String keyId, RecoveryRequestData data) throws EBaseException { - KeyData keyData = null; + KeyData keyData; BigInteger serial = new BigInteger(keyId); - // get wrapped key + String rId = data.getRequestId(); + + String transWrappedSessionKey; + String sessionWrappedPassphrase; + + IRequest request = queue.findRequest(new RequestId(rId)); + + if (request == null) { + return null; + } + + // get wrapped key IKeyRecord rec = repo.readKeyRecord(serial); if (rec == null) { - // key does not exist - // log the error return null; } - // TODO unwrap the key and wrap with the credential in RecoveryRequestData - // need to figure out how to do this with jmagne + + Hashtable<String, Object> requestParams = kra.getVolatileRequest( + request.getRequestId()); + + if(requestParams == null) { + throw new EBaseException("Can't obtain Volatile requestParams in KeyDAO.getKey!"); + } + + String sessWrappedKeyData = (String) requestParams.get(SecurityDataRecoveryService.ATTR_SESS_WRAPPED_DATA); + String passWrappedKeyData = (String) requestParams.get(SecurityDataRecoveryService.ATTR_PASS_WRAPPED_DATA); + String nonceData = (String) requestParams.get(IRequest.SECURITY_DATA_IV_STRING_OUT); + + if (sessWrappedKeyData != null || passWrappedKeyData != null) { + //The recovery process has already placed a valid recovery + //package, either session key wrapped or pass wrapped, into the request. + //Request already has been processed. + keyData = new KeyData(); + + } else { + // The request has not yet been processed, let's see if the RecoveryRequestData contains + // the info now needed to process the recovery request. + + transWrappedSessionKey = data.getTransWrappedSessionKey(); + sessionWrappedPassphrase = data.getSessionWrappedPassphrase(); + nonceData = data.getNonceData(); + + if(transWrappedSessionKey == null) { + //There must be at least a transWrappedSessionKey input provided. + //The command AND the request have provided insufficient data, end of the line. + throw new EBaseException("Can't retrieve key, insufficient input data!"); + } + + if (sessionWrappedPassphrase != null) { + requestParams.put(IRequest.SECURITY_DATA_SESS_PASS_PHRASE, sessionWrappedPassphrase); + } + + if (transWrappedSessionKey != null) { + requestParams.put(IRequest.SECURITY_DATA_TRANS_SESS_KEY, transWrappedSessionKey); + } + + if (nonceData != null) { + requestParams.put(IRequest.SECURITY_DATA_IV_STRING_IN, nonceData); + } + + try { + // Has to be in this state or it won't go anywhere. + request.setRequestStatus(RequestStatus.BEGIN); + queue.processRequest(request); + } catch (EBaseException e) { + kra.destroyVolatileRequest(request.getRequestId()); + throw new EBaseException(e.toString()); + } + + nonceData = null; + keyData = new KeyData(); + + sessWrappedKeyData = (String) requestParams.get(SecurityDataRecoveryService.ATTR_SESS_WRAPPED_DATA); + passWrappedKeyData = (String) requestParams.get(SecurityDataRecoveryService.ATTR_PASS_WRAPPED_DATA); + nonceData = (String) requestParams.get(IRequest.SECURITY_DATA_IV_STRING_OUT); + + } + + if (sessWrappedKeyData != null) { + keyData.setWrappedPrivateData(sessWrappedKeyData); + } + if (passWrappedKeyData != null) { + keyData.setWrappedPrivateData(passWrappedKeyData); + } + if (nonceData != null) { + keyData.setNonceData(nonceData); + } + + kra.destroyVolatileRequest(request.getRequestId()); + + queue.markAsServiced(request); return keyData; } @@ -103,9 +195,6 @@ public class KeyDAO { UriBuilder keyBuilder = uriInfo.getBaseUriBuilder(); keyBuilder.path("/key/" + serial); ret.setKeyURL(keyBuilder.build().toString()); - - // clientID = rec.getClientID(); - // TODO add other fields as needed return ret; } diff --git a/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java index 0e6e80dec..4f303e27d 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java +++ b/pki/base/common/src/com/netscape/cms/servlet/key/model/KeyData.java @@ -36,6 +36,9 @@ public class KeyData { @XmlElement String wrappedPrivateData; + @XmlElement + String nonceData; + public KeyData() { // required for JAXB (defaults) } @@ -54,4 +57,20 @@ public class KeyData { this.wrappedPrivateData = wrappedPrivateData; } + /** + * @return the nonceData + */ + + public String getNonceData() { + return nonceData; + } + + /** + * @param nonceData the nonceData to set + */ + + public void setNonceData(String nonceData) { + this.nonceData = nonceData; + } + } diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java index 146b03d89..656768f02 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java +++ b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResource.java @@ -14,6 +14,9 @@ import com.netscape.cms.servlet.request.model.RecoveryRequestData; @Path("/keyrequest") public interface KeyRequestResource { + public final String SYMMETRIC_KEY_TYPE = "symmetricKey"; + public final String PASS_PHRASE_TYPE = "passPhrase"; + public final String ASYMMETRIC_KEY_TYPE = "asymmetricKey"; /** * Used to retrieve key request info for a specific request diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java index da08c4d69..e18407727 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java +++ b/pki/base/common/src/com/netscape/cms/servlet/request/KeyRequestResourceService.java @@ -69,6 +69,14 @@ public class KeyRequestResourceService extends CMSResourceService implements Key public KeyRequestInfo archiveKey(ArchivalRequestData data) { // auth and authz + // Catch this before internal server processing has to deal with it + + if (data == null || data.getClientId() == null + || data.getWrappedPrivateData() == null + || data.getDataType() == null) { + throw new WebApplicationException(Response.Status.BAD_REQUEST); + } + KeyRequestDAO dao = new KeyRequestDAO(); KeyRequestInfo info; try { @@ -89,6 +97,15 @@ public class KeyRequestResourceService extends CMSResourceService implements Key public KeyRequestInfo recoverKey(RecoveryRequestData data) { // auth and authz + + //Check for entirely illegal data combination here + //Catch this before the internal server processing has to deal with it + //If data has been provided, we need at least the wrapped session key, + //or the command is invalid. + if (data == null || (data.getTransWrappedSessionKey() == null + && data.getSessionWrappedPassphrase() != null)) { + throw new WebApplicationException(Response.Status.BAD_REQUEST); + } KeyRequestDAO dao = new KeyRequestDAO(); KeyRequestInfo info; try { @@ -102,6 +119,9 @@ public class KeyRequestResourceService extends CMSResourceService implements Key } public void approveRequest(@PathParam("id") String id) { + if ( id == null) { + throw new WebApplicationException(Response.Status.BAD_REQUEST); + } // auth and authz KeyRequestDAO dao = new KeyRequestDAO(); try { @@ -114,6 +134,9 @@ public class KeyRequestResourceService extends CMSResourceService implements Key } public void rejectRequest(@PathParam("id") String id) { + if ( id == null) { + throw new WebApplicationException(Response.Status.BAD_REQUEST); + } // auth and authz KeyRequestDAO dao = new KeyRequestDAO(); try { @@ -126,6 +149,9 @@ public class KeyRequestResourceService extends CMSResourceService implements Key } public void cancelRequest(@PathParam("id") String id) { + if ( id == null) { + throw new WebApplicationException(Response.Status.BAD_REQUEST); + } // auth and authz KeyRequestDAO dao = new KeyRequestDAO(); try { diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java b/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java index 16da23d8b..623fa941f 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java +++ b/pki/base/common/src/com/netscape/cms/servlet/request/model/KeyRequestDAO.java @@ -19,9 +19,12 @@ package com.netscape.cms.servlet.request.model; import java.net.URI; import java.util.ArrayList; +import java.util.Hashtable; import java.util.List; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; @@ -35,6 +38,9 @@ import com.netscape.certsrv.request.IRequestVirtualList; import com.netscape.certsrv.request.RequestId; import com.netscape.certsrv.request.RequestStatus; import com.netscape.cms.servlet.base.model.Link; +import com.netscape.cms.servlet.key.model.KeyDAO; +import com.netscape.cms.servlet.key.model.KeyDataInfos; +import com.netscape.certsrv.profile.IEnrollProfile; /** * @author alee @@ -42,6 +48,9 @@ import com.netscape.cms.servlet.base.model.Link; */ public class KeyRequestDAO { private IRequestQueue queue; + private IKeyRecoveryAuthority kra; + + private static String REQUEST_ARCHIVE_OPTIONS = IEnrollProfile.REQUEST_ARCHIVE_OPTIONS; private String[] vlvFilters = { "(requeststate=*)", "(requesttype=enrollment)", @@ -56,8 +65,9 @@ public class KeyRequestDAO { "(&(requeststate=complete)(requesttype=recovery))" }; + public static final String ATTR_SERIALNO = "serialNumber"; + public KeyRequestDAO() { - IKeyRecoveryAuthority kra = null; kra = ( IKeyRecoveryAuthority ) CMS.getSubsystem( "kra" ); queue = kra.getRequestQueue(); } @@ -104,6 +114,10 @@ public class KeyRequestDAO { // We should think about whether they should be, or if we need to // limit the number of results returned. IRequestList requests = queue.listRequestsByFilter(filter, maxResults, maxTime); + + if (requests == null) { + return null; + } while (requests.hasMoreElements()) { RequestId rid = (RequestId) requests.nextElement(); IRequest request = queue.findRequest(rid); @@ -168,10 +182,26 @@ public class KeyRequestDAO { * @throws EBaseException */ public KeyRequestInfo submitRequest(ArchivalRequestData data, UriInfo uriInfo) throws EBaseException { + String clientId = data.getClientId(); + String wrappedSecurityData = data.getWrappedPrivateData(); + String dataType = data.getDataType(); + + boolean keyExists = doesKeyExist(clientId, "active", uriInfo); + + if(keyExists == true) { + throw new EBaseException("Can not archive already active existing key!"); + } + IRequest request = queue.newRequest(IRequest.SECURITY_DATA_ENROLLMENT_REQUEST); - //TODO : - //set data using request.setExtData(field, data) + + request.setExtData(REQUEST_ARCHIVE_OPTIONS, wrappedSecurityData); + request.setExtData(IRequest.SECURITY_DATA_CLIENT_ID, clientId); + request.setExtData(IRequest.SECURITY_DATA_TYPE, dataType); + queue.processRequest(request); + + queue.markAsServiced(request); + return createKeyRequestInfo(request, uriInfo); } /** @@ -181,25 +211,61 @@ public class KeyRequestDAO { * @throws EBaseException */ public KeyRequestInfo submitRequest(RecoveryRequestData data, UriInfo uriInfo) throws EBaseException { - IRequest request = queue.newRequest(IRequest.SECURITY_DATA_RECOVERY_REQUEST); + // set data using request.setExtData(field, data) + + String wrappedSessionKeyStr = data.getTransWrappedSessionKey(); + String wrappedPassPhraseStr = data.getSessionWrappedPassphrase(); + String nonceDataStr = data.getNonceData(); + + IRequest request = queue.newRequest(IRequest.SECURITY_DATA_RECOVERY_REQUEST); + + String keyId = data.getKeyId(); + + Hashtable<String, Object> requestParams; + requestParams = kra.createVolatileRequest(request.getRequestId()); + + if(requestParams == null) { + throw new EBaseException("Can not create Volatile params in submitRequest!"); + } + + CMS.debug("Create volatile params for recovery request. " + requestParams); + + if (wrappedPassPhraseStr != null) { + requestParams.put(IRequest.SECURITY_DATA_SESS_PASS_PHRASE, wrappedPassPhraseStr); + } + + if (wrappedSessionKeyStr != null) { + requestParams.put(IRequest.SECURITY_DATA_TRANS_SESS_KEY, wrappedSessionKeyStr); + } + + if (nonceDataStr != null) { + requestParams.put(IRequest.SECURITY_DATA_IV_STRING_IN, nonceDataStr); + } + + request.setExtData(ATTR_SERIALNO,keyId); + queue.processRequest(request); + return createKeyRequestInfo(request, uriInfo); } public void approveRequest(String id) throws EBaseException { IRequest request = queue.findRequest(new RequestId(id)); request.setRequestStatus(RequestStatus.APPROVED); + queue.updateRequest(request); } public void rejectRequest(String id) throws EBaseException { IRequest request = queue.findRequest(new RequestId(id)); request.setRequestStatus(RequestStatus.CANCELED); + queue.updateRequest(request); } public void cancelRequest(String id) throws EBaseException { IRequest request = queue.findRequest(new RequestId(id)); request.setRequestStatus(RequestStatus.REJECTED); + queue.updateRequest(request); } public KeyRequestInfo createKeyRequestInfo(IRequest request, UriInfo uriInfo) { @@ -229,4 +295,27 @@ public class KeyRequestDAO { } return false; } + + //We only care if the key exists or not + private boolean doesKeyExist(String clientId, String keyStatus, UriInfo uriInfo) { + boolean ret = false; + String state = "active"; + + KeyDAO keys = new KeyDAO(); + + KeyDataInfos existingKeys; + String filter = "(&(" + IRequest.SECURITY_DATA_CLIENT_ID + "=" + clientId + ")" + + "(" + IRequest.SECURITY_DATA_STATUS + "=" + state + "))"; + try { + existingKeys = keys.listKeys(filter, 1, 10, uriInfo); + + if(existingKeys != null && existingKeys.getKeyInfos().size() > 0) { + ret = true; + } + } catch (EBaseException e) { + ret= false; + } + + return ret; + } } diff --git a/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java b/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java index c84d8f491..ae8417542 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java +++ b/pki/base/common/src/com/netscape/cms/servlet/request/model/RecoveryRequestData.java @@ -39,6 +39,7 @@ public class RecoveryRequestData { private static final String REQUEST_ID = "requestId"; private static final String TRANS_WRAPPED_SESSION_KEY = "transWrappedSessionKey"; private static final String SESSION_WRAPPED_PASSPHRASE = "sessionWrappedPassphrase"; + private static final String NONCE_DATA = "nonceData"; @XmlElement protected String keyId; @@ -52,6 +53,9 @@ public class RecoveryRequestData { @XmlElement protected String sessionWrappedPassphrase; + @XmlElement + protected String nonceData; + public RecoveryRequestData() { // required for JAXB (defaults) } @@ -61,6 +65,7 @@ public class RecoveryRequestData { requestId = form.getFirst(REQUEST_ID); transWrappedSessionKey = form.getFirst(TRANS_WRAPPED_SESSION_KEY); sessionWrappedPassphrase = form.getFirst(SESSION_WRAPPED_PASSPHRASE); + nonceData = form.getFirst(NONCE_DATA); } /** @@ -119,4 +124,20 @@ public class RecoveryRequestData { this.sessionWrappedPassphrase = sessionWrappedPassphrase; } + /** + * @return nonceData + */ + + public String getNonceData() { + return nonceData; + } + + /** + * @param nonceData the nonceData to set + */ + + public void setNonceData(String nonceData) { + this.nonceData = nonceData; + } + } diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java index ca9db779b..50b3badc3 100644 --- a/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java +++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyDBSchema.java @@ -45,4 +45,7 @@ public class KeyDBSchema { public static final String LDAP_ATTR_PUBLIC_KEY_FORMAT = "publicKeyFormat"; public static final String LDAP_ATTR_ARCHIVED_BY = "archivedBy"; + public static final String LDAP_ATTR_CLIENT_ID = "clientId"; + public static final String LDAP_ATTR_STATUS = "status"; + public static final String LDAP_ATTR_DATA_TYPE = "dataType"; } diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java index 8f2888715..f7773e3fa 100644 --- a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java +++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRecord.java @@ -56,6 +56,10 @@ public class KeyRecord implements IDBObj, IKeyRecord { private Date mCreateTime = null; private Date mModifyTime = null; private String mArchivedBy = null; + private String mClientId = null; + private String mStatus = null; + private String mDataType = null; + protected static Vector<String> mNames = new Vector<String>(); static { @@ -71,6 +75,9 @@ public class KeyRecord implements IDBObj, IKeyRecord { mNames.addElement(ATTR_CREATE_TIME); mNames.addElement(ATTR_MODIFY_TIME); mNames.addElement(ATTR_ARCHIVED_BY); + mNames.addElement(ATTR_CLIENT_ID); + mNames.addElement(ATTR_STATUS); + mNames.addElement(ATTR_DATA_TYPE); } /** @@ -128,6 +135,12 @@ public class KeyRecord implements IDBObj, IKeyRecord { mModifyTime = (Date) object; } else if (name.equalsIgnoreCase(ATTR_ARCHIVED_BY)) { mArchivedBy = (String) object; + } else if (name.equalsIgnoreCase(ATTR_CLIENT_ID)) { + mClientId = (String) object; + } else if (name.equalsIgnoreCase(ATTR_DATA_TYPE)) { + mDataType = (String) object; + } else if (name.equalsIgnoreCase(ATTR_STATUS)) { + mStatus = (String) object; } else { throw new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name)); } @@ -162,6 +175,12 @@ public class KeyRecord implements IDBObj, IKeyRecord { return mMetaInfo; } else if (name.equalsIgnoreCase(ATTR_ARCHIVED_BY)) { return mArchivedBy; + } else if (name.equalsIgnoreCase(ATTR_CLIENT_ID)) { + return mClientId; + } else if (name.equalsIgnoreCase(ATTR_DATA_TYPE)) { + return mDataType; + } else if (name.equalsIgnoreCase(ATTR_STATUS)) { + return mStatus; } else { throw new EBaseException(com.netscape.certsrv.apps.CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", name)); } @@ -342,4 +361,26 @@ public class KeyRecord implements IDBObj, IKeyRecord { public Date getModifyTime() { return mModifyTime; } + + /** + * Retrieves the client ID of this record. + */ + public String getClientId() throws EBaseException { + return mClientId ; + } + + /** + * Retrieves the key status of this record. + */ + public String getKeyStatus() throws EBaseException { + return mStatus; + + } + + /** + * Retrieves the key data type of this record. + */ + public String getDataType() throws EBaseException { + return mDataType; + } } diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java index 269a94c9d..6219bab0c 100644 --- a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java +++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java @@ -129,6 +129,19 @@ public class KeyRepository extends Repository implements IKeyRepository { reg.registerAttribute(KeyRecord.ATTR_ARCHIVED_BY, new StringMapper(KeyDBSchema.LDAP_ATTR_ARCHIVED_BY)); } + if (!reg.isAttributeRegistered(KeyRecord.ATTR_CLIENT_ID)) { + reg.registerAttribute(KeyRecord.ATTR_CLIENT_ID, new + StringMapper(KeyDBSchema.LDAP_ATTR_CLIENT_ID)); + } + if (!reg.isAttributeRegistered(KeyRecord.ATTR_STATUS)) { + reg.registerAttribute(KeyRecord.ATTR_STATUS, new + StringMapper(KeyDBSchema.LDAP_ATTR_STATUS)); + } + if (!reg.isAttributeRegistered(KeyRecord.ATTR_DATA_TYPE)) { + reg.registerAttribute(KeyRecord.ATTR_DATA_TYPE, new + StringMapper(KeyDBSchema.LDAP_ATTR_DATA_TYPE)); + } + } public void setKeyStatusUpdateInterval(IRepository requestRepo, int interval) { diff --git a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java index 06d5d961f..4f7de8f84 100644 --- a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java +++ b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMRestClient.java @@ -49,12 +49,13 @@ public class DRMRestClient { return list; } - public KeyRequestInfo archiveSecurityData(byte[] encoded, String clientId) { + public KeyRequestInfo archiveSecurityData(byte[] encoded, String clientId, String dataType) { // create archival request ArchivalRequestData data = new ArchivalRequestData(); String req1 = com.netscape.osutil.OSUtil.BtoA(encoded); data.setWrappedPrivateData(req1); data.setClientId(clientId); + data.setDataType(dataType); KeyRequestInfo info = keyRequestClient.archiveKey(data); return info; @@ -75,7 +76,7 @@ public class DRMRestClient { return null; } - public KeyRequestInfo requestRecovery(String keyId, byte[] rpwd, byte[] rkey) { + public KeyRequestInfo requestRecovery(String keyId, byte[] rpwd, byte[] rkey, byte[] nonceData) { // create recovery request RecoveryRequestData data = new RecoveryRequestData(); data.setKeyId(keyId); @@ -86,6 +87,10 @@ public class DRMRestClient { data.setTransWrappedSessionKey(com.netscape.osutil.OSUtil.BtoA(rkey)); } + if (nonceData != null) { + data.setNonceData(com.netscape.osutil.OSUtil.BtoA(nonceData)); + } + KeyRequestInfo info = keyRequestClient.recoverKey(data); return info; } @@ -94,7 +99,7 @@ public class DRMRestClient { keyRequestClient.approveRequest(recoveryId); } - public KeyData retrieveKey(String keyId, String requestId, byte[] rpwd, byte[] rkey) { + public KeyData retrieveKey(String keyId, String requestId, byte[] rpwd, byte[] rkey, byte[] nonceData) { // create recovery request RecoveryRequestData data = new RecoveryRequestData(); data.setKeyId(keyId); @@ -105,6 +110,11 @@ public class DRMRestClient { if (rpwd != null) { data.setSessionWrappedPassphrase(com.netscape.osutil.OSUtil.BtoA(rpwd)); } + + if (nonceData != null) { + data.setNonceData(com.netscape.osutil.OSUtil.BtoA(nonceData)); + } + KeyData key = keyClient.retrieveKey(data); return key; } diff --git a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java index a8560dc2e..7890b96c8 100644 --- a/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java +++ b/pki/base/kra/functional/src/com/netscape/cms/servlet/test/DRMTest.java @@ -17,6 +17,7 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.test; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.CharConversionException; import java.io.IOException; @@ -27,11 +28,13 @@ import java.security.cert.CertificateEncodingException; import java.util.Calendar; import java.util.Collection; import java.util.Iterator; +import java.util.Random; + import org.mozilla.jss.CryptoManager; 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.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.BadPaddingException; import org.mozilla.jss.crypto.Cipher; @@ -43,13 +46,15 @@ import org.mozilla.jss.crypto.KeyGenAlgorithm; 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.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.X509Certificate; +import org.mozilla.jss.pkcs12.PasswordConverter; +import org.mozilla.jss.pkcs7.EncryptedContentInfo; 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 org.mozilla.jss.util.Password; @@ -63,6 +68,7 @@ import org.apache.commons.cli.PosixParser; import com.netscape.cms.servlet.base.CMSResourceService; import com.netscape.cms.servlet.key.model.KeyData; import com.netscape.cms.servlet.key.model.KeyDataInfo; +import com.netscape.cms.servlet.request.KeyRequestResource; import com.netscape.cms.servlet.request.model.KeyRequestInfo; @SuppressWarnings("deprecation") @@ -123,8 +129,16 @@ public class DRMTest { // used for crypto operations byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; - IVParameterSpec IV = null; - IV = new IVParameterSpec(iv); + IVParameterSpec ivSpec; + IVParameterSpec ivSpecServer; + + try { + ivSpec = genIV(8); + } catch (Exception e) { + log("Can't generate initialization vector use default: " + e); + ivSpec = new IVParameterSpec(iv); + } + CryptoManager manager = null; CryptoToken token = null; KeyGenerator kg1 = null; @@ -196,7 +210,7 @@ public class DRMTest { // Test 2: Get list of completed key archival requests log("\n\nList of completed archival requests"); - Collection<KeyRequestInfo> list = client.listRequests("complete", "enrollment"); + Collection<KeyRequestInfo> list = client.listRequests("complete", "securityDataEnrollment"); if (list == null) { log("No requests found"); } else { @@ -209,7 +223,7 @@ public class DRMTest { // Test 3: Get list of key recovery requests log("\n\nList of completed recovery requests"); - Collection<KeyRequestInfo> list2 = client.listRequests("complete", "recovery"); + Collection<KeyRequestInfo> list2 = client.listRequests("complete", "securityDataRecovery"); if (list2 == null) { log("No requests found"); } else { @@ -226,9 +240,10 @@ public class DRMTest { try { kg1 = token.getKeyGenerator(KeyGenAlgorithm.DES3); vek = kg1.generate(); - byte[] encoded = createPKIArchiveOptions(manager, token, transportCert, vek, null, kg1); - KeyRequestInfo info = client.archiveSecurityData(encoded, clientId); + byte[] encoded = createPKIArchiveOptions(manager, token, transportCert, vek, null, kg1, ivSpec); + + KeyRequestInfo info = client.archiveSecurityData(encoded, clientId, KeyRequestResource.SYMMETRIC_KEY_TYPE); log("Archival Results:"); printRequestInfo(info); keyId = getId(info.getKeyURL()); @@ -238,6 +253,7 @@ public class DRMTest { } //Test 5: Get keyId for active key with client ID + log("Getting key ID for symmetric key"); keyInfo = client.getKeyData(clientId, "active"); String keyId2 = getId(keyInfo.getKeyURL()); @@ -249,6 +265,8 @@ public class DRMTest { if (!keyId.equals(keyId2)) { log("Error: key ids from search and archival do not match"); + } else { + log("Success: keyids from search and archival match."); } // Test 6: Submit a recovery request for the symmetric key using a session key @@ -256,7 +274,7 @@ public class DRMTest { try { recoveryKey = kg1.generate(); wrappedRecoveryKey = wrapSymmetricKey(manager, token, transportCert, recoveryKey); - KeyRequestInfo info = client.requestRecovery(keyId, null, wrappedRecoveryKey); + KeyRequestInfo info = client.requestRecovery(keyId, null, wrappedRecoveryKey, ivSpec.getIV()); recoveryRequestId = getId(info.getRequestURL()); } catch (Exception e) { log("Exception in recovering symmetric key using session key: " + e.getMessage()); @@ -269,10 +287,12 @@ public class DRMTest { // Test 8: Get key log("Getting key: " + keyId); - keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey); + keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey, ivSpec.getIV()); wrappedRecoveredKey = keyData.getWrappedPrivateData(); + + ivSpecServer = new IVParameterSpec( com.netscape.osutil.OSUtil.AtoB(keyData.getNonceData())); try { - recoveredKey = unwrap(token, IV, wrappedRecoveredKey.getBytes("ISO-8859-1"), recoveryKey); + recoveredKey = unwrap(token, ivSpecServer,com.netscape.osutil.OSUtil.AtoB(wrappedRecoveredKey), recoveryKey); } catch (Exception e) { log("Exception in unwrapping key: " + e.toString()); e.printStackTrace(); @@ -280,6 +300,8 @@ public class DRMTest { if (!recoveredKey.equals(com.netscape.osutil.OSUtil.BtoA(vek.getEncoded()))) { log("Error: recovered and archived keys do not match!"); + } else { + log("Success: recoverd and archived keys match!"); } // Test 9: Submit a recovery request for the symmetric key using a passphrase @@ -288,9 +310,10 @@ public class DRMTest { try { recoveryKey = kg1.generate(); - wrappedRecoveryPassphrase = wrapPassphrase(token, recoveryPassphrase, IV, recoveryKey); + wrappedRecoveryPassphrase = wrapPassphrase(token, recoveryPassphrase, ivSpec, recoveryKey); wrappedRecoveryKey = wrapSymmetricKey(manager, token, transportCert, recoveryKey); - requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey); + + requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); recoveryRequestId = getId(requestInfo.getRequestURL()); } catch (Exception e) { log("Exception in recovering symmetric key using passphrase" + e.toString()); @@ -303,19 +326,25 @@ public class DRMTest { // Test 11: Get key log("Getting key: " + keyId); - keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey); + keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); wrappedRecoveredKey = keyData.getWrappedPrivateData(); + recoveredKey = unwrap(wrappedRecoveredKey, recoveryPassphrase); - if (!recoveredKey.equals(com.netscape.osutil.OSUtil.BtoA(vek.getEncoded()))) { + + if (recoveredKey == null || !recoveredKey.equals(com.netscape.osutil.OSUtil.BtoA(vek.getEncoded()))) { log("Error: recovered and archived keys do not match!"); + } else { + log("Success: recovered and archived keys do match!"); } + + passphrase = "secret12345"; // Test 12: Generate and archive a passphrase clientId = "UUID: 123-45-6789 RKEK " + Calendar.getInstance().getTime().toString(); try { - byte[] encoded = createPKIArchiveOptions(manager, token, transportCert, null, passphrase, kg1); - requestInfo = client.archiveSecurityData(encoded, clientId); + byte[] encoded = createPKIArchiveOptions(manager, token, transportCert, null, passphrase, kg1, ivSpec); + requestInfo = client.archiveSecurityData(encoded, clientId, KeyRequestResource.PASS_PHRASE_TYPE); log("Archival Results:"); printRequestInfo(requestInfo); keyId = getId(requestInfo.getKeyURL()); @@ -336,6 +365,8 @@ public class DRMTest { if (!keyId.equals(keyId2)) { log("Error: key ids from search and archival do not match"); + } else { + log("Success: key ids from search and archival do match!"); } // Test 14: Submit a recovery request for the passphrase using a session key @@ -346,7 +377,8 @@ public class DRMTest { try { recoveryKey = kg1.generate(); wrappedRecoveryKey = wrapSymmetricKey(manager, token, transportCert, recoveryKey); - requestInfo = client.requestRecovery(keyId, null, wrappedRecoveryKey); + wrappedRecoveryPassphrase = wrapPassphrase(token, recoveryPassphrase, ivSpec, recoveryKey); + requestInfo = client.requestRecovery(keyId, null, wrappedRecoveryKey, ivSpec.getIV()); recoveryRequestId = getId(requestInfo.getRequestURL()); } catch (Exception e) { log("Exception in recovering passphrase using session key: " + e.getMessage()); @@ -359,22 +391,26 @@ public class DRMTest { // Test 16: Get key log("Getting passphrase: " + keyId); - keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey); + keyData = client.retrieveKey(keyId, recoveryRequestId, null, wrappedRecoveryKey, ivSpec.getIV()); wrappedRecoveredKey = keyData.getWrappedPrivateData(); + ivSpecServer = new IVParameterSpec( com.netscape.osutil.OSUtil.AtoB(keyData.getNonceData())); try { - recoveredKey = unwrap(token, IV, wrappedRecoveredKey.getBytes("ISO-8859-1"), recoveryKey); + recoveredKey = unwrap(token, ivSpecServer, com.netscape.osutil.OSUtil.AtoB(wrappedRecoveredKey), recoveryKey); + recoveredKey = new String(com.netscape.osutil.OSUtil.AtoB(recoveredKey), "UTF-8"); } catch (Exception e) { log("Exception in unwrapping key: " + e.toString()); e.printStackTrace(); } - if (!recoveredKey.equals(passphrase)) { + if (recoveredKey == null || !recoveredKey.equals(passphrase)) { log("Error: recovered and archived passphrases do not match!"); + } else { + log("Success: recovered and archived passphrases do match!"); } // Test 17: Submit a recovery request for the passphrase using a passphrase log("Submitting a recovery request for the passphrase using a passphrase"); - requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey); + requestInfo = client.requestRecovery(keyId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); recoveryRequestId = getId(requestInfo.getRequestURL()); //Test 18: Approve recovery @@ -383,19 +419,80 @@ public class DRMTest { // Test 19: Get key log("Getting passphrase: " + keyId); - keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey); + keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); wrappedRecoveredKey = keyData.getWrappedPrivateData(); recoveredKey = unwrap(wrappedRecoveredKey, recoveryPassphrase); + try { + recoveredKey = new String(com.netscape.osutil.OSUtil.AtoB(recoveredKey), "UTF-8"); + } catch (Exception e) { + log("Error: Can't convert recovered passphrase from binary to ascii!"); + } - if (!recoveredKey.equals(passphrase)) { + if (recoveredKey == null || !recoveredKey.equals(passphrase)) { log("Error: recovered and archived passphrases do not match!"); + } else { + log("Success: recovered and archived passphrases do match!"); + } + + // Test 20: Submit a recovery request for the passphrase using a passphrase + //Wait until retrieving key before sending input data. + + log("Submitting a recovery request for the passphrase using a passphrase, wait till end to provide recovery data."); + requestInfo = client.requestRecovery(keyId, null, null, null); + recoveryRequestId = getId(requestInfo.getRequestURL()); + + //Test 21: Approve recovery + log("Approving recovery request: " + recoveryRequestId); + client.approveRecovery(recoveryRequestId); + + // Test 22: Get key + log("Getting passphrase: " + keyId); + keyData = client.retrieveKey(keyId, recoveryRequestId, wrappedRecoveryPassphrase, wrappedRecoveryKey, ivSpec.getIV()); + wrappedRecoveredKey = keyData.getWrappedPrivateData(); + recoveredKey = unwrap(wrappedRecoveredKey, recoveryPassphrase); + try { + recoveredKey = new String(com.netscape.osutil.OSUtil.AtoB(recoveredKey), "UTF-8"); + } catch (Exception e) { + log("Error: Can't convert recovered passphrase from binary to ascii!"); } + if (recoveredKey == null || !recoveredKey.equals(passphrase)) { + log("Error: recovered and archived passphrases do not match!"); + } else { + log("Success: recovered and archived passphrases do match!"); + } } private static String unwrap(String wrappedRecoveredKey, String recoveryPassphrase) { - // TODO Auto-generated method stub - return null; + + EncryptedContentInfo cInfo = null; + String unwrappedData = null; + + //We have to do this to get the decoding to work. + PBEAlgorithm pbeAlg = PBEAlgorithm.PBE_SHA1_DES3_CBC; + + log("pbeAlg: " + pbeAlg); + try { + Password pass = new Password(recoveryPassphrase.toCharArray()); + PasswordConverter passConverter = new + PasswordConverter(); + + byte[] encoded = com.netscape.osutil.OSUtil.AtoB(wrappedRecoveredKey); + + ByteArrayInputStream inStream = new ByteArrayInputStream(encoded); + cInfo = (EncryptedContentInfo) + new EncryptedContentInfo.Template().decode(inStream); + + byte[] decodedData = cInfo.decrypt(pass, passConverter); + + unwrappedData = com.netscape.osutil.OSUtil.BtoA(decodedData); + + } catch (Exception e) { + log("Problem unwraping PBE wrapped datat! " + e.toString()); + + } + + return unwrappedData; } private static void log(String string) { @@ -407,31 +504,24 @@ public class DRMTest { SymmetricKey recoveryKey) throws NoSuchAlgorithmException, TokenException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException { - if (wrappedRecoveredKey == null || recoveryKey == null || token == null) { - return null; - } - Cipher decryptor = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); decryptor.initDecrypt(recoveryKey, IV); byte[] unwrappedData = decryptor.doFinal(wrappedRecoveredKey); - String unwrappedS = new String(unwrappedData); + String unwrappedS = com.netscape.osutil.OSUtil.BtoA( unwrappedData); return unwrappedS; } private static String getId(String link) { - return link.substring(link.lastIndexOf("/")); + return link.substring(link.lastIndexOf("/") + 1); } private static byte[] createPKIArchiveOptions(CryptoManager manager, CryptoToken token, String transportCert, - SymmetricKey vek, String passphrase, KeyGenerator kg1) throws TokenException, CharConversionException, + SymmetricKey vek, String passphrase, KeyGenerator kg1, IVParameterSpec IV) throws TokenException, CharConversionException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, CertificateEncodingException, IOException, IllegalStateException, IllegalBlockSizeException, BadPaddingException { byte[] key_data = null; - byte iv[] = { 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; - IVParameterSpec IV = null; - IV = new IVParameterSpec(iv); //generate session key SymmetricKey sk = kg1.generate(); @@ -450,17 +540,35 @@ public class DRMTest { // create PKIArchiveOptions structure AlgorithmIdentifier algS = new AlgorithmIdentifier(new OBJECT_IDENTIFIER("1.2.840.113549.3.7"), - new OCTET_STRING(iv)); + new OCTET_STRING(IV.getIV())); EncryptedValue encValue = new EncryptedValue(null, algS, new BIT_STRING(session_data, 0), null, null, new BIT_STRING(key_data, 0)); EncryptedKey key = new EncryptedKey(encValue); PKIArchiveOptions opt = new PKIArchiveOptions(key); - SEQUENCE seq = new SEQUENCE(); - seq.addElement(new AVA(new OBJECT_IDENTIFIER("1.3.6.1.5.5.7.5.1.4"), opt)); - ByteArrayOutputStream bo = new ByteArrayOutputStream(); - seq.encode(bo); - byte[] encoded = bo.toByteArray(); + byte[] encoded = null; + + try { + + //Let's make sure we can decode the encoded PKIArchiveOptions.. + ByteArrayOutputStream oStream = new ByteArrayOutputStream(); + + opt.encode(oStream); + + encoded = oStream.toByteArray(); + ByteArrayInputStream inStream = new ByteArrayInputStream( encoded); + PKIArchiveOptions options = (PKIArchiveOptions) + new PKIArchiveOptions.Template().decode(inStream); + log("Decoded PKIArchiveOptions: " + options); + } catch (IOException e) { + log("Problem with PKIArchiveOptions: " + e.toString()); + return null; + + } catch (InvalidBERException e) { + log("Problem with PKIArchiveOptions: " + e.toString()); + return null; + } + return encoded; } @@ -470,28 +578,16 @@ public class DRMTest { byte[] wrappedPassphrase = null; Cipher encryptor = null; - if (passphrase == null || sk == null || token == null || IV == null) { - return null; - } - encryptor = token.getCipherContext(EncryptionAlgorithm.DES3_CBC_PAD); log("cipher " + encryptor); if (encryptor != null) { encryptor.initEncrypt(sk, IV); - wrappedPassphrase = encryptor.doFinal(passphrase.getBytes()); - log("Pass phrase mode key_data: " + wrappedPassphrase); - - // Try to decrypt - String wrappedS = new String(wrappedPassphrase, "ISO-8859-1"); - byte[] pPhrase = wrappedS.getBytes("ISO-8859-1"); - encryptor.initDecrypt(sk, IV); - byte[] decrypted = encryptor.doFinal(pPhrase); - String s = new String(decrypted, "ISO-8859-1"); - log("Re decrypted pass phrase " + s + " decrypted.size " + decrypted.length); + wrappedPassphrase = encryptor.doFinal(passphrase.getBytes("UTF-8")); } else { throw new IOException("Failed to create cipher"); } + return wrappedPassphrase; } @@ -513,4 +609,14 @@ public class DRMTest { log("Type: " + info.getRequestType()); } + //Use this when we actually create random initialization vectors + private static IVParameterSpec genIV(int blockSize) throws Exception { + // generate an IV + byte[] iv = new byte[blockSize]; + + Random rnd = new Random(); + rnd.nextBytes(iv); + + return new IVParameterSpec(iv); + } } diff --git a/pki/base/kra/shared/conf/index.ldif b/pki/base/kra/shared/conf/index.ldif index c1eecc19d..4bc8aebf9 100644 --- a/pki/base/kra/shared/conf/index.ldif +++ b/pki/base/kra/shared/conf/index.ldif @@ -19,6 +19,27 @@ nsIndexType: eq nsSystemIndex: false cn: publicKeyData +dn: cn=clientId,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: clientId + +dn: cn=dataType,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: dataType + +dn: cn=status,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: status + dn: cn=description,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config objectClass: top objectClass: nsIndex diff --git a/pki/base/kra/shared/conf/schema.ldif b/pki/base/kra/shared/conf/schema.ldif index caf71e965..70578e21c 100644 --- a/pki/base/kra/shared/conf/schema.ldif +++ b/pki/base/kra/shared/conf/schema.ldif @@ -161,6 +161,21 @@ attributeTypes: ( keySize-oid NAME 'keySize' DESC 'CMS defined attribute' SYNTAX dn: cn=schema changetype: modify add: attributeTypes +attributeTypes: ( clientId-oid NAME 'clientId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( dataType-oid NAME 'dataType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( status-oid NAME 'status' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes attributeTypes: ( keyState-oid NAME 'keyState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema @@ -446,7 +461,7 @@ objectClasses: ( userDetails-oid NAME 'userDetails' DESC 'CMS defined class' SUP dn: cn=schema changetype: modify add: objectClasses -objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy ) X-ORIGIN 'user defined' ) +objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy $ clientId $ dataType $ status ) X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify 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 diff --git a/pki/base/ocsp/shared/conf/index.ldif b/pki/base/ocsp/shared/conf/index.ldif index 567b707c8..184187045 100644 --- a/pki/base/ocsp/shared/conf/index.ldif +++ b/pki/base/ocsp/shared/conf/index.ldif @@ -24,6 +24,27 @@ nsIndexType: eq nsSystemIndex: false cn: publicKeyData +dn: cn=clientId,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: clientId + +dn: cn=dataType,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: dataType + +dn: cn=status,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: status + dn: cn=description,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config objectClass: top objectClass: nsIndex diff --git a/pki/base/ocsp/shared/conf/schema.ldif b/pki/base/ocsp/shared/conf/schema.ldif index caf71e965..70578e21c 100644 --- a/pki/base/ocsp/shared/conf/schema.ldif +++ b/pki/base/ocsp/shared/conf/schema.ldif @@ -161,6 +161,21 @@ attributeTypes: ( keySize-oid NAME 'keySize' DESC 'CMS defined attribute' SYNTAX dn: cn=schema changetype: modify add: attributeTypes +attributeTypes: ( clientId-oid NAME 'clientId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( dataType-oid NAME 'dataType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( status-oid NAME 'status' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes attributeTypes: ( keyState-oid NAME 'keyState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema @@ -446,7 +461,7 @@ objectClasses: ( userDetails-oid NAME 'userDetails' DESC 'CMS defined class' SUP dn: cn=schema changetype: modify add: objectClasses -objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy ) X-ORIGIN 'user defined' ) +objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy $ clientId $ dataType $ status ) X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify diff --git a/pki/base/tks/shared/conf/index.ldif b/pki/base/tks/shared/conf/index.ldif index 567b707c8..184187045 100644 --- a/pki/base/tks/shared/conf/index.ldif +++ b/pki/base/tks/shared/conf/index.ldif @@ -24,6 +24,27 @@ nsIndexType: eq nsSystemIndex: false cn: publicKeyData +dn: cn=clientId,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: clientId + +dn: cn=dataType,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: dataType + +dn: cn=status,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: nsIndex +nsIndexType: eq +nsSystemIndex: false +cn: status + dn: cn=description,cn=index,cn={database},cn=ldbm database, cn=plugins, cn=config objectClass: top objectClass: nsIndex diff --git a/pki/base/tks/shared/conf/schema.ldif b/pki/base/tks/shared/conf/schema.ldif index caf71e965..70578e21c 100644 --- a/pki/base/tks/shared/conf/schema.ldif +++ b/pki/base/tks/shared/conf/schema.ldif @@ -161,6 +161,21 @@ attributeTypes: ( keySize-oid NAME 'keySize' DESC 'CMS defined attribute' SYNTAX dn: cn=schema changetype: modify add: attributeTypes +attributeTypes: ( clientId-oid NAME 'clientId' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( dataType-oid NAME 'dataType' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( status-oid NAME 'status' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes attributeTypes: ( keyState-oid NAME 'keyState' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema @@ -446,7 +461,7 @@ objectClasses: ( userDetails-oid NAME 'userDetails' DESC 'CMS defined class' SUP dn: cn=schema changetype: modify add: objectClasses -objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy ) X-ORIGIN 'user defined' ) +objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy $ clientId $ dataType $ status ) X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify |