From 046cd4e89b9a0deb3ce1bb26833bd86567fe0b4b Mon Sep 17 00:00:00 2001 From: Andrew Wnuk Date: Wed, 15 Feb 2012 15:34:13 -0800 Subject: ECC encryption and signing profiles This patch provides an option for certificate profiles to allow them to automatically create enrollment pages which are used to generate new signing and encryption certificate requests. Bug: 703608. --- pki/base/ca/shared/conf/registry.cfg | 8 +- pki/base/ca/shared/profiles/ca/caEncECUserCert.cfg | 2 +- pki/base/common/src/CMakeLists.txt | 2 + pki/base/common/src/UserMessages.properties | 4 + .../com/netscape/certsrv/property/IDescriptor.java | 4 + .../cms/profile/input/EncryptionKeyGenInput.java | 184 +++++++++++++++++++++ .../cms/profile/input/SigningKeyGenInput.java | 184 +++++++++++++++++++++ .../shared/webapps/ca/ee/ca/ProfileSelect.template | 95 +++++++---- 8 files changed, 451 insertions(+), 32 deletions(-) create mode 100644 pki/base/common/src/com/netscape/cms/profile/input/EncryptionKeyGenInput.java create mode 100644 pki/base/common/src/com/netscape/cms/profile/input/SigningKeyGenInput.java diff --git a/pki/base/ca/shared/conf/registry.cfg b/pki/base/ca/shared/conf/registry.cfg index f99c43653..f424bdb1b 100644 --- a/pki/base/ca/shared/conf/registry.cfg +++ b/pki/base/ca/shared/conf/registry.cfg @@ -167,7 +167,7 @@ profile.caServerCertEnrollImpl.name=Server Certificate Enrollment Profile profile.caUserCertEnrollImpl.class=com.netscape.cms.profile.common.UserCertCAEnrollProfile profile.caUserCertEnrollImpl.desc=Certificate Authority User Certificate Enrollment Profile profile.caUserCertEnrollImpl.name=User Certificate Enrollment Profile -profileInput.ids=cmcCertReqInputImpl,certReqInputImpl,keyGenInputImpl,dualKeyGenInputImpl,subjectNameInputImpl,submitterInfoInputImpl,genericInputImpl,fileSigningInputImpl,imageInputImpl,subjectDNInputImpl,nsNKeyCertReqInputImpl,nsHKeyCertReqInputImpl,serialNumRenewInputImpl +profileInput.ids=cmcCertReqInputImpl,certReqInputImpl,keyGenInputImpl,encKeyGenInputImpl,signKeyGenInputImpl,dualKeyGenInputImpl,subjectNameInputImpl,submitterInfoInputImpl,genericInputImpl,fileSigningInputImpl,imageInputImpl,subjectDNInputImpl,nsNKeyCertReqInputImpl,nsHKeyCertReqInputImpl,serialNumRenewInputImpl profileInput.fileSigningInputImpl.class=com.netscape.cms.profile.input.FileSigningInput profileInput.fileSigningInputImpl.desc=File Signing Input profileInput.fileSigningInputImpl.name=File Signing Input @@ -189,6 +189,12 @@ profileInput.cmcCertReqInputImpl.name=CMC Certificate Request Input profileInput.dualKeyGenInputImpl.class=com.netscape.cms.profile.input.DualKeyGenInput profileInput.dualKeyGenInputImpl.desc=Dual Key Generation Input profileInput.dualKeyGenInputImpl.name=Dual Key Generation Input +profileInput.signKeyGenInputImpl.class=com.netscape.cms.profile.input.SigningKeyGenInput +profileInput.signKeyGenInputImpl.desc=Encryption Key Generation Input +profileInput.signKeyGenInputImpl.name=Encryption Key Generation Input +profileInput.encKeyGenInputImpl.class=com.netscape.cms.profile.input.EncryptionKeyGenInput +profileInput.encKeyGenInputImpl.desc=Encryption Key Generation Input +profileInput.encKeyGenInputImpl.name=Encryption Key Generation Input profileInput.keyGenInputImpl.class=com.netscape.cms.profile.input.KeyGenInput profileInput.keyGenInputImpl.desc=Key Generation Input profileInput.keyGenInputImpl.name=Key Generation Input diff --git a/pki/base/ca/shared/profiles/ca/caEncECUserCert.cfg b/pki/base/ca/shared/profiles/ca/caEncECUserCert.cfg index 43ad77c5c..66baa4bf8 100644 --- a/pki/base/ca/shared/profiles/ca/caEncECUserCert.cfg +++ b/pki/base/ca/shared/profiles/ca/caEncECUserCert.cfg @@ -5,7 +5,7 @@ enableBy=admin name=Manual User Encryption ECC Certificates Enrollment auth.class_id= input.list=i1 -input.i1.class_id=keyGenInputImpl +input.i1.class_id=encKeyGenInputImpl output.list=o1 output.o1.class_id=certOutputImpl policyset.list=encryptionCertSet diff --git a/pki/base/common/src/CMakeLists.txt b/pki/base/common/src/CMakeLists.txt index 5b4bf0fa4..0ea1d61e4 100644 --- a/pki/base/common/src/CMakeLists.txt +++ b/pki/base/common/src/CMakeLists.txt @@ -806,6 +806,8 @@ set(pki-cms_java_SRCS com/netscape/cms/profile/input/SerialNumRenewInput.java com/netscape/cms/profile/input/SubjectNameInput.java com/netscape/cms/profile/input/KeyGenInput.java + com/netscape/cms/profile/input/SigningKeyGenInput.java + com/netscape/cms/profile/input/EncryptionKeyGenInput.java com/netscape/cms/profile/input/ImageInput.java com/netscape/cms/profile/input/EnrollInput.java com/netscape/cms/profile/input/nsNKeyCertReqInput.java diff --git a/pki/base/common/src/UserMessages.properties b/pki/base/common/src/UserMessages.properties index 4cb83e5ab..5d7cb3d0c 100644 --- a/pki/base/common/src/UserMessages.properties +++ b/pki/base/common/src/UserMessages.properties @@ -1039,6 +1039,10 @@ CMS_PROFILE_INPUT_SUBJECT_NAME_NAME=Subject Name CMS_PROFILE_INPUT_SUBJECT_NAME_TEXT=Subject Name CMS_PROFILE_INPUT_KEY_GEN_NAME=Key Generation CMS_PROFILE_INPUT_KEY_GEN_TEXT=Key Generation +CMS_PROFILE_INPUT_ENC_KEY_GEN_NAME=Encryption Key Generation +CMS_PROFILE_INPUT_ENC_KEY_GEN_TEXT=Encryption Key Generation +CMS_PROFILE_INPUT_SIGN_KEY_GEN_NAME=Signing Key Generation +CMS_PROFILE_INPUT_SIGN_KEY_GEN_TEXT=Signing Key Generation CMS_PROFILE_INPUT_DUAL_KEY_NAME=Dual Key Generation CMS_PROFILE_INPUT_DUAL_KEY_TEXT=Dual Key Generation CMS_PROFILE_UPDATER_SUBSYSTEM_NAME=Updater for Subsystem Group diff --git a/pki/base/common/src/com/netscape/certsrv/property/IDescriptor.java b/pki/base/common/src/com/netscape/certsrv/property/IDescriptor.java index b44d12698..727c1130d 100644 --- a/pki/base/common/src/com/netscape/certsrv/property/IDescriptor.java +++ b/pki/base/common/src/com/netscape/certsrv/property/IDescriptor.java @@ -37,6 +37,10 @@ public interface IDescriptor { public static String STRING_LIST = "string_list"; public static String KEYGEN_REQUEST = "keygen_request"; public static String KEYGEN_REQUEST_TYPE = "keygen_request_type"; + public static String ENC_KEYGEN_REQUEST = "enc_keygen_request"; + public static String ENC_KEYGEN_REQUEST_TYPE = "enc_keygen_request_type"; + public static String SIGN_KEYGEN_REQUEST = "sign_keygen_request"; + public static String SIGN_KEYGEN_REQUEST_TYPE = "sign_keygen_request_type"; public static String DUAL_KEYGEN_REQUEST = "dual_keygen_request"; public static String DUAL_KEYGEN_REQUEST_TYPE = "dual_keygen_request_type"; public static String CERT_REQUEST = "cert_request"; diff --git a/pki/base/common/src/com/netscape/cms/profile/input/EncryptionKeyGenInput.java b/pki/base/common/src/com/netscape/cms/profile/input/EncryptionKeyGenInput.java new file mode 100644 index 000000000..d59629f78 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/profile/input/EncryptionKeyGenInput.java @@ -0,0 +1,184 @@ +// --- 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.cms.profile.input; + +import java.util.Locale; + +import netscape.security.pkcs.PKCS10; +import netscape.security.util.DerInputStream; +import netscape.security.x509.X509CertInfo; + +import org.mozilla.jss.pkix.cmc.TaggedRequest; +import org.mozilla.jss.pkix.crmf.CertReqMsg; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.profile.EProfileException; +import com.netscape.certsrv.profile.IProfile; +import com.netscape.certsrv.profile.IProfileContext; +import com.netscape.certsrv.profile.IProfileInput; +import com.netscape.certsrv.property.Descriptor; +import com.netscape.certsrv.property.IDescriptor; +import com.netscape.certsrv.request.IRequest; +import com.netscape.cms.profile.common.EnrollProfile; + +/** + * This class implements the key generation input that + * populates parameters to the enrollment page for + * key generation. + *

+ * + * This input normally is used with user-based or non certificate request profile. + *

+ * + * @version $Revision$, $Date$ + */ +public class EncryptionKeyGenInput extends EnrollInput implements IProfileInput { + + public static final String VAL_KEYGEN_REQUEST_TYPE = + EnrollProfile.CTX_CERT_REQUEST_TYPE; + public static final String VAL_KEYGEN_REQUEST = + EnrollProfile.CTX_CERT_REQUEST; + + public EnrollProfile mEnrollProfile = null; + + public EncryptionKeyGenInput() { + addValueName(VAL_KEYGEN_REQUEST_TYPE); + addValueName(VAL_KEYGEN_REQUEST); + } + + /** + * Initializes this default policy. + */ + public void init(IProfile profile, IConfigStore config) + throws EProfileException { + super.init(profile, config); + mEnrollProfile = (EnrollProfile) profile; + } + + /** + * Retrieves the localizable name of this policy. + */ + public String getName(Locale locale) { + return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_ENC_KEY_GEN_NAME"); + } + + /** + * Retrieves the localizable description of this policy. + */ + public String getText(Locale locale) { + return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_ENC_KEY_GEN_TEXT"); + } + + /** + * Populates the request with this policy default. + */ + public void populate(IProfileContext ctx, IRequest request) + throws EProfileException { + String keygen_request_type = ctx.get(VAL_KEYGEN_REQUEST_TYPE); + String keygen_request = ctx.get(VAL_KEYGEN_REQUEST); + + X509CertInfo info = + request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO); + + if (keygen_request_type == null) { + CMS.debug("EncryptionKeyGenInput: populate - invalid cert request type " + + ""); + throw new EProfileException( + CMS.getUserMessage(getLocale(request), + "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE", + "")); + } + if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_PKCS10)) { + PKCS10 pkcs10 = mEnrollProfile.parsePKCS10(getLocale(request), keygen_request); + + if (pkcs10 == null) { + throw new EProfileException(CMS.getUserMessage( + getLocale(request), "CMS_PROFILE_NO_CERT_REQ")); + } + + mEnrollProfile.fillPKCS10(getLocale(request), pkcs10, info, request); + } else if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_KEYGEN)) { + DerInputStream keygen = mEnrollProfile.parseKeyGen(getLocale(request), keygen_request); + + if (keygen == null) { + throw new EProfileException(CMS.getUserMessage( + getLocale(request), "CMS_PROFILE_NO_CERT_REQ")); + } + + mEnrollProfile.fillKeyGen(getLocale(request), keygen, info, request); + } else if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_CRMF)) { + CertReqMsg msgs[] = mEnrollProfile.parseCRMF(getLocale(request), keygen_request); + + if (msgs == null) { + throw new EProfileException(CMS.getUserMessage( + getLocale(request), "CMS_PROFILE_NO_CERT_REQ")); + } + for (int x = 0; x < msgs.length; x++) { + verifyPOP(getLocale(request), msgs[x]); + } + // This profile only handle the first request in CRMF + Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM); + + mEnrollProfile.fillCertReqMsg(getLocale(request), msgs[seqNum.intValue()], info, request); + } else if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_CMC)) { + TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), keygen_request); + + if (msgs == null) { + throw new EProfileException(CMS.getUserMessage( + getLocale(request), "CMS_PROFILE_NO_CERT_REQ")); + } + // This profile only handle the first request in CRMF + Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM); + + if (seqNum == null) { + throw new EProfileException( + CMS.getUserMessage(getLocale(request), + "CMS_PROFILE_UNKNOWN_SEQ_NUM")); + } + + mEnrollProfile.fillTaggedRequest(getLocale(request), msgs[seqNum.intValue()], info, request); + } else { + // error + CMS.debug("EncryptionKeyGenInput: populate - " + + "invalid cert request type " + keygen_request_type); + throw new EProfileException(CMS.getUserMessage( + getLocale(request), + "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE", + keygen_request_type)); + } + request.setExtData(EnrollProfile.REQUEST_CERTINFO, info); + } + + /** + * Retrieves the descriptor of the given value + * parameter by name. + */ + public IDescriptor getValueDescriptor(Locale locale, String name) { + if (name.equals(VAL_KEYGEN_REQUEST_TYPE)) { + return new Descriptor(IDescriptor.ENC_KEYGEN_REQUEST_TYPE, null, + null, + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ_TYPE")); + } else if (name.equals(VAL_KEYGEN_REQUEST)) { + return new Descriptor(IDescriptor.ENC_KEYGEN_REQUEST, null, + null, + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ")); + } + return null; + } +} diff --git a/pki/base/common/src/com/netscape/cms/profile/input/SigningKeyGenInput.java b/pki/base/common/src/com/netscape/cms/profile/input/SigningKeyGenInput.java new file mode 100644 index 000000000..aa471d4f6 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/profile/input/SigningKeyGenInput.java @@ -0,0 +1,184 @@ +// --- 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.cms.profile.input; + +import java.util.Locale; + +import netscape.security.pkcs.PKCS10; +import netscape.security.util.DerInputStream; +import netscape.security.x509.X509CertInfo; + +import org.mozilla.jss.pkix.cmc.TaggedRequest; +import org.mozilla.jss.pkix.crmf.CertReqMsg; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.profile.EProfileException; +import com.netscape.certsrv.profile.IProfile; +import com.netscape.certsrv.profile.IProfileContext; +import com.netscape.certsrv.profile.IProfileInput; +import com.netscape.certsrv.property.Descriptor; +import com.netscape.certsrv.property.IDescriptor; +import com.netscape.certsrv.request.IRequest; +import com.netscape.cms.profile.common.EnrollProfile; + +/** + * This class implements the key generation input that + * populates parameters to the enrollment page for + * key generation. + *

+ * + * This input normally is used with user-based or non certificate request profile. + *

+ * + * @version $Revision$, $Date$ + */ +public class SigningKeyGenInput extends EnrollInput implements IProfileInput { + + public static final String VAL_KEYGEN_REQUEST_TYPE = + EnrollProfile.CTX_CERT_REQUEST_TYPE; + public static final String VAL_KEYGEN_REQUEST = + EnrollProfile.CTX_CERT_REQUEST; + + public EnrollProfile mEnrollProfile = null; + + public SigningKeyGenInput() { + addValueName(VAL_KEYGEN_REQUEST_TYPE); + addValueName(VAL_KEYGEN_REQUEST); + } + + /** + * Initializes this default policy. + */ + public void init(IProfile profile, IConfigStore config) + throws EProfileException { + super.init(profile, config); + mEnrollProfile = (EnrollProfile) profile; + } + + /** + * Retrieves the localizable name of this policy. + */ + public String getName(Locale locale) { + return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SIGN_KEY_GEN_NAME"); + } + + /** + * Retrieves the localizable description of this policy. + */ + public String getText(Locale locale) { + return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_SIGN_KEY_GEN_TEXT"); + } + + /** + * Populates the request with this policy default. + */ + public void populate(IProfileContext ctx, IRequest request) + throws EProfileException { + String keygen_request_type = ctx.get(VAL_KEYGEN_REQUEST_TYPE); + String keygen_request = ctx.get(VAL_KEYGEN_REQUEST); + + X509CertInfo info = + request.getExtDataInCertInfo(EnrollProfile.REQUEST_CERTINFO); + + if (keygen_request_type == null) { + CMS.debug("SigningKeyGenInput: populate - invalid cert request type " + + ""); + throw new EProfileException( + CMS.getUserMessage(getLocale(request), + "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE", + "")); + } + if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_PKCS10)) { + PKCS10 pkcs10 = mEnrollProfile.parsePKCS10(getLocale(request), keygen_request); + + if (pkcs10 == null) { + throw new EProfileException(CMS.getUserMessage( + getLocale(request), "CMS_PROFILE_NO_CERT_REQ")); + } + + mEnrollProfile.fillPKCS10(getLocale(request), pkcs10, info, request); + } else if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_KEYGEN)) { + DerInputStream keygen = mEnrollProfile.parseKeyGen(getLocale(request), keygen_request); + + if (keygen == null) { + throw new EProfileException(CMS.getUserMessage( + getLocale(request), "CMS_PROFILE_NO_CERT_REQ")); + } + + mEnrollProfile.fillKeyGen(getLocale(request), keygen, info, request); + } else if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_CRMF)) { + CertReqMsg msgs[] = mEnrollProfile.parseCRMF(getLocale(request), keygen_request); + + if (msgs == null) { + throw new EProfileException(CMS.getUserMessage( + getLocale(request), "CMS_PROFILE_NO_CERT_REQ")); + } + for (int x = 0; x < msgs.length; x++) { + verifyPOP(getLocale(request), msgs[x]); + } + // This profile only handle the first request in CRMF + Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM); + + mEnrollProfile.fillCertReqMsg(getLocale(request), msgs[seqNum.intValue()], info, request); + } else if (keygen_request_type.startsWith(EnrollProfile.REQ_TYPE_CMC)) { + TaggedRequest msgs[] = mEnrollProfile.parseCMC(getLocale(request), keygen_request); + + if (msgs == null) { + throw new EProfileException(CMS.getUserMessage( + getLocale(request), "CMS_PROFILE_NO_CERT_REQ")); + } + // This profile only handle the first request in CRMF + Integer seqNum = request.getExtDataInInteger(EnrollProfile.REQUEST_SEQ_NUM); + + if (seqNum == null) { + throw new EProfileException( + CMS.getUserMessage(getLocale(request), + "CMS_PROFILE_UNKNOWN_SEQ_NUM")); + } + + mEnrollProfile.fillTaggedRequest(getLocale(request), msgs[seqNum.intValue()], info, request); + } else { + // error + CMS.debug("SigningKeyGenInput: populate - " + + "invalid cert request type " + keygen_request_type); + throw new EProfileException(CMS.getUserMessage( + getLocale(request), + "CMS_PROFILE_UNKNOWN_CERT_REQ_TYPE", + keygen_request_type)); + } + request.setExtData(EnrollProfile.REQUEST_CERTINFO, info); + } + + /** + * Retrieves the descriptor of the given value + * parameter by name. + */ + public IDescriptor getValueDescriptor(Locale locale, String name) { + if (name.equals(VAL_KEYGEN_REQUEST_TYPE)) { + return new Descriptor(IDescriptor.SIGN_KEYGEN_REQUEST_TYPE, null, + null, + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ_TYPE")); + } else if (name.equals(VAL_KEYGEN_REQUEST)) { + return new Descriptor(IDescriptor.SIGN_KEYGEN_REQUEST, null, + null, + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_KEYGEN_REQ")); + } + return null; + } +} diff --git a/pki/dogtag/ca-ui/shared/webapps/ca/ee/ca/ProfileSelect.template b/pki/dogtag/ca-ui/shared/webapps/ca/ee/ca/ProfileSelect.template index f05930f8f..0e3ded046 100644 --- a/pki/dogtag/ca-ui/shared/webapps/ca/ee/ca/ProfileSelect.template +++ b/pki/dogtag/ca-ui/shared/webapps/ca/ee/ca/ProfileSelect.template @@ -36,6 +36,8 @@ width="100%">