From 621d9e5c413e561293d7484b93882d985b3fe15f Mon Sep 17 00:00:00 2001 From: Endi Sukma Dewata Date: Sat, 24 Mar 2012 02:27:47 -0500 Subject: Removed unnecessary pki folder. Previously the source code was located inside a pki folder. This folder was created during svn migration and is no longer needed. This folder has now been removed and the contents have been moved up one level. Ticket #131 --- .../cms/profile/def/SubjectAltNameExtDefault.java | 542 +++++++++++++++++++++ 1 file changed, 542 insertions(+) create mode 100644 base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java (limited to 'base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java') diff --git a/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java b/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java new file mode 100644 index 000000000..d3838577e --- /dev/null +++ b/base/common/src/com/netscape/cms/profile/def/SubjectAltNameExtDefault.java @@ -0,0 +1,542 @@ +// --- 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.def; + +import java.io.IOException; +import java.util.Enumeration; +import java.util.Locale; +import java.util.StringTokenizer; +import java.util.UUID; + +import netscape.security.x509.GeneralNameInterface; +import netscape.security.x509.GeneralNames; +import netscape.security.x509.PKIXExtensions; +import netscape.security.x509.SubjectAlternativeNameExtension; +import netscape.security.x509.X509CertInfo; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IAttrSet; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.pattern.Pattern; +import com.netscape.certsrv.profile.EProfileException; +import com.netscape.certsrv.profile.IProfile; +import com.netscape.certsrv.property.Descriptor; +import com.netscape.certsrv.property.EPropertyException; +import com.netscape.certsrv.property.IDescriptor; +import com.netscape.certsrv.request.IRequest; + +/** + * This class implements an enrollment default policy + * that populates a subject alternative name extension + * into the certificate template. + * + * @version $Revision$, $Date$ + */ +public class SubjectAltNameExtDefault extends EnrollExtDefault { + + public static final String CONFIG_CRITICAL = "subjAltNameExtCritical"; + public static final String CONFIG_NUM_GNS = "subjAltNameNumGNs"; + public static final String CONFIG_GN_ENABLE = "subjAltExtGNEnable_"; + public static final String CONFIG_TYPE = "subjAltExtType_"; + public static final String CONFIG_PATTERN = "subjAltExtPattern_"; + public static final String CONFIG_SOURCE = "subjAltExtSource_"; + public static final String CONFIG_SOURCE_UUID4 = "UUID4"; + + public static final String CONFIG_OLD_TYPE = "subjAltExtType"; + public static final String CONFIG_OLD_PATTERN = "subjAltExtPattern"; + + public static final String VAL_CRITICAL = "subjAltNameExtCritical"; + public static final String VAL_GENERAL_NAMES = "subjAltNames"; + + private static final String GN_ENABLE = "Enable"; + private static final String GN_TYPE = "Pattern Type"; + private static final String GN_PATTERN = "Pattern"; + + private static final int DEF_NUM_GN = 1; + private static final int MAX_NUM_GN = 100; + + public SubjectAltNameExtDefault() { + super(); + } + + protected int getNumGNs() { + int num = DEF_NUM_GN; + String numGNs = getConfig(CONFIG_NUM_GNS); + + if (numGNs != null) { + try { + num = Integer.parseInt(numGNs); + } catch (NumberFormatException e) { + // ignore + } + } + + if (num >= MAX_NUM_GN) + num = DEF_NUM_GN; + return num; + } + + public void init(IProfile profile, IConfigStore config) + throws EProfileException { + + super.init(profile, config); + refreshConfigAndValueNames(); + // migrate old parameters to new parameters + String old_type = null; + String old_pattern = null; + IConfigStore paramConfig = config.getSubStore("params"); + try { + if (paramConfig != null) { + old_type = paramConfig.getString(CONFIG_OLD_TYPE); + } + } catch (EBaseException e) { + // nothing to do here + } + CMS.debug("SubjectAltNameExtDefault: Upgrading old_type=" + + old_type); + try { + if (paramConfig != null) { + old_pattern = paramConfig.getString(CONFIG_OLD_PATTERN); + } + } catch (EBaseException e) { + // nothing to do here + } + CMS.debug("SubjectAltNameExtDefault: Upgrading old_pattern=" + + old_pattern); + if (old_type != null && old_pattern != null) { + CMS.debug("SubjectAltNameExtDefault: Upgrading"); + try { + paramConfig.putString(CONFIG_NUM_GNS, "1"); + paramConfig.putString(CONFIG_GN_ENABLE + "0", "true"); + paramConfig.putString(CONFIG_TYPE + "0", old_type); + paramConfig.putString(CONFIG_PATTERN + "0", old_pattern); + paramConfig.remove(CONFIG_OLD_TYPE); + paramConfig.remove(CONFIG_OLD_PATTERN); + profile.getConfigStore().commit(true); + } catch (Exception e) { + CMS.debug("SubjectAltNameExtDefault: Failed to upgrade " + e); + } + } + } + + public void setConfig(String name, String value) + throws EPropertyException { + int num = 0; + if (name.equals(CONFIG_NUM_GNS)) { + try { + num = Integer.parseInt(value); + + if (num >= MAX_NUM_GN || num < 0) { + throw new EPropertyException(CMS.getUserMessage( + "CMS_INVALID_PROPERTY", CONFIG_NUM_GNS)); + } + + } catch (Exception e) { + throw new EPropertyException(CMS.getUserMessage( + "CMS_INVALID_PROPERTY", CONFIG_NUM_GNS)); + } + } + super.setConfig(name, value); + } + + public Enumeration getConfigNames() { + refreshConfigAndValueNames(); + return super.getConfigNames(); + } + + protected void refreshConfigAndValueNames() { + super.refreshConfigAndValueNames(); + + addValueName(VAL_CRITICAL); + addValueName(VAL_GENERAL_NAMES); + + addConfigName(CONFIG_CRITICAL); + int num = getNumGNs(); + addConfigName(CONFIG_NUM_GNS); + for (int i = 0; i < num; i++) { + addConfigName(CONFIG_TYPE + i); + addConfigName(CONFIG_PATTERN + i); + addConfigName(CONFIG_GN_ENABLE + i); + } + } + + public IDescriptor getConfigDescriptor(Locale locale, String name) { + if (name.equals(CONFIG_CRITICAL)) { + return new Descriptor(IDescriptor.BOOLEAN, null, + "false", + CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL")); + } else if (name.startsWith(CONFIG_TYPE)) { + return new Descriptor(IDescriptor.CHOICE, + "RFC822Name,DNSName,DirectoryName,EDIPartyName,URIName,IPAddress,OIDName,OtherName", + "RFC822Name", + CMS.getUserMessage(locale, + "CMS_PROFILE_SUBJECT_ALT_NAME_TYPE")); + } else if (name.startsWith(CONFIG_PATTERN)) { + return new Descriptor(IDescriptor.STRING, null, + null, + CMS.getUserMessage(locale, + "CMS_PROFILE_SUBJECT_ALT_NAME_PATTERN")); + } else if (name.startsWith(CONFIG_GN_ENABLE)) { + return new Descriptor(IDescriptor.BOOLEAN, null, + "false", + CMS.getUserMessage(locale, "CMS_PROFILE_GN_ENABLE")); + } else if (name.startsWith(CONFIG_NUM_GNS)) { + return new Descriptor(IDescriptor.INTEGER, null, + "1", + CMS.getUserMessage(locale, "CMS_PROFILE_NUM_GNS")); + } + + return null; + } + + public IDescriptor getValueDescriptor(Locale locale, String name) { + if (name.equals(VAL_CRITICAL)) { + return new Descriptor(IDescriptor.BOOLEAN, null, + "false", + CMS.getUserMessage(locale, "CMS_PROFILE_CRITICAL")); + } else if (name.equals(VAL_GENERAL_NAMES)) { + return new Descriptor(IDescriptor.STRING_LIST, null, + null, + CMS.getUserMessage(locale, "CMS_PROFILE_GENERAL_NAMES")); + } else { + return null; + } + } + + public void setValue(String name, Locale locale, + X509CertInfo info, String value) + throws EPropertyException { + try { + SubjectAlternativeNameExtension ext = null; + + if (name == null) { + throw new EPropertyException(CMS.getUserMessage( + locale, "CMS_INVALID_PROPERTY", name)); + } + + ext = + (SubjectAlternativeNameExtension) + getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info); + + if (ext == null) { + populate(null, info); + } + + if (name.equals(VAL_CRITICAL)) { + ext = + (SubjectAlternativeNameExtension) + getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info); + + if (ext == null) { + // it is ok, the extension is never populated or delted + return; + } + boolean critical = Boolean.valueOf(value).booleanValue(); + + ext.setCritical(critical); + } else if (name.equals(VAL_GENERAL_NAMES)) { + ext = + (SubjectAlternativeNameExtension) + getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info); + + if (ext == null) { + // it is ok, the extension is never populated or delted + return; + } + if (value.equals("")) { + // if value is empty, do not add this extension + deleteExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info); + return; + } + GeneralNames gn = new GeneralNames(); + StringTokenizer st = new StringTokenizer(value, "\r\n"); + + while (st.hasMoreTokens()) { + String gname = (String) st.nextToken(); + CMS.debug("SubjectAltNameExtDefault: setValue GN:" + gname); + + if (!isGeneralNameValid(gname)) { + continue; + } + GeneralNameInterface n = parseGeneralName(gname); + if (n != null) { + gn.addElement(n); + } + } + if (gn.size() == 0) { + CMS.debug("GN size is zero"); + deleteExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info); + return; + } else { + CMS.debug("GN size is non zero (" + gn.size() + ")"); + ext.set(SubjectAlternativeNameExtension.SUBJECT_NAME, gn); + } + } else { + throw new EPropertyException(CMS.getUserMessage( + locale, "CMS_INVALID_PROPERTY", name)); + } + replaceExtension( + PKIXExtensions.SubjectAlternativeName_Id.toString(), + ext, info); + } catch (IOException e) { + CMS.debug("SubjectAltNameExtDefault: setValue " + e.toString()); + throw new EPropertyException(CMS.getUserMessage( + locale, "CMS_INVALID_PROPERTY", name)); + } catch (EProfileException e) { + CMS.debug("SubjectAltNameExtDefault: setValue " + e.toString()); + throw new EPropertyException(CMS.getUserMessage( + locale, "CMS_INVALID_PROPERTY", name)); + } + } + + public String getValue(String name, Locale locale, + X509CertInfo info) + throws EPropertyException { + try { + if (name == null) { + throw new EPropertyException(CMS.getUserMessage( + locale, "CMS_INVALID_PROPERTY", name)); + } + + SubjectAlternativeNameExtension ext = + (SubjectAlternativeNameExtension) + getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info); + + if (ext == null) { + try { + populate(null, info); + + } catch (EProfileException e) { + throw new EPropertyException(CMS.getUserMessage( + locale, "CMS_INVALID_PROPERTY", name)); + } + + } + + if (name.equals(VAL_CRITICAL)) { + ext = + (SubjectAlternativeNameExtension) + getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info); + + if (ext == null) { + return null; + } + if (ext.isCritical()) { + return "true"; + } else { + return "false"; + } + } else if (name.equals(VAL_GENERAL_NAMES)) { + ext = + (SubjectAlternativeNameExtension) + getExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), info); + if (ext == null) { + return null; + } + + GeneralNames names = (GeneralNames) + ext.get(SubjectAlternativeNameExtension.SUBJECT_NAME); + StringBuffer sb = new StringBuffer(); + Enumeration e = names.elements(); + + while (e.hasMoreElements()) { + GeneralNameInterface gn = e.nextElement(); + + if (!sb.toString().equals("")) { + sb.append("\r\n"); + } + sb.append(toGeneralNameString(gn)); + CMS.debug("SubjectAltNameExtDefault: getValue append GN:" + toGeneralNameString(gn)); + } + return sb.toString(); + } else { + throw new EPropertyException(CMS.getUserMessage( + locale, "CMS_INVALID_PROPERTY", name)); + } + } catch (IOException e) { + CMS.debug("SubjectAltNameExtDefault: getValue " + + e.toString()); + } + return null; + } + + /* + * returns text that goes into description for this extension on + * a profile + */ + public String getText(Locale locale) { + StringBuffer sb = new StringBuffer(); + int num = getNumGNs(); + + for (int i = 0; i < num; i++) { + sb.append("Record #"); + sb.append(i); + sb.append("{"); + sb.append(GN_PATTERN + ":"); + sb.append(getConfig(CONFIG_PATTERN + i)); + sb.append(","); + sb.append(GN_TYPE + ":"); + sb.append(getConfig(CONFIG_TYPE + i)); + sb.append(","); + sb.append(GN_ENABLE + ":"); + sb.append(getConfig(CONFIG_GN_ENABLE + i)); + sb.append("}"); + } + ; + + return CMS.getUserMessage(locale, "CMS_PROFILE_DEF_SUBJECT_ALT_NAME_EXT", getConfig(CONFIG_CRITICAL), + sb.toString()); + } + + /** + * Populates the request with this policy default. + */ + public void populate(IRequest request, X509CertInfo info) + throws EProfileException { + SubjectAlternativeNameExtension ext = null; + + try { + /* read from config file*/ + ext = createExtension(request); + + } catch (IOException e) { + CMS.debug("SubjectAltNameExtDefault: populate " + e.toString()); + } + if (ext != null) { + addExtension(PKIXExtensions.SubjectAlternativeName_Id.toString(), + ext, info); + } else { + CMS.debug("SubjectAltNameExtDefault: populate sees no extension. get out"); + } + } + + public SubjectAlternativeNameExtension createExtension(IRequest request) + throws IOException { + SubjectAlternativeNameExtension ext = null; + int num = getNumGNs(); + + boolean critical = Boolean.valueOf( + getConfig(CONFIG_CRITICAL)).booleanValue(); + + GeneralNames gn = new GeneralNames(); + int count = 0; // # of actual gnames + for (int i = 0; i < num; i++) { + String enable = getConfig(CONFIG_GN_ENABLE + i); + if (enable != null && enable.equals("true")) { + CMS.debug("SubjectAltNameExtDefault: createExtension i=" + i); + + String pattern = getConfig(CONFIG_PATTERN + i); + if (pattern == null || pattern.equals("")) { + pattern = " "; + } + + if (!pattern.equals("")) { + String gname = ""; + + // cfu - see if this is server-generated (e.g. UUID4) + // to use this feature, use $server.source$ in pattern + String source = getConfig(CONFIG_SOURCE + i); + String type = getConfig(CONFIG_TYPE + i); + if ((source != null) && (!source.equals(""))) { + if (type.equalsIgnoreCase("OtherName")) { + CMS.debug("SubjectAlternativeNameExtension: using " + + source + " as gn"); + if (source.equals(CONFIG_SOURCE_UUID4)) { + UUID randUUID = UUID.randomUUID(); + // call the mapPattern that does server-side gen + // request is not used, but needed for the substitute + // function + gname = mapPattern(randUUID.toString(), request, pattern); + } else { //expand more server-gen types here + CMS.debug("SubjectAltNameExtDefault: createExtension - unsupported server-generated type: " + + source + ". Supported: UUID4"); + continue; + } + } else { + CMS.debug("SubjectAltNameExtDefault: createExtension - source is only supported for subjAltExtType OtherName"); + continue; + } + } else { + if (request != null) { + gname = mapPattern(request, pattern); + } + } + + if (gname.equals("")) { + CMS.debug("gname is empty, not added"); + continue; + } + CMS.debug("SubjectAltNameExtDefault: createExtension got gname=" + gname); + + GeneralNameInterface n = parseGeneralName(type + ":" + gname); + + CMS.debug("adding gname: " + gname); + if (n != null) { + CMS.debug("SubjectAlternativeNameExtension: n not null"); + gn.addElement(n); + count++; + } else { + CMS.debug("SubjectAlternativeNameExtension: n null"); + } + } + } + } //for + + if (count != 0) { + try { + ext = new SubjectAlternativeNameExtension(); + } catch (Exception e) { + CMS.debug(e.toString()); + throw new IOException(e.toString()); + } + ext.set(SubjectAlternativeNameExtension.SUBJECT_NAME, gn); + ext.setCritical(critical); + } else { + CMS.debug("count is 0"); + } + return ext; + } + + public String mapPattern(IRequest request, String pattern) + throws IOException { + Pattern p = new Pattern(pattern); + IAttrSet attrSet = null; + if (request != null) { + attrSet = request.asIAttrSet(); + } + return p.substitute("request", attrSet); + } + + // for server-side generated values + public String mapPattern(String val, IRequest request, String pattern) + throws IOException { + Pattern p = new Pattern(pattern); + IAttrSet attrSet = null; + if (request != null) { + attrSet = request.asIAttrSet(); + } + try { + attrSet.set("source", val); + } catch (Exception e) { + CMS.debug("SubjectAlternativeNameExtension: mapPattern source " + e.toString()); + } + + return p.substitute("server", attrSet); + } +} -- cgit