From 034bcadd67bb2a392b6be9a16a340052ac22fd2b Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Tue, 12 Aug 2014 04:08:30 -0400 Subject: [PATCH 11/13] Add IECUserRolesExtInput profile input --- base/ca/shared/conf/registry.cfg | 5 +- .../cms/profile/input/IECUserRolesExtInput.java | 204 +++++++++++++++++++++ base/server/cmsbundle/src/UserMessages.properties | 8 + 3 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 base/server/cms/src/com/netscape/cms/profile/input/IECUserRolesExtInput.java diff --git a/base/ca/shared/conf/registry.cfg b/base/ca/shared/conf/registry.cfg index 9cd4e6d5c89b6e9bd0323fd3fd272b4af1de9568..c4e3ab86b453bec8964d62b3fbdbac14b40f6105 100644 --- a/base/ca/shared/conf/registry.cfg +++ b/base/ca/shared/conf/registry.cfg @@ -173,7 +173,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,encKeyGenInputImpl,signKeyGenInputImpl,dualKeyGenInputImpl,subjectNameInputImpl,submitterInfoInputImpl,genericInputImpl,fileSigningInputImpl,imageInputImpl,subjectDNInputImpl,nsNKeyCertReqInputImpl,nsHKeyCertReqInputImpl,serialNumRenewInputImpl,subjectAltNameExtInputImpl +profileInput.ids=cmcCertReqInputImpl,certReqInputImpl,keyGenInputImpl,encKeyGenInputImpl,signKeyGenInputImpl,dualKeyGenInputImpl,subjectNameInputImpl,submitterInfoInputImpl,genericInputImpl,fileSigningInputImpl,imageInputImpl,subjectDNInputImpl,nsNKeyCertReqInputImpl,nsHKeyCertReqInputImpl,serialNumRenewInputImpl,subjectAltNameExtInputImpl,iecUserRolesExtInputImpl profileInput.subjectAltNameExtInputImpl.class=com.netscape.cms.profile.input.SubjectAltNameExtInput profileInput.subjectAltNameExtInputImpl.desc=SAN Input profileInput.subjectAltNameExtInputImpl.name=SAN Input @@ -222,6 +222,9 @@ profileInput.subjectDNInputImpl.name=Subject DN Input profileInput.subjectNameInputImpl.class=com.netscape.cms.profile.input.SubjectNameInput profileInput.subjectNameInputImpl.desc=Subject Name Input profileInput.subjectNameInputImpl.name=Subject Name Input +profileInput.iecUserRolesExtInputImpl.class=com.netscape.cms.profile.input.IECUserRolesExtInput +profileInput.iecUserRolesExtInputImpl.desc=IECUserRoles Extension Input +profileInput.iecUserRolesExtInputImpl.name=IECUserRoles Extension Input profileOutput.ids=certOutputImpl,cmmfOutputImpl,pkcs7OutputImpl,nsNKeyOutputImpl profileOutput.certOutputImpl.class=com.netscape.cms.profile.output.CertOutput profileOutput.certOutputImpl.desc=Certificate Output diff --git a/base/server/cms/src/com/netscape/cms/profile/input/IECUserRolesExtInput.java b/base/server/cms/src/com/netscape/cms/profile/input/IECUserRolesExtInput.java new file mode 100644 index 0000000000000000000000000000000000000000..1212a8307cf6fc0e7ee48532e8a1ac28e70b0e44 --- /dev/null +++ b/base/server/cms/src/com/netscape/cms/profile/input/IECUserRolesExtInput.java @@ -0,0 +1,204 @@ +// --- 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) 2014 Red Hat, Inc. +// All rights reserved. +// --- END COPYRIGHT BLOCK --- + +package com.netscape.cms.profile.input; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Locale; +import java.util.StringTokenizer; + +import netscape.security.extensions.IECUserRolesExtension; +import netscape.security.x509.CertificateExtensions; +import netscape.security.x509.X509CertInfo; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +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 plugin accepts IEC 62351-8 IECUserRoles extension data from user. + * + * Only a single UserRoleInfo object is accepted. The + * IECUserRolesExtension implementation does support multiple + * UserRoleInfo objects, but additional work is required in this + * Input to make it possible to use more than one. + */ +public class IECUserRolesExtInput extends EnrollInput implements IProfileInput { + public static final String CONFIG_ROLE_DEFINITION = "role_definition"; + public static final String CONFIG_OPERATION_REQUIRED = "operation_required"; + + public static final String VAL_USER_ROLES = "userRole"; + public static final String VAL_AOR = "aor"; + public static final String VAL_REVISION = "revision"; + public static final String VAL_OPERATION = "operation"; + + public IECUserRolesExtInput() { + addConfigName(CONFIG_ROLE_DEFINITION); + addConfigName(CONFIG_OPERATION_REQUIRED); + } + + /** + * Retrieves the localizable name of this policy. + */ + public String getName(Locale locale) { + return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_NAME"); + } + + /** + * Retrieves the localizable description of this policy. + */ + public String getText(Locale locale) { + return CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_TEXT"); + } + + public void populate(IProfileContext ctx, IRequest request) + throws EProfileException { + + ArrayList userRole = new ArrayList<>(); + String userRoleString = ctx.get(VAL_USER_ROLES); + StringTokenizer tok = new StringTokenizer(userRoleString, ","); + while (tok.hasMoreTokens()) { + try { + userRole.add(new Integer(tok.nextToken())); + } catch (NumberFormatException e) { + throw new EProfileException("RoleIDs must be integers"); + } + } + + String aor = ctx.get(VAL_AOR); + + String revisionString = ctx.get(VAL_REVISION); + int revision = -1; + try { + revision = Integer.parseInt(revisionString); + } catch (NumberFormatException e) { + throw new EProfileException("revision must be an integer"); + } + + String roleDefinition = getConfig(CONFIG_ROLE_DEFINITION); + + IECUserRolesExtension.Operation operation = null; + String operationString = ctx.get(VAL_OPERATION).trim(); + if (operationString.equals("1") + || operationString.equalsIgnoreCase("ADD")) { + operation = IECUserRolesExtension.Operation.ADD; + } else if (operationString.equals("2") + || operationString.equalsIgnoreCase("DELETE")) { + operation = IECUserRolesExtension.Operation.DELETE; + } else if (operationString.equals("3") + || operationString.equalsIgnoreCase("CHANGE")) { + operation = IECUserRolesExtension.Operation.CHANGE; + } + String operationRequired = getConfig(CONFIG_OPERATION_REQUIRED); + if (operationRequired != null + && operationRequired.equalsIgnoreCase("true") + && operation == null) { + throw new EProfileException("operation is required"); + } + + // IEEE 1815-2012: "Optional if the authority can guarantee + // Certificate.tbsCertificate.serialNumber will always + // increase for this user. + // + BigInteger statusChangeSequenceNumber = null; + + // create extension + IECUserRolesExtension ext; + try { + IECUserRolesExtension.UserRoleInfo userRoleInfo = + new IECUserRolesExtension.UserRoleInfo( + userRole, aor, revision, roleDefinition, + operation, statusChangeSequenceNumber + ); + ext = new IECUserRolesExtension(false, Arrays.asList(userRoleInfo)); + } catch (CertificateException e) { + throw new EProfileException( + "failed to construct IECUserRoles extension: " + e.toString()); + } + + CertificateExtensions exts = + request.getExtDataInCertExts(EnrollProfile.REQUEST_EXTENSIONS); + if (exts == null) { + throw new EProfileException("extensions not found"); + } + try { + exts.set(IECUserRolesExtension.NAME, ext); + } catch (IOException e) { + CMS.debug("IECUserRolesExtInput: " + e.toString()); + throw new EProfileException("failed to set IECUserRoles extension"); + } + + request.setExtData(EnrollProfile.REQUEST_EXTENSIONS, exts); + } + + /** + * Return value names + */ + public Enumeration getValueNames() { + return Collections.enumeration(Arrays.asList( + VAL_USER_ROLES, VAL_AOR, VAL_REVISION, VAL_OPERATION)); + } + + public IDescriptor getConfigDescriptor(Locale locale, String name) { + if (name.equals(CONFIG_ROLE_DEFINITION)) { + return new Descriptor(IDescriptor.STRING, null, null, + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_ROLE_DEFINITION")); + } else if (name.equals(CONFIG_OPERATION_REQUIRED)) { + return new Descriptor(IDescriptor.BOOLEAN, null, "false", + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_OPERATION_REQUIRED")); + } else { + return null; + } + } + + /** + * Retrieves the descriptor of the given value + * parameter by name. + */ + public IDescriptor getValueDescriptor(Locale locale, String name) { + if (name.equals(VAL_USER_ROLES)) { + return new Descriptor(IDescriptor.STRING, null, null, + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_USER_ROLES")); + } else if (name.equals(VAL_AOR)) { + return new Descriptor(IDescriptor.STRING, null, null, + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_AOR")); + } else if (name.equals(VAL_REVISION)) { + return new Descriptor(IDescriptor.STRING, null, null, + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_REVISION")); + } else if (name.equals(VAL_OPERATION)) { + return new Descriptor(IDescriptor.STRING, null, null, + CMS.getUserMessage(locale, "CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_OPERATION")); + } + return null; + } +} diff --git a/base/server/cmsbundle/src/UserMessages.properties b/base/server/cmsbundle/src/UserMessages.properties index 6b4dc69b5a6787309f02b0e5e79d93b1f2918f88..fdccb3867fde8ad5ffc9e3cbe7a70a7bf08d8420 100644 --- a/base/server/cmsbundle/src/UserMessages.properties +++ b/base/server/cmsbundle/src/UserMessages.properties @@ -1079,6 +1079,14 @@ CMS_PROFILE_OUTPUT_CERT_B64=Certificate Base-64 Encoded CMS_PROFILE_OUTPUT_CMMF_B64=CMMF Base-64 Encoded CMS_PROFILE_OUTPUT_PKCS7_B64=PKCS #7 Base-64 Encoded CMS_PROFILE_OUTPUT_DER_B64=DER Base 64 Encoded +CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_NAME=IECUserRoles Extension Input +CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_TEXT=IECUserRoles Extension Input +CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_USER_ROLES=User Roles +CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_AOR=Area of Responsibility (AOR) +CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_REVISION=Revision number +CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_ROLE_DEFINITION=Role Definition +CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_OPERATION=Operation (Add/Delete/Change) +CMS_PROFILE_INPUT_IEC_USER_ROLES_EXT_OPERATION_REQUIRED=Require Operation Value ####################################################### # Self Tests # -- 2.1.0