From db615a895b644af038308ae71b680f1d93f78f70 Mon Sep 17 00:00:00 2001 From: mharmsen Date: Sat, 29 Oct 2011 04:43:21 +0000 Subject: Bugzilla Bug #737761 - Update Dogtag Packages for Fedora 16 git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/tags/DOGTAG_9_0_FEDORA_15_16_17_20111028@2279 c9f7a03b-bd48-0410-a16d-cbbf54688b0b --- .../netscape/cms/profile/def/EnrollDefault.java | 796 +++++++++++++++++++++ 1 file changed, 796 insertions(+) create mode 100644 pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java (limited to 'pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java') diff --git a/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java new file mode 100644 index 000000000..c45798281 --- /dev/null +++ b/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java @@ -0,0 +1,796 @@ +// --- 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.*; +import java.util.*; +import java.security.cert.CertificateException; + +import com.netscape.certsrv.base.*; +import com.netscape.certsrv.common.*; +import com.netscape.certsrv.profile.*; +import com.netscape.certsrv.request.*; +import com.netscape.certsrv.property.*; +import com.netscape.certsrv.apps.*; +import com.netscape.certsrv.pattern.*; +import com.netscape.certsrv.apps.*; + +import com.netscape.cms.profile.common.EnrollProfile; +import netscape.security.x509.*; +import netscape.security.util.*; +import netscape.security.extensions.*; + + +/** + * This class implements an enrollment default policy. + * + * @version $Revision$, $Date$ + */ +public abstract class EnrollDefault implements IPolicyDefault, ICertInfoPolicyDefault { + + public static final String PROP_NAME = "name"; + + public static final String GN_RFC822_NAME = "RFC822Name"; + public static final String GN_DNS_NAME = "DNSName"; + public static final String GN_URI_NAME = "URIName"; + public static final String GN_IP_NAME = "IPAddressName"; + public static final String GN_DIRECTORY_NAME = "DirectoryName"; + public static final String GN_EDI_NAME = "EDIPartyName"; + public static final String GN_ANY_NAME = "OtherName"; + public static final String GN_OID_NAME = "OIDName"; + + protected IConfigStore mConfig = null; + protected Vector mConfigNames = new Vector(); + protected Vector mValueNames = new Vector(); + + public EnrollDefault() { + } + + public Enumeration getConfigNames() { + return mConfigNames.elements(); + } + + public IDescriptor getConfigDescriptor(Locale locale, String name) { + return null; + } + + public void addConfigName(String name) { + mConfigNames.addElement(name); + } + + public void setConfig(String name, String value) + throws EPropertyException { + if (mConfig.getSubStore("params") == null) { + // + } else { + mConfig.getSubStore("params").putString(name, value); + } + } + + public String getConfig(String name) { + try { + if (mConfig == null) + return null; + if (mConfig.getSubStore("params") != null) { + return mConfig.getSubStore("params").getString(name); + } + } catch (EBaseException e) { + } + return ""; + } + + public void init(IProfile profile, IConfigStore config) + throws EProfileException { + mConfig = config; + } + + /** + * Retrieves the localizable description of this policy. + * + * @param locale locale of the end user + * @return localized description of this default policy + */ + public abstract String getText(Locale locale); + + + public IConfigStore getConfigStore() { + return mConfig; + } + + public String getName(Locale locale) { + try { + return mConfig.getString(PROP_NAME); + } catch (EBaseException e) { + return null; + } + } + + /** + * Populates attributes into the certificate template. + * + * @param request enrollment request + * @param info certificate template + * @exception EProfileException failed to populate attributes + * into request + */ + public abstract void populate(IRequest request, X509CertInfo info) + throws EProfileException; + + /** + * Sets values from the approval page into certificate template. + * + * @param name name of the attribute + * @param locale user locale + * @param info certificate template + * @param value attribute value + * @exception EProfileException failed to set attributes + * into request + */ + public abstract void setValue(String name, Locale locale, + X509CertInfo info, String value) + throws EPropertyException; + + /** + * Retrieves certificate template values and returns them to + * the approval page. + * + * @param name name of the attribute + * @param locale user locale + * @param info certificate template + * @exception EProfileException failed to get attributes + * from request + */ + public abstract String getValue(String name, Locale locale, + X509CertInfo info) + throws EPropertyException; + + /** + * Populates the request with this policy default. + * + * The current implementation extracts enrollment specific attributes + * and calls the populate() method of the subclass. + * + * @param request request to be populated + * @exception EProfileException failed to populate + */ + public void populate(IRequest request) + throws EProfileException { + String name = getClass().getName(); + + name = name.substring(name.lastIndexOf('.') + 1); + CMS.debug(name + ": populate start"); + X509CertInfo info = + request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO); + + populate(request, info); + + request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info); + CMS.debug(name + ": populate end"); + } + + public void addValueName(String name) { + mValueNames.addElement(name); + } + + public Enumeration getValueNames() { + return mValueNames.elements(); + } + + public IDescriptor getValueDescriptor(String name) { + return null; + } + + /** + * Sets the value of the given value property by name. + * + * The current implementation extracts enrollment specific attributes + * and calls the setValue() method of the subclass. + * + * @param name name of property + * @param locale locale of the end user + * @param request request + * @param value value to be set in the given request + * @exception EPropertyException failed to set property + */ + public void setValue(String name, Locale locale, IRequest request, + String value) + throws EPropertyException { + X509CertInfo info = + request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO); + + setValue(name, locale, info, value); + + request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info); + } + + /** + * Retrieves the value of the given value + * property by name. + * + * The current implementation extracts enrollment specific attributes + * and calls the getValue() method of the subclass. + * + * @param name name of property + * @param locale locale of the end user + * @param request request + * @exception EPropertyException failed to get property + */ + public String getValue(String name, Locale locale, IRequest request) + throws EPropertyException { + X509CertInfo info = + request.getExtDataInCertInfo(IEnrollProfile.REQUEST_CERTINFO); + + String value = getValue(name, locale, info); + request.setExtData(IEnrollProfile.REQUEST_CERTINFO, info); + return value; + } + + public String toHexString(byte data[]) { + IPrettyPrintFormat pp = CMS.getPrettyPrintFormat(":"); + String s = pp.toHexString(data, 0, 16); + StringTokenizer st = new StringTokenizer(s, "\n"); + StringBuffer buffer = new StringBuffer(); + + while (st.hasMoreTokens()) { + buffer.append(st.nextToken()); + buffer.append("\\n"); + } + return buffer.toString(); + } + + protected void refreshConfigAndValueNames() { + mConfigNames.removeAllElements(); + mValueNames.removeAllElements(); + } + + protected void deleteExtension(String name, X509CertInfo info) { + CertificateExtensions exts = null; + + try { + exts = (CertificateExtensions) + info.get(X509CertInfo.EXTENSIONS); + if (exts == null) + return; + Enumeration e = exts.getNames(); + + while (e.hasMoreElements()) { + String n = (String) e.nextElement(); + Extension ext = (Extension) exts.get(n); + + if (ext.getExtensionId().toString().equals(name)) { + exts.delete(n); + } + } + } catch (Exception e) { + CMS.debug(e.toString()); + } + } + + protected Extension getExtension(String name, X509CertInfo info) { + CertificateExtensions exts = null; + + try { + exts = (CertificateExtensions) + info.get(X509CertInfo.EXTENSIONS); + } catch (Exception e) { + CMS.debug("EnrollDefault: getExtension " + e.toString()); + } + if (exts == null) + return null; + return getExtension(name, exts); + } + + protected Extension getExtension(String name, CertificateExtensions exts) { + if (exts == null) + return null; + Enumeration e = exts.getElements(); + + while (e.hasMoreElements()) { + Extension ext = (Extension) e.nextElement(); + + if (ext.getExtensionId().toString().equals(name)) { + return ext; + } + } + return null; + } + + protected void addExtension(String name, Extension ext, X509CertInfo info) + throws EProfileException { + if (ext == null) { + throw new EProfileException("extension not found"); + } + CertificateExtensions exts = null; + + Extension alreadyPresentExtension = getExtension(name,info); + + if (alreadyPresentExtension != null) { + String eName = ext.toString(); + CMS.debug("EnrollDefault.addExtension: duplicate extension attempted! Name: " + eName); + throw new EProfileException(CMS.getUserMessage("CMS_PROFILE_DUPLICATE_EXTENSION",eName)); + } + + try { + exts = (CertificateExtensions) + info.get(X509CertInfo.EXTENSIONS); + } catch (Exception e) { + CMS.debug("EnrollDefault: " + e.toString()); + } + if (exts == null) { + throw new EProfileException("extensions not found"); + } + try { + exts.set(name, ext); + } catch (IOException e) { + CMS.debug("EnrollDefault: " + e.toString()); + } + } + + protected void replaceExtension(String name, Extension ext, X509CertInfo info) + throws EProfileException { + deleteExtension(name, info); + addExtension(name, ext, info); + } + + protected boolean isOptional(String value) { + return value.equals(""); + } + + protected boolean getBoolean(String value) { + return Boolean.valueOf(value).booleanValue(); + } + + protected int getInt(String value) { + return Integer.valueOf(value).intValue(); + } + + protected boolean getConfigBoolean(String value) { + return getBoolean(getConfig(value)); + } + + protected int getConfigInt(String value) { + return getInt(getConfig(value)); + } + + protected boolean isGeneralNameValid(String name) + { + if (name == null) + return false; + int pos = name.indexOf(':'); + if (pos == -1) + return false; + String nameType = name.substring(0, pos).trim(); + String nameValue = name.substring(pos + 1).trim(); + if (nameValue.equals("")) + return false; + return true; + } + + protected GeneralNameInterface parseGeneralName(String name) + throws IOException { + int pos = name.indexOf(':'); + if (pos == -1) + return null; + String nameType = name.substring(0, pos).trim(); + String nameValue = name.substring(pos + 1).trim(); + return parseGeneralName(nameType, nameValue); + } + + protected boolean isGeneralNameType(String nameType) + { + if (nameType.equalsIgnoreCase("RFC822Name")) { + return true; + } + if (nameType.equalsIgnoreCase("DNSName")) { + return true; + } + if (nameType.equalsIgnoreCase("x400")) { + return true; + } + if (nameType.equalsIgnoreCase("DirectoryName")) { + return true; + } + if (nameType.equalsIgnoreCase("EDIPartyName")) { + return true; + } + if (nameType.equalsIgnoreCase("URIName")) { + return true; + } + if (nameType.equalsIgnoreCase("IPAddress")) { + return true; + } + if (nameType.equalsIgnoreCase("OIDName")) { + return true; + } + if (nameType.equalsIgnoreCase("OtherName")) { + return true; + } + return false; + } + + protected GeneralNameInterface parseGeneralName(String nameType, String nameValue) + throws IOException + { + if (nameType.equalsIgnoreCase("RFC822Name")) { + return new RFC822Name(nameValue); + } + if (nameType.equalsIgnoreCase("DNSName")) { + return new DNSName(nameValue); + } + if (nameType.equalsIgnoreCase("x400")) { + // XXX + } + if (nameType.equalsIgnoreCase("DirectoryName")) { + return new X500Name(nameValue); + } + if (nameType.equalsIgnoreCase("EDIPartyName")) { + return new EDIPartyName(nameValue); + } + if (nameType.equalsIgnoreCase("URIName")) { + return new URIName(nameValue); + } + if (nameType.equalsIgnoreCase("IPAddress")) { + CMS.debug("IP Value:" + nameValue); + if (nameValue.indexOf('/') != -1) { + // CIDR support for NameConstraintsExt + StringTokenizer st = new StringTokenizer(nameValue, "/"); + String addr = st.nextToken(); + String netmask = st.nextToken(); + CMS.debug("addr:" + addr +" netmask: "+netmask); + return new IPAddressName(addr, netmask); + } else { + return new IPAddressName(nameValue); + } + } + if (nameType.equalsIgnoreCase("OIDName")) { + try { + // check if OID + ObjectIdentifier oid = new ObjectIdentifier(nameValue); + } catch (Exception e) { + return null; + } + return new OIDName(nameValue); + } + if (nameType.equals("OtherName")) { + if (nameValue == null || nameValue.length() == 0) + nameValue = " "; + if (nameValue.startsWith("(PrintableString)")) { + // format: OtherName: (PrintableString)oid,value + int pos0 = nameValue.indexOf(')'); + int pos1 = nameValue.indexOf(','); + if (pos1 == -1) + return null; + String on_oid = nameValue.substring(pos0 + 1, pos1).trim(); + String on_value = nameValue.substring(pos1 + 1).trim(); + if (isValidOID(on_oid)) { + return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_PrintableString, on_value); + } else { + return null; + } + } else if (nameValue.startsWith("(KerberosName)")) { + // Syntax: (KerberosName)Realm|NameType|NameString(s) + int pos0 = nameValue.indexOf(')'); + int pos1 = nameValue.indexOf('|'); + int pos2 = nameValue.lastIndexOf('|'); + String realm = nameValue.substring(pos0 + 1, pos1).trim(); + String name_type = nameValue.substring(pos1 + 1, pos2).trim(); + String name_strings = nameValue.substring(pos2 + 1).trim(); + Vector strings = new Vector(); + StringTokenizer st = new StringTokenizer(name_strings, ","); + while (st.hasMoreTokens()) { + strings.addElement(st.nextToken()); + } + KerberosName name = new KerberosName(realm, + Integer.parseInt(name_type), strings); + // krb5 OBJECT IDENTIFIER ::= { iso (1) + // org (3) + // dod (6) + // internet (1) + // security (5) + // kerberosv5 (2) } + // krb5PrincipalName OBJECT IDENTIFIER ::= { krb5 2 } + return new OtherName(KerberosName.KRB5_PRINCIPAL_NAME, + name.toByteArray()); + } else if (nameValue.startsWith("(IA5String)")) { + int pos0 = nameValue.indexOf(')'); + int pos1 = nameValue.indexOf(','); + if (pos1 == -1) + return null; + String on_oid = nameValue.substring(pos0 + 1, pos1).trim(); + String on_value = nameValue.substring(pos1 + 1).trim(); + if (isValidOID(on_oid)) { + return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_IA5String, on_value); + } else { + return null; + } + } else if (nameValue.startsWith("(UTF8String)")) { + int pos0 = nameValue.indexOf(')'); + int pos1 = nameValue.indexOf(','); + if (pos1 == -1) + return null; + String on_oid = nameValue.substring(pos0 + 1, pos1).trim(); + String on_value = nameValue.substring(pos1 + 1).trim(); + if (isValidOID(on_oid)) { + return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_UTF8String, on_value); + } else { + return null; + } + } else if (nameValue.startsWith("(BMPString)")) { + int pos0 = nameValue.indexOf(')'); + int pos1 = nameValue.indexOf(','); + if (pos1 == -1) + return null; + String on_oid = nameValue.substring(pos0 + 1, pos1).trim(); + String on_value = nameValue.substring(pos1 + 1).trim(); + if (isValidOID(on_oid)) { + return new OtherName(new ObjectIdentifier(on_oid), DerValue.tag_BMPString, on_value); + } else { + return null; + } + } else if (nameValue.startsWith("(Any)")) { + int pos0 = nameValue.indexOf(')'); + int pos1 = nameValue.indexOf(','); + if (pos1 == -1) + return null; + String on_oid = nameValue.substring(pos0 + 1, pos1).trim(); + String on_value = nameValue.substring(pos1 + 1).trim(); + if (isValidOID(on_oid)) { + CMS.debug("OID: " + on_oid + " Value:" + on_value); + return new OtherName(new ObjectIdentifier(on_oid), getBytes(on_value)); + } else { + CMS.debug("Invalid OID " + on_oid); + return null; + } + } else { + return null; + } + } + return null; + } + +/** + * Converts string containing pairs of characters in the range of '0' + * to '9', 'a' to 'f' to an array of bytes such that each pair of + * characters in the string represents an individual byte + */ + public byte[] getBytes(String string) { + if (string == null) + return null; + int stringLength = string.length(); + if ((stringLength == 0) || ((stringLength % 2) != 0)) + return null; + byte[] bytes = new byte[ (stringLength / 2) ]; + for (int i = 0, b = 0; i < stringLength; i += 2, ++b) { + String nextByte = string.substring(i, (i + 2)); + bytes[b] = (byte)Integer.parseInt(nextByte, 0x10); + } + return bytes; + } + + /** + * Check if a object identifier in string form is valid, + * that is a string in the form n.n.n.n and der encode and decode-able. + * @param oid object identifier string. + * @return true if the oid is valid + */ + public boolean isValidOID(String oid) + { + ObjectIdentifier v = null; + try { + v = ObjectIdentifier.getObjectIdentifier(oid); + } catch (Exception e) { + return false; + } + if (v == null) + return false; + + // if the OID isn't valid (ex. n.n) the error isn't caught til + // encoding time leaving a bad request in the request queue. + try { + DerOutputStream derOut = new DerOutputStream(); + + derOut.putOID(v); + new ObjectIdentifier(new DerInputStream(derOut.toByteArray())); + } catch (Exception e) { + return false; + } + return true; + } + + protected String buildRecords(Vector recs) throws EPropertyException { + StringBuffer sb = new StringBuffer(); + + for (int i = 0; i < recs.size(); i++) { + NameValuePairs pairs = (NameValuePairs) recs.elementAt(i); + + sb.append("Record #"); + sb.append(i); + sb.append("\r\n"); + Enumeration e = pairs.getNames(); + + while (e.hasMoreElements()) { + String key = (String) e.nextElement(); + String val = pairs.getValue(key); + + sb.append(key); + sb.append(":"); + sb.append(val); + sb.append("\r\n"); + } + sb.append("\r\n"); + + } + return sb.toString(); + } + + protected Vector parseRecords(String value) throws EPropertyException { + StringTokenizer st = new StringTokenizer(value, "\r\n"); + int num = 0; + Vector v = new Vector(); + NameValuePairs nvps = null; + + while (st.hasMoreTokens()) { + String token = (String) st.nextToken(); + + if (token.equals("Record #" + num)) { + CMS.debug("parseRecords: Record" + num); + nvps = new NameValuePairs(); + v.addElement(nvps); + try { + token = (String) st.nextToken(); + } catch (NoSuchElementException e) { + v.removeElementAt(num); + CMS.debug(e.toString()); + return v; + } + num++; + } + + if (nvps == null) + throw new EPropertyException("Bad Input Format"); + + int pos = token.indexOf(":"); + + if (pos <= 0) { + CMS.debug("parseRecords: No colon found in the input line"); + throw new EPropertyException("Bad Input Format"); + } else { + if (pos == (token.length() - 1)) { + nvps.add(token.substring(0, pos), ""); + } else { + nvps.add(token.substring(0, pos), token.substring(pos + 1)); + } + } + } + + return v; + } + + protected String getGeneralNameType(GeneralName gn) + throws EPropertyException { + int type = gn.getType(); + + if (type == GeneralNameInterface.NAME_RFC822) + return "RFC822Name"; + else if (type == GeneralNameInterface.NAME_DNS) + return "DNSName"; + else if (type == GeneralNameInterface.NAME_URI) + return "URIName"; + else if (type == GeneralNameInterface.NAME_IP) + return "IPAddress"; + else if (type == GeneralNameInterface.NAME_DIRECTORY) + return "DirectoryName"; + else if (type == GeneralNameInterface.NAME_EDI) + return "EDIPartyName"; + else if (type == GeneralNameInterface.NAME_ANY) + return "OtherName"; + else if (type == GeneralNameInterface.NAME_OID) + return "OIDName"; + + throw new EPropertyException("Unsupported type: " + type); + } + + protected String getGeneralNameValue(GeneralName gn) throws EPropertyException { + String s = gn.toString(); + int type = gn.getType(); + + if (type == GeneralNameInterface.NAME_DIRECTORY) + return s; + else { + int pos = s.indexOf(":"); + + if (pos <= 0) + throw new EPropertyException("Badly formatted general name: " + s); + else { + return s.substring(pos + 1).trim(); + } + } + } + + public Locale getLocale(IRequest request) { + Locale locale = null; + + if (request == null) + return null; + + String language = request.getExtDataInString( + EnrollProfile.REQUEST_LOCALE); + if (language != null) { + locale = new Locale(language); + } + return locale; + } + + public String toGeneralNameString(GeneralName gn) { + int type = gn.getType(); + // Sun's General Name is not consistent, so we need + // to do a special case for directory string + if (type == GeneralNameInterface.NAME_DIRECTORY) { + return "DirectoryName: " + gn.toString(); + } + return gn.toString(); + } + + protected String mapPattern(IRequest request, String pattern) + throws IOException { + Pattern p = new Pattern(pattern); + IAttrSet attrSet = null; + if (request != null) { + attrSet = request.asIAttrSet(); + } + return p.substitute2("request", attrSet); + } + + protected StringBuffer escapeValueRfc1779(String v, boolean doubleEscape) + { + StringBuffer result = new StringBuffer(); + + // Do we need to escape any characters + for (int i = 0; i < v.length(); i++) { + int c = v.charAt(i); + if (c == ',' || c == '=' || c == '+' || c == '<' || + c == '>' || c == '#' || c == ';' || c == '\r' || + c == '\n' || c == '\\' || c == '"') { + if ((c == 0x5c) && ((i+1) < v.length())) { + int nextC = v.charAt(i+1); + if ((c == 0x5c) && (nextC == ',' || nextC == '=' || nextC == '+' || + nextC == '<' || nextC == '>' || nextC == '#' || + nextC == ';' || nextC == '\r' || nextC == '\n' || + nextC == '\\' || nextC == '"')) { + if (doubleEscape) result.append('\\'); + } else { + result.append('\\'); + if (doubleEscape) result.append('\\'); + } + } else { + result.append('\\'); + if (doubleEscape) result.append('\\'); + } + } + if (c == '\r') { + result.append("0D"); + } else if (c == '\n') { + result.append("0A"); + } else { + result.append((char)c); + } + } + return result; + } + +} -- cgit