summaryrefslogtreecommitdiffstats
path: root/pki/base/common/src/com/netscape/cms/policy
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/common/src/com/netscape/cms/policy')
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/APolicyRule.java354
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java165
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java401
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java249
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java105
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java207
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java221
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java103
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java274
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java235
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java342
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java208
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java442
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java189
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java47
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java299
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java316
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java381
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java418
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java498
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java464
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java521
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java247
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java320
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java271
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java471
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java252
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java351
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java288
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java541
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java468
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java183
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java282
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java417
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java164
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java250
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java141
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java350
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java322
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java434
-rw-r--r--pki/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java368
41 files changed, 12559 insertions, 0 deletions
diff --git a/pki/base/common/src/com/netscape/cms/policy/APolicyRule.java b/pki/base/common/src/com/netscape/cms/policy/APolicyRule.java
new file mode 100644
index 000000000..d0bd6a6bc
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/APolicyRule.java
@@ -0,0 +1,354 @@
+// --- 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.policy;
+
+
+import java.util.*;
+import java.text.*;
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.AgentApprovals;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import java.security.*;
+import java.security.cert.*;
+
+
+/**
+ * The abstract policy rule that concrete implementations will
+ * extend.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public abstract class APolicyRule implements IPolicyRule {
+ protected String NAME = null;
+ protected String DESC = null;
+ protected IExpression mFilterExp = null;
+ protected String mInstanceName = null;
+ protected ILogger mLogger = CMS.getLogger();
+
+ public APolicyRule() {
+ }
+
+ /**
+ * Initializes the policy rule.
+ * <P>
+ *
+ * @param config The config store reference
+ */
+ public abstract void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException;
+
+ /**
+ * Gets the description for this policy rule.
+ * <P>
+ * @return The Description for this rule.
+ */
+ public String getDescription() {
+ return DESC;
+ }
+
+ /**
+ * Sets a predicate expression for rule matching.
+ * <P>
+ *
+ * @param exp The predicate expression for the rule.
+ */
+ public void setPredicate(IExpression exp) {
+ mFilterExp = exp;
+ }
+
+ /**
+ * Returns the predicate expression for the rule.
+ * <P>
+ *
+ * @return The predicate expression for the rule.
+ */
+ public IExpression getPredicate() {
+ return mFilterExp;
+ }
+
+ /**
+ * Returns the name of the policy rule.
+ * <P>
+ *
+ * @return The name of the policy class.
+ */
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Sets the instance name for a policy rule.
+ * <P>
+ *
+ * @param instanceName The name of the rule instance.
+ */
+ public void setInstanceName(String instanceName) {
+ mInstanceName = instanceName;
+ }
+
+ /**
+ * Returns the name of the policy rule instance.
+ * <P>
+ *
+ * @return The name of the policy rule instance if set, else
+ * the name of the rule class.
+ */
+ public String getInstanceName() {
+ return mInstanceName != null ? mInstanceName : NAME;
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public abstract PolicyResult apply(IRequest req);
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public abstract Vector getInstanceParams();
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public abstract Vector getDefaultParams();
+
+ public void setError(IRequest req, String format, Object[] params) {
+ setPolicyException(req, format, params);
+ }
+
+ public void setError(IRequest req, String format, String arg1,
+ String arg2) {
+ Object[] np = new Object[2];
+
+ np[0] = arg1;
+ np[1] = arg2;
+ setPolicyException(req, format, np);
+ }
+
+ public void setError(IRequest req, String format, String arg) {
+ Object[] np = new Object[1];
+
+ np[0] = arg;
+ setPolicyException(req, format, np);
+ }
+
+ public void setPolicyException(IRequest req, EBaseException ex) {
+ Vector ev = req.getExtDataInStringVector(IRequest.ERRORS);
+ if (ev == null) {
+ ev = new Vector();
+ }
+ ev.addElement(ex.toString());
+ req.setExtData(IRequest.ERRORS, ev);
+
+ }
+
+ /**
+ * determines whether a DEFERRED policy result should be returned
+ * by checking the contents of the AgentApprovals attribute. This
+ * call should be used by policy modules instead of returning
+ * PolicyResult.DEFERRED directly.
+ * <p>
+ */
+ protected PolicyResult deferred(IRequest req) {
+ // Try to find an agent approval
+ AgentApprovals aa = AgentApprovals.fromStringVector(
+ req.getExtDataInStringVector(AgentApprovals.class.getName()));
+
+ // Any approvals causes success
+ if (aa != null && aa.elements().hasMoreElements()) {
+ return PolicyResult.ACCEPTED;
+ } else {
+ return PolicyResult.DEFERRED;
+ }
+ }
+
+ /**
+ * request has previously been approved by an agent
+ */
+ protected boolean agentApproved(IRequest req) {
+ // Try to find an agent approval
+ AgentApprovals aa = AgentApprovals.fromStringVector(
+ req.getExtDataInStringVector(AgentApprovals.class.getName()));
+
+ // Any approvals causes success
+ if (aa != null && aa.elements().hasMoreElements()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public void setPolicyException(IRequest req, String format,
+ Object[] params) {
+ if (format == null)
+ return;
+
+ EPolicyException ex;
+
+ if (params == null)
+ ex = new EPolicyException(format);
+ else
+ ex = new EPolicyException(format, params);
+
+ Vector ev = req.getExtDataInStringVector(IRequest.ERRORS);
+ if (ev == null) {
+ ev = new Vector();
+ }
+ ev.addElement(ex.toString());
+ req.setExtData(IRequest.ERRORS, ev);
+ }
+
+ /**
+ * log a message for this policy rule.
+ */
+ protected void log(int level, String msg) {
+ mLogger.log(ILogger.EV_SYSTEM, ILogger.S_OTHER, level,
+ "APolicyRule " + NAME + ": " + msg);
+ }
+
+ public static KeyIdentifier createKeyIdentifier(X509Key key)
+ throws NoSuchAlgorithmException, InvalidKeyException {
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(key.getEncoded());
+ return new KeyIdentifier(md.digest());
+ }
+
+ /**
+ * Form a byte array of octet string key identifier from the sha-1 hash of
+ * the Subject Public Key INFO. (including algorithm ID, etc.)
+ * <p>
+ * @param certInfo cert info of the certificate.
+ * @return A Key identifier with the sha-1 hash of subject public key.
+ */
+ protected KeyIdentifier formSpkiSHA1KeyId(X509CertInfo certInfo)
+ throws EBaseException {
+ KeyIdentifier keyId = null;
+
+ try {
+ CertificateX509Key certKey =
+ (CertificateX509Key) certInfo.get(X509CertInfo.KEY);
+
+ if (certKey == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", ""));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+
+ if (key == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", ""));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ keyId = createKeyIdentifier(key);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (InvalidKeyException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ }
+ return keyId;
+ }
+
+ /**
+ * Form a byte array of octet string key identifier from the sha-1 hash of
+ * the Subject Public Key BIT STRING.
+ * <p>
+ * @param certInfo cert info of the certificate.
+ * @return A Key identifier with the sha-1 hash of subject public key.
+ */
+ protected KeyIdentifier formSHA1KeyId(X509CertInfo certInfo)
+ throws EBaseException {
+ KeyIdentifier keyId = null;
+
+ try {
+ CertificateX509Key certKey =
+ (CertificateX509Key) certInfo.get(X509CertInfo.KEY);
+
+ if (certKey == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", ""));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+
+ if (key == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", ""));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ byte[] rawKey = key.getKey();
+
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(rawKey);
+ keyId = new KeyIdentifier(md.digest());
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ }
+ return keyId;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java b/pki/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java
new file mode 100644
index 000000000..0702ef29c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/AgentPolicy.java
@@ -0,0 +1,165 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.IPolicy;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.AgentApprovals;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.CMS;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * AgentPolicy is an enrollment policy wraps another policy module.
+ * Requests are sent first to the contained module, but if the
+ * policy indicates that the request should be deferred, a check
+ * for agent approvals is done. If any are found, the request
+ * is approved.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AgentPolicy extends APolicyRule
+ implements IEnrollmentPolicy {
+ public AgentPolicy() {
+ NAME = "AgentPolicy";
+ DESC = "Agent Approval Policy";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=AgentPolicy
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate= ou == engineering AND o == netscape.com
+ * ra.Policy.rule.<ruleName>.class=xxxx
+ * ra.Policy.rule.<ruleName>.params.*
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ // Create subordinate object
+ String className = (String) config.get("class");
+
+ System.err.println("Creating agent policy with class " + className);
+ if (className != null) {
+ IConfigStore substore = config.getSubStore("params");
+
+ try {
+ Class c = Class.forName(className);
+
+ Object o = c.newInstance();
+
+ if (!(o instanceof APolicyRule)) {
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CLASS",
+ getInstanceName(), className));
+ }
+
+ APolicyRule pr = (APolicyRule) o;
+
+ pr.init(owner, substore);
+ mPolicy = pr;
+ } catch (EPolicyException e) {
+ System.err.println("Agent Policy Error: " + e);
+ throw e;
+ } catch (Exception e) {
+ System.err.println("Agent Policy Error: " + e);
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_LOADING_POLICY_ERROR",
+ getInstanceName(), className));
+ }
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // The default is to require manual approval for everything
+ PolicyResult result = PolicyResult.DEFERRED;
+
+ // Give the underlying object a chance
+ if (mPolicy != null) {
+ result = mPolicy.apply(req);
+ System.err.println("Subordinate policy returns " + result);
+ }
+
+ if (result == PolicyResult.DEFERRED) {
+ System.err.println("Checking agent approvals");
+ // Try to find an agent approval
+ AgentApprovals aa = AgentApprovals.fromStringVector(
+ req.getExtDataInStringVector(AgentApprovals.class.getName()));
+
+ //Object o = req.get("agentApprovals");
+
+ // Any approvals causes success
+ if (aa != null && aa.elements().hasMoreElements()) //if (o != null)
+ {
+ System.err.println("Agent approval found");
+ result = PolicyResult.ACCEPTED;
+ }
+ }
+ System.err.println("Agent policy returns " + result);
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return null;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return null;
+ }
+
+ APolicyRule mPolicy = null;
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java
new file mode 100644
index 000000000..3410c7baa
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/AttributePresentConstraints.java
@@ -0,0 +1,401 @@
+// --- 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.policy.constraints;
+
+
+import java.io.File;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.ldap.*;
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.notification.*;
+import java.security.*;
+import java.security.cert.*;
+import java.io.IOException;
+import java.util.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.common.*;
+import java.text.DateFormat;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This checks if attribute present.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AttributePresentConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_ENABLED = "enabled";
+ protected static final String PROP_LDAP = "ldap";
+
+ protected String mName = null;
+ protected String mImplName = null;
+
+ private boolean mEnabled = false;
+ private ILogger mLogger = CMS.getLogger();
+ private Hashtable mContentParams = new Hashtable();
+
+ private ICertAuthority mSub = null;
+ private IConfigStore mConfig = null;
+ private IConfigStore mLdapConfig = null;
+ private RequestId mReqId = null;
+ private ILdapConnFactory mConnFactory = null;
+ private LDAPConnection mCheckAttrLdapConnection = null;
+
+ public AttributePresentConstraints() {
+ DESC = "Rejects request if ldap attribute is not present in the " +
+ "directory.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String params[] = {
+ PROP_ATTR + ";string,required;Ldap attribute to check presence of (default " +
+ DEF_ATTR + ")",
+ PROP_VALUE + ";string;if this parameter is non-empty, the attribute must " +
+ "match this value for the request to proceed ",
+ PROP_LDAP_BASE + ";string,required;Base DN to start searching " +
+ "under. If your user's DN is 'uid=jsmith, o=company', you " +
+ "might want to use 'o=company' here",
+ PROP_LDAP_HOST + ";string,required;" +
+ "LDAP host to connect to",
+ PROP_LDAP_PORT + ";number,required;" +
+ "LDAP port number (use 389, or 636 if SSL)",
+ PROP_LDAP_SSL + ";boolean;" +
+ "Use SSL to connect to directory?",
+ PROP_LDAP_VER + ";choice(3,2),required;" +
+ "LDAP protocol version",
+ PROP_LDAP_BIND + ";string;DN to bind as for attribute checking. " +
+ "For example 'CN=Pincheck User'",
+ PROP_LDAP_PW + ";password;Enter password used to bind as " +
+ "the above user",
+ PROP_LDAP_AUTH + ";choice(BasicAuth,SslClientAuth),required;" +
+ "How to bind to the directory",
+ PROP_LDAP_CERT + ";string;If you want to use " +
+ "SSL client auth to the directory, set the client " +
+ "cert nickname here",
+ PROP_LDAP_BASE + ";string,required;Base DN to start searching " +
+ "under. If your user's DN is 'uid=jsmith, o=company', you " +
+ "might want to use 'o=company' here",
+ PROP_LDAP_MINC + ";number;number of connections " +
+ "to keep open to directory server. Default " + DEF_LDAP_MINC,
+ PROP_LDAP_MAXC + ";number;when needed, connection " +
+ "pool can grow to this many (multiplexed) connections. Default " + DEF_LDAP_MAXC,
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-pinpresent",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";" + DESC + " This plugin can be used to " +
+ "check the presence (and, optionally, the value) of any LDAP " +
+ "attribute for the user. "
+ };
+
+ return params;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public String getImplName() {
+ return mImplName;
+ }
+
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ public void shutdown() {
+ }
+
+ // Parameters
+
+ protected static final String PROP_LDAP_HOST = "ldap.ldapconn.host";
+ protected static final String DEF_LDAP_HOST = "localhost";
+
+ protected static final String PROP_LDAP_PORT = "ldap.ldapconn.port";
+ protected static final Integer DEF_LDAP_PORT = Integer.valueOf(389);
+
+ protected static final String PROP_LDAP_SSL = "ldap.ldapconn.secureConn";
+ protected static final Boolean DEF_LDAP_SSL = Boolean.FALSE;
+
+ protected static final String PROP_LDAP_VER = "ldap.ldapconn.version";
+ protected static final Integer DEF_LDAP_VER = Integer.valueOf(3);
+
+ protected static final String PROP_LDAP_BIND = "ldap.ldapauth.bindDN";
+ protected static final String DEF_LDAP_BIND = "CN=Directory Manager";
+
+ protected static final String PROP_LDAP_PW = "ldap.ldapauth.bindPWPrompt";
+ protected static final String DEF_LDAP_PW = "";
+
+ protected static final String PROP_LDAP_CERT = "ldap.ldapauth.clientCertNickname";
+ protected static final String DEF_LDAP_CERT = "";
+
+ protected static final String PROP_LDAP_AUTH = "ldap.ldapauth.authtype";
+ protected static final String DEF_LDAP_AUTH = "BasicAuth";
+
+ protected static final String PROP_LDAP_BASE = "ldap.ldapconn.basedn";
+ protected static final String DEF_LDAP_BASE = "";
+
+ protected static final String PROP_LDAP_MINC = "ldap.ldapconn.minConns";
+ protected static final Integer DEF_LDAP_MINC = Integer.valueOf(1);
+
+ protected static final String PROP_LDAP_MAXC = "ldap.ldapconn.maxConns";
+ protected static final Integer DEF_LDAP_MAXC = Integer.valueOf(5);
+
+ protected static final String PROP_ATTR = "attribute";
+ protected static final String DEF_ATTR = "pin";
+
+ protected static final String PROP_VALUE = "value";
+ protected static final String DEF_VALUE = "";
+
+ protected static Vector mParamNames;
+ protected static Hashtable mParamDefault;
+ protected Hashtable mParamValue = null;
+
+ static {
+ mParamNames = new Vector();
+ mParamDefault = new Hashtable();
+ addParam(PROP_LDAP_HOST, DEF_LDAP_HOST);
+ addParam(PROP_LDAP_PORT, DEF_LDAP_PORT);
+ addParam(PROP_LDAP_SSL, DEF_LDAP_SSL);
+ addParam(PROP_LDAP_VER, DEF_LDAP_VER);
+ addParam(PROP_LDAP_BIND, DEF_LDAP_BIND);
+ addParam(PROP_LDAP_PW, DEF_LDAP_PW);
+ addParam(PROP_LDAP_CERT, DEF_LDAP_CERT);
+ addParam(PROP_LDAP_AUTH, DEF_LDAP_AUTH);
+ addParam(PROP_LDAP_BASE, DEF_LDAP_BASE);
+ addParam(PROP_LDAP_MINC, DEF_LDAP_MINC);
+ addParam(PROP_LDAP_MAXC, DEF_LDAP_MAXC);
+ addParam(PROP_ATTR, DEF_ATTR);
+ addParam(PROP_VALUE, DEF_VALUE);
+ };
+
+ protected static void addParam(String name, Object value) {
+ mParamNames.addElement(name);
+ mParamDefault.put(name, value);
+ }
+
+ protected void getStringConfigParam(IConfigStore config, String paramName) {
+ try {
+ mParamValue.put(
+ paramName, config.getString(paramName, (String) mParamDefault.get(paramName))
+ );
+ } catch (Exception e) {
+ }
+ }
+
+ protected void getIntConfigParam(IConfigStore config, String paramName) {
+ try {
+ mParamValue.put(
+ paramName, Integer.valueOf(
+ config.getInteger(paramName,
+ ((Integer) mParamDefault.get(paramName)).intValue()
+ )
+ )
+ );
+ } catch (Exception e) {
+ }
+ }
+
+ protected void getBooleanConfigParam(IConfigStore config, String paramName) {
+ try {
+ mParamValue.put(
+ paramName, Boolean.valueOf(
+ config.getBoolean(paramName,
+ ((Boolean) mParamDefault.get(paramName)).booleanValue()
+ )
+ )
+ );
+ } catch (Exception e) {
+ }
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mParamValue = new Hashtable();
+
+ getStringConfigParam(mConfig, PROP_LDAP_HOST);
+ getIntConfigParam(mConfig, PROP_LDAP_PORT);
+ getBooleanConfigParam(mConfig, PROP_LDAP_SSL);
+ getIntConfigParam(mConfig, PROP_LDAP_VER);
+ getStringConfigParam(mConfig, PROP_LDAP_BIND);
+ getStringConfigParam(mConfig, PROP_LDAP_PW);
+ getStringConfigParam(mConfig, PROP_LDAP_CERT);
+ getStringConfigParam(mConfig, PROP_LDAP_AUTH);
+ getStringConfigParam(mConfig, PROP_LDAP_BASE);
+ getIntConfigParam(mConfig, PROP_LDAP_MINC);
+ getIntConfigParam(mConfig, PROP_LDAP_MAXC);
+ getStringConfigParam(mConfig, PROP_ATTR);
+ getStringConfigParam(mConfig, PROP_VALUE);
+
+ mLdapConfig = mConfig.getSubStore(PROP_LDAP);
+
+ mConnFactory = CMS.getLdapBoundConnFactory();
+ mConnFactory.init(mLdapConfig);
+ mCheckAttrLdapConnection = mConnFactory.getConn();
+
+ }
+
+ public PolicyResult apply(IRequest r) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ mReqId = r.getRequestId();
+
+ String requestType = r.getRequestType();
+
+ if (requestType.equals(IRequest.ENROLLMENT_REQUEST) ||
+ requestType.equals(IRequest.RENEWAL_REQUEST)) {
+
+ String uid = r.getExtDataInString(IRequest.HTTP_PARAMS, "uid");
+
+ if (uid == null) {
+ log(ILogger.LL_INFO, "did not find UID parameter in request " + r.getRequestId());
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+
+ String userdn = null;
+
+ try {
+ String[] attrs = { (String) mParamValue.get(PROP_ATTR) };
+ LDAPSearchResults searchResult =
+ mCheckAttrLdapConnection.search((String) mParamValue.get(PROP_LDAP_BASE),
+ LDAPv2.SCOPE_SUB, "(uid=" + uid + ")", attrs, false);
+
+ if (!searchResult.hasMoreElements()) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_PIN_FOUND", uid));
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+
+ LDAPEntry entry = (LDAPEntry) searchResult.nextElement();
+
+ userdn = entry.getDN();
+
+ LDAPAttribute attr = entry.getAttribute((String) mParamValue.get(PROP_ATTR));
+
+ /* if attribute not present, reject the request */
+ if (attr == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_PIN_FOUND", userdn));
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+ String acceptedValue = ((String) mParamValue.get(PROP_VALUE));
+
+ if (!acceptedValue.equals("")) {
+ int matches = 0;
+
+ String[] values = attr.getStringValueArray();
+
+ for (int i = 0; i < values.length; i++) {
+ if (values[i].equals(acceptedValue)) {
+ matches++;
+ }
+ }
+ if (matches == 0) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CMS_AUTH_NO_PIN_FOUND", userdn));
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ CMS.debug("AttributePresentConstraints: Attribute is present for user: \"" + userdn + "\"");
+
+ } catch (LDAPException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_PIN_UNAUTHORIZED"));
+ setError(r, CMS.getUserMessage("CMS_POLICY_PIN_UNAUTHORIZED"), "");
+ return PolicyResult.REJECTED;
+ }
+
+ }
+ return res;
+ }
+
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ Enumeration e = mParamNames.elements();
+
+ while (e.hasMoreElements()) {
+ try {
+ String paramName = (String) e.nextElement();
+ String paramValue = mParamValue.get(paramName).toString();
+ String temp = paramName + "=" + paramValue;
+
+ params.addElement(temp);
+ } catch (Exception ex) {
+ }
+ }
+
+ return params;
+ }
+
+ public Vector getDefaultParams() {
+ Vector params = new Vector();
+
+ Enumeration e = mParamNames.elements();
+
+ while (e.hasMoreElements()) {
+ try {
+ String paramName = (String) e.nextElement();
+ String paramValue = mParamDefault.get(paramName).toString();
+ String temp = paramName + "=" + paramValue;
+
+ params.addElement(temp);
+ } catch (Exception ex) {
+ }
+ }
+
+ return params;
+
+ /*
+ params.addElement("ldap.ldapconn.host=localhost");
+ params.addElement("ldap.ldapconn.port=389");
+ params.addElement("ldap.ldapconn.secureConn=false");
+ params.addElement("ldap.ldapconn.version=3");
+ params.addElement("ldap.ldapauth.bindDN=CN=Directory Manager");
+ params.addElement("ldap.ldapauth.bindPWPrompt=");
+ params.addElement("ldap.ldapauth.clientCertNickname=");
+ params.addElement("ldap.ldapauth.authtype=BasicAuth");
+ params.addElement("ldap.basedn=");
+ params.addElement("ldap.minConns=1");
+ params.addElement("ldap.maxConns=5");
+ */
+ }
+
+ protected void log(int level, String msg) {
+ if (mLogger == null) return;
+
+ mLogger.log(ILogger.EV_SYSTEM, null, ILogger.S_OTHER,
+ level, "AttributePresentConstraints: " + msg);
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java
new file mode 100644
index 000000000..4623826f0
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/DSAKeyConstraints.java
@@ -0,0 +1,249 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.CMS;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.provider.DSAPublicKey;
+import java.security.interfaces.DSAParams;
+import java.math.BigInteger;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * DSAKeyConstraints policy enforces min and max size of the key.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class DSAKeyConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private int mMinSize;
+ private int mMaxSize;
+
+ private final static int INCREMENT = 64;
+ private final static int DEF_MIN_SIZE = 512;
+ private final static int DEF_MAX_SIZE = 1024;
+
+ private final static String DSA = "DSA";
+ private final static String PROP_MIN_SIZE = "minSize";
+ private final static String PROP_MAX_SIZE = "maxSize";
+
+ private final static Vector defConfParams = new Vector();
+
+ private IConfigStore mConfig = null;
+
+ static {
+ defConfParams.addElement(PROP_MIN_SIZE + "=" + DEF_MIN_SIZE);
+ defConfParams.addElement(PROP_MAX_SIZE + "=" + DEF_MAX_SIZE);
+ }
+
+ public DSAKeyConstraints() {
+ NAME = "DSAKeyConstraints";
+ DESC = "Enforces DSA Key Constraints.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MIN_SIZE + ";number;Minimum key size",
+ PROP_MAX_SIZE + ";number;Maximum key size",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-dsakeyconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Rejects request if DSA key size is out of range"
+ };
+
+ return params;
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form
+ * ra.Policy.rule.<ruleName>.implName=DSAKeyConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.minSize=512
+ * ra.Policy.rule.<ruleName>.maxSize=1024
+ * ra.Policy.rule.<ruleName>.predicate= ou == engineering AND o == netscape.com
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ // Get Min and Max sizes
+ mConfig = config;
+
+ try {
+ mMinSize = config.getInteger(PROP_MIN_SIZE, DEF_MIN_SIZE);
+ mMaxSize = config.getInteger(PROP_MAX_SIZE, DEF_MAX_SIZE);
+
+ if (mMaxSize > DEF_MAX_SIZE) {
+ String msg = "cannot be more than " + DEF_MAX_SIZE;
+
+ log(ILogger.LL_FAILURE, PROP_MAX_SIZE + " " + msg);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_MAX_SIZE, msg));
+ }
+ if (mMinSize < DEF_MIN_SIZE) {
+ String msg = "cannot be less than " + DEF_MIN_SIZE;
+
+ log(ILogger.LL_FAILURE, PROP_MIN_SIZE + " " + msg);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_MIN_SIZE, msg));
+ }
+ if (mMaxSize % INCREMENT != 0) {
+ String msg = "must be in increments of " + INCREMENT;
+
+ log(ILogger.LL_FAILURE, PROP_MAX_SIZE + " " + msg);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_MIN_SIZE, msg));
+ }
+ if (mMaxSize % INCREMENT != 0) {
+ String msg = "must be in increments of " + INCREMENT;
+
+ log(ILogger.LL_FAILURE, PROP_MIN_SIZE + " " + msg);
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_MIN_SIZE, msg));
+ }
+
+ config.putInteger(PROP_MIN_SIZE, mMinSize);
+ config.putInteger(PROP_MAX_SIZE, mMaxSize);
+
+ } catch (Exception e) {
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", getInstanceName(), e.toString()));
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificate info from the request
+ X509CertInfo ci[] =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // There should be a certificate info set.
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the key size(s) are within the limit.
+ for (int i = 0; i < ci.length; i++) {
+ CertificateX509Key certKey = (CertificateX509Key)
+ ci[i].get(X509CertInfo.KEY);
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ String alg = key.getAlgorithmId().toString();
+
+ if (!alg.equalsIgnoreCase(DSA))
+ continue;
+
+ // Check DSAKey parameters.
+ // size refers to the p parameter.
+ DSAPublicKey dsaKey = new DSAPublicKey(key.getEncoded());
+ DSAParams keyParams = dsaKey.getParams();
+
+ if (keyParams == null) {
+ // key parameters could not be parsed.
+ Object[] params = new Object[] {
+ getInstanceName(), String.valueOf(i + 1) };
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_KEY_PARAMS", getInstanceName(), String.valueOf(i + 1)), "");
+ return PolicyResult.REJECTED;
+ }
+ BigInteger p = keyParams.getP();
+ int len = p.bitLength();
+
+ if (len < mMinSize || len > mMaxSize ||
+ (len % INCREMENT) != 0) {
+ String[] parms = new String[] {
+ getInstanceName(),
+ String.valueOf(len),
+ String.valueOf(mMinSize),
+ String.valueOf(mMaxSize),
+ String.valueOf(INCREMENT) };
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_KEY_SIZE_VIOLATION_1", parms), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String[] params = { getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ try {
+ confParams.addElement(PROP_MIN_SIZE + "=" + mConfig.getInteger(PROP_MIN_SIZE, DEF_MIN_SIZE));
+ confParams.addElement(PROP_MAX_SIZE + "=" + mConfig.getInteger(PROP_MAX_SIZE, DEF_MAX_SIZE));
+ } catch (EBaseException e) {;
+ }
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java b/pki/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java
new file mode 100644
index 000000000..8fca9a2fa
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/DefaultRevocation.java
@@ -0,0 +1,105 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This is the default revocation policy. Currently this does
+ * nothing. We can later add checks like whether or not to
+ * revoke expired certs ..etc here.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class DefaultRevocation extends APolicyRule
+ implements IRevocationPolicy, IExtendedPluginInfo {
+ public DefaultRevocation() {
+ NAME = "DefaultRevocation";
+ DESC = "Default Revocation Policy";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=DefaultRevocation
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate= ou == engineering AND o == netscape.com
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return null;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return null;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-defaultrevocation"
+ };
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java
new file mode 100644
index 000000000..5746a3b21
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/IssuerConstraints.java
@@ -0,0 +1,207 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * IssuerConstraints is a rule for restricting the issuers of the
+ * certificates used for certificate-based enrollments.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$ $Date$
+ */
+public class IssuerConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private final static String PROP_ISSUER_DN = "issuerDN";
+ private static final String CLIENT_ISSUER = "clientIssuer";
+ private X500Name mIssuerDN = null;
+ private String mIssuerDNString;
+
+ /**
+ * checks the issuer of the ssl client-auth cert. Only one issuer
+ * is allowed for now
+ */
+ public IssuerConstraints() {
+ NAME = "IssuerConstraints";
+ DESC = "Checks to see if the Issuer is one allowed";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_ISSUER_DN + ";string;Subject DN of the Issuer. The IssuerDN of the authenticating cert must match what's specified here",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-issuerconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Rejects the request if the issuer in the certificate is" +
+ "not of the one specified"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ try {
+ mIssuerDNString = config.getString(PROP_ISSUER_DN, null);
+ if ((mIssuerDNString != null) &&
+ !mIssuerDNString.equals("")) {
+ mIssuerDN = new X500Name(mIssuerDNString);
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ NAME + CMS.getLogMessage("CA_GET_ISSUER_NAME_FAILED"));
+
+ String[] params = {getInstanceName(), e.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", params));
+ }
+ CMS.debug(
+ NAME + ": init() done");
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ if (mIssuerDN == null)
+ return result;
+
+ try {
+ String clientIssuerDN = req.getExtDataInString(CLIENT_ISSUER);
+
+ if (clientIssuerDN != null) {
+ X500Name ci_name = new X500Name(clientIssuerDN);
+
+ if (!ci_name.equals(mIssuerDN)) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_INVALID_ISSUER",
+ getInstanceName()), "");
+ result = PolicyResult.REJECTED;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_GET_ISSUER_NAME_FAILED"));
+ CMS.debug(
+ NAME + ": apply() - issuerDN mismatch: client issuerDN = " + clientIssuerDN + "; expected issuerDN = " + mIssuerDNString);
+ }
+ } else {
+
+ // Get the certificate info from the request
+ X509CertInfo certInfo[] =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (certInfo == null) {
+ log(ILogger.LL_FAILURE,
+ NAME + ": apply() - missing certInfo");
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < certInfo.length; i++) {
+ String oldIssuer = (String)
+ certInfo[i].get(X509CertInfo.ISSUER).toString();
+
+ if (oldIssuer == null) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CLIENT_ISSUER_NOT_FOUND",
+ getInstanceName()), "");
+ result = PolicyResult.REJECTED;
+ log(ILogger.LL_FAILURE,
+ NAME + ": apply() - client issuerDN not found");
+ }
+ X500Name oi_name = new X500Name(oldIssuer);
+
+ if (!oi_name.equals(mIssuerDN)) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_INVALID_ISSUER",
+ getInstanceName()), "");
+ result = PolicyResult.REJECTED;
+ log(ILogger.LL_FAILURE,
+ NAME + ": apply() - cert issuerDN mismatch: client issuerDN = " + oldIssuer + "; expected issuerDN = " + mIssuerDNString);
+ }
+ }
+ }
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+
+ if (result.equals(PolicyResult.ACCEPTED)) {
+ log(ILogger.LL_INFO,
+ NAME + ": apply() - accepted");
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_ISSUER_DN + "=" +
+ mIssuerDNString);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_ISSUER_DN + "=");
+ return defParams;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java
new file mode 100644
index 000000000..181752b01
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/KeyAlgorithmConstraints.java
@@ -0,0 +1,221 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * KeyAlgorithmConstraints enforces a constraint that the RA or a CA
+ * honor only the keys generated using one of the permitted algorithms
+ * such as RSA, DSA or DH.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class KeyAlgorithmConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private Vector mAlgorithms;
+ private final static String DEF_KEY_ALGORITHM = "RSA,DSA";
+ private final static String PROP_ALGORITHMS = "algorithms";
+ private final static String[] supportedAlgorithms =
+ {"RSA", "DSA", "DH" };
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ defConfParams.addElement(PROP_ALGORITHMS + "=" +
+ DEF_KEY_ALGORITHM);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String params[] = {
+ "algorithms;choice(RSA\\,DSA,RSA,DSA);Certificate's key can be one of these algorithms",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-keyalgorithmconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Rejects the request if the key in the certificate is " +
+ "not of the type specified"
+ };
+
+ return params;
+ }
+
+ public KeyAlgorithmConstraints() {
+ NAME = "KeyAlgorithmConstraints";
+ DESC = "Enforces Key Algorithm Constraints.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form
+ * ra.Policy.rule.<ruleName>.implName=KeyAlgorithmConstraints
+ * ra.Policy.rule.<ruleName>.algorithms=RSA,DSA
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ mAlgorithms = new Vector();
+
+ if (config == null || config.size() == 0) {
+ mAlgorithms.addElement(DEF_KEY_ALGORITHM);
+ return;
+ }
+
+ // Get Algorithm names
+ String algNames = null;
+
+ try {
+ algNames = config.getString(PROP_ALGORITHMS, null);
+ } catch (Exception e) {
+ String[] params = {getInstanceName(), e.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", params));
+ }
+
+ if (algNames == null) {
+ mAlgorithms.addElement(DEF_KEY_ALGORITHM);
+ return;
+ }
+ StringTokenizer tok = new StringTokenizer(algNames, ",");
+
+ while (tok.hasMoreTokens()) {
+ String alg = tok.nextToken().trim().toUpperCase();
+
+ if (alg.length() == 0)
+ continue;
+ mAlgorithms.addElement(alg);
+ }
+
+ // Check if configured algorithms are supported.
+ for (Enumeration e = mAlgorithms.elements();
+ e.hasMoreElements();) {
+ int i;
+ String configuredAlg = (String) e.nextElement();
+
+ // See if it is a supported algorithm.
+ for (i = 0; i < supportedAlgorithms.length; i++) {
+ if (configuredAlg.equals(supportedAlgorithms[i]))
+ break;
+ }
+
+ // Did we not find it?
+ if (i == supportedAlgorithms.length)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_UNSUPPORTED_KEY_ALG",
+ getInstanceName(), configuredAlg));
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificate info from the request
+ // X509CertInfo certInfo[] = (X509CertInfo[])
+ // req.get(IRequest.CERT_INFO);
+ X509CertInfo certInfo[] = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // We need to have a certificate info set
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the key algorithm is supported.
+ for (int i = 0; i < certInfo.length; i++) {
+ CertificateX509Key certKey = (CertificateX509Key)
+ certInfo[i].get(X509CertInfo.KEY);
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ String alg = key.getAlgorithmId().getName().toUpperCase();
+
+ if (!mAlgorithms.contains(alg)) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_KEY_ALG_VIOLATION",
+ getInstanceName(), alg), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration e = mAlgorithms.elements(); e.hasMoreElements();) {
+ sb.append((String) e.nextElement());
+ sb.append(",");
+ }
+ if (sb.length() > 0)
+ sb.setLength(sb.length() - 1);
+ v.addElement(PROP_ALGORITHMS + "=" + sb.toString());
+ return v;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java b/pki/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java
new file mode 100644
index 000000000..d88bb3c02
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/ManualAuthentication.java
@@ -0,0 +1,103 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * ManualAuthentication is an enrollment policy that queues
+ * all requests for issuing agent's approval if no authentication
+ * is present. The policy rejects a request if any of the auth tokens
+ * indicates authentication failure.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class ManualAuthentication extends APolicyRule
+ implements IEnrollmentPolicy {
+ public ManualAuthentication() {
+ NAME = "ManualAuthentication";
+ DESC = "Manual Authentication Policy";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ManualAuthentication
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate= ou == engineering AND o == netscape.com
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ IAuthToken authToken = req.getExtDataInAuthToken(IRequest.AUTH_TOKEN);
+
+ if (authToken == null)
+ return deferred(req);
+
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return null;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return null;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java
new file mode 100644
index 000000000..b30e27901
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/RSAKeyConstraints.java
@@ -0,0 +1,274 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.security.provider.RSAPublicKey;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * RSAKeyConstraints policy enforces min and max size of the key.
+ * Optionally checks the exponents.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RSAKeyConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private Vector mExponents;
+ private int mMinSize;
+ private int mMaxSize;
+
+ private final static int DEF_MIN_SIZE = 512;
+ private final static int DEF_MAX_SIZE = 2048;
+ private final static String PROP_MIN_SIZE = "minSize";
+ private final static String PROP_MAX_SIZE = "maxSize";
+ private final static String PROP_EXPONENTS = "exponents";
+ private final static String RSA = "RSA";
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ defConfParams.addElement(PROP_MIN_SIZE + "=" + DEF_MIN_SIZE);
+ defConfParams.addElement(PROP_MAX_SIZE + "=" + DEF_MAX_SIZE);
+ defConfParams.addElement(PROP_EXPONENTS + "=" + " ");
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MIN_SIZE + ";number;Minimum size of user's RSA key (bits)",
+ PROP_MAX_SIZE + ";number;Maximum size of user's RSA key (bits)",
+ PROP_EXPONENTS + ";string;Comma-separated list of permissible exponents",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-rsakeyconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Reject request if RSA key length is not within the " +
+ "specified constraints"
+ };
+
+ return params;
+ }
+
+ public RSAKeyConstraints() {
+ NAME = "RSAKeyConstraints";
+ DESC = "Enforces RSA Key Constraints.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=RSAKeyConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.minSize=512
+ * ra.Policy.rule.<ruleName>.maxSize=2048
+ * ra.Policy.rule.<ruleName>.predicate=ou==Marketing
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+ if (config == null || config.size() == 0)
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_MISSING_POLICY_CONFIG",
+ getInstanceName()));
+ String exponents = null;
+
+ // Get Min and Max sizes
+ mMinSize = config.getInteger(PROP_MIN_SIZE, DEF_MIN_SIZE);
+ mMaxSize = config.getInteger(PROP_MAX_SIZE, DEF_MAX_SIZE);
+
+ if (mMinSize <= 0)
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_MUST_BE_POSITIVE_NUMBER", PROP_MIN_SIZE));
+ if (mMaxSize <= 0)
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_MUST_BE_POSITIVE_NUMBER", PROP_MAX_SIZE));
+
+ if (mMinSize > mMaxSize)
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_A_GREATER_THAN_EQUAL_B", PROP_MIN_SIZE, PROP_MAX_SIZE));
+
+ mExponents = new Vector();
+
+ // Get exponents
+ exponents = config.getString(PROP_EXPONENTS, null);
+
+ if (exponents != null) {
+ StringTokenizer tok = new StringTokenizer(exponents, ",");
+
+ try {
+ while (tok.hasMoreTokens()) {
+ String exp = tok.nextToken().trim();
+
+ mExponents.addElement(new BigInt(Integer.parseInt(exp)));
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String[] params = {getInstanceName(), exponents,
+ PROP_EXPONENTS};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_CONFIG_PARAM", params));
+ }
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificate info from the request
+ X509CertInfo certInfo[] =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // There should be a certificate info set.
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the key size(s) are within the limit.
+ for (int i = 0; i < certInfo.length; i++) {
+ CertificateX509Key certKey = (CertificateX509Key)
+ certInfo[i].get(X509CertInfo.KEY);
+ X509Key key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ String alg = key.getAlgorithmId().toString();
+
+ if (!alg.equalsIgnoreCase(RSA))
+ continue;
+ X509Key newkey = null;
+
+ try {
+ newkey = new X509Key(AlgorithmId.get("RSA"),
+ key.getKey());
+ } catch (Exception e) {
+ CMS.debug( "RSAKeyConstraints::apply() - "
+ + "Exception="+e.toString() );
+ setError( req,
+ CMS.getUserMessage( "CMS_POLICY_KEY_SIZE_VIOLATION",
+ getInstanceName() ),
+ "" );
+ return PolicyResult.REJECTED;
+ }
+ RSAPublicKey rsaKey = new RSAPublicKey(newkey.getEncoded());
+ int keySize = rsaKey.getKeySize();
+
+ if (keySize < mMinSize || keySize > mMaxSize) {
+ String[] params = {getInstanceName(),
+ String.valueOf(keySize),
+ String.valueOf(mMinSize),
+ String.valueOf(mMaxSize)};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_KEY_SIZE_VIOLATION",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+
+ // If the exponents are configured, see if the key's
+ // exponent is a configured one.
+ if (mExponents.size() > 0) {
+ BigInt exp = rsaKey.getPublicExponent();
+
+ if (!mExponents.contains(exp)) {
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration e = mExponents.elements();
+ e.hasMoreElements();) {
+ BigInt bi = (BigInt) e.nextElement();
+
+ sb.append(bi.toBigInteger().toString());
+ sb.append(" ");
+ }
+ String[] params = {getInstanceName(),
+ exp.toBigInteger().toString(), new String(sb)};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_EXPONENT_VIOLATION", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_MIN_SIZE + "=" + mMinSize);
+ confParams.addElement(PROP_MAX_SIZE + "=" + mMaxSize);
+ StringBuffer sb = new StringBuffer();
+
+ for (Enumeration e = mExponents.elements(); e.hasMoreElements();) {
+ sb.append(((BigInt) e.nextElement()).toInt());
+ sb.append(",");
+ }
+ if (sb.length() > 0)
+ sb.setLength(sb.length() - 1);
+ confParams.addElement(PROP_EXPONENTS + "=" + sb.toString());
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java
new file mode 100644
index 000000000..5cadafa17
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalConstraints.java
@@ -0,0 +1,235 @@
+// --- 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.policy.constraints;
+
+
+import java.io.*;
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Whether to allow renewal of an expired cert.
+ * @version $Revision$, $Date$
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RenewalConstraints extends APolicyRule
+ implements IRenewalPolicy, IExtendedPluginInfo {
+
+ private static final String PROP_ALLOW_EXPIRED_CERTS = "allowExpiredCerts";
+ private static final String PROP_RENEWAL_NOT_AFTER = "renewalNotAfter";
+
+ private boolean mAllowExpiredCerts = true;
+ private long mRenewalNotAfter = 0;
+
+ public final static int DEF_RENEWAL_NOT_AFTER = 30;
+ public final static long DAYS_TO_MS_FACTOR = 24L * 3600 * 1000;
+
+ private final static Vector defConfParams = new Vector();
+ static {
+ defConfParams.addElement(PROP_ALLOW_EXPIRED_CERTS + "=" + true);
+ defConfParams.addElement(PROP_RENEWAL_NOT_AFTER + "=" +
+ DEF_RENEWAL_NOT_AFTER);
+ }
+
+ public RenewalConstraints() {
+ NAME = "RenewalConstraints";
+ DESC = "Whether to allow renewal of expired certs.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_ALLOW_EXPIRED_CERTS + ";boolean;Allow a user to renew an already-expired certificate",
+ PROP_RENEWAL_NOT_AFTER + ";number;Number of days since certificate expiry after which renewal request would be rejected",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-renewalconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Permit administrator to decide policy on whether to " +
+ "permit renewals for already-expired certificates"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ValidityConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.allowExpiredCerts=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ // Get min and max validity in days and configure them.
+ try {
+ mAllowExpiredCerts =
+ config.getBoolean(PROP_ALLOW_EXPIRED_CERTS, true);
+ String val = config.getString(PROP_RENEWAL_NOT_AFTER, null);
+
+ if (val == null)
+ mRenewalNotAfter = DEF_RENEWAL_NOT_AFTER * DAYS_TO_MS_FACTOR;
+ else {
+ mRenewalNotAfter = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+ }
+
+ } catch (EBaseException e) {
+ // never happen.
+ }
+
+ CMS.debug("RenewalConstraints: allow expired certs " + mAllowExpiredCerts);
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificates being renwed.
+ X509CertImpl[] oldCerts =
+ req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (oldCerts == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_OLD_CERT",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ if (mAllowExpiredCerts) {
+ CMS.debug("checking validity of each cert");
+ // check if each cert to be renewed is expired for more than // allowed days.
+ for (int i = 0; i < oldCerts.length; i++) {
+ X509CertInfo oldCertInfo = (X509CertInfo)
+ oldCerts[i].get(X509CertImpl.NAME + "." +
+ X509CertImpl.INFO);
+ CertificateValidity oldValidity = (CertificateValidity)
+ oldCertInfo.get(X509CertInfo.VALIDITY);
+ Date notAfter = (Date)
+ oldValidity.get(CertificateValidity.NOT_AFTER);
+
+ // Is the Certificate eligible for renewal ?
+
+ Date now = CMS.getCurrentDate();
+
+ Date renewedNotAfter = new Date(notAfter.getTime() +
+ mRenewalNotAfter);
+
+ CMS.debug("RenewalConstraints: cert " + i + " renewedNotAfter " + renewedNotAfter + " now=" + now);
+
+ if (renewedNotAfter.before(now)) {
+ CMS.debug(
+ "One or more certificates is expired for more than " + (mRenewalNotAfter / DAYS_TO_MS_FACTOR) + " days");
+ String params[] = { getInstanceName(), Long.toString(mRenewalNotAfter / DAYS_TO_MS_FACTOR) };
+
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CANNOT_RENEW_EXPIRED_CERTS_AFTER_ALLOWED_PERIOD",
+ params), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ CMS.debug("RenewalConstraints: checking validity of each cert");
+ // check if each cert to be renewed is expired.
+ for (int i = 0; i < oldCerts.length; i++) {
+ X509CertInfo oldCertInfo = (X509CertInfo)
+ oldCerts[i].get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ CertificateValidity oldValidity = (CertificateValidity)
+ oldCertInfo.get(X509CertInfo.VALIDITY);
+ Date notAfter = (Date)
+ oldValidity.get(CertificateValidity.NOT_AFTER);
+
+ // Is the Certificate still valid?
+ Date now = CMS.getCurrentDate();
+
+ CMS.debug("RenewalConstraints: cert " + i + " notAfter " + notAfter + " now=" + now);
+ if (notAfter.before(now)) {
+ CMS.debug(
+ "RenewalConstraints: One or more certificates is expired.");
+ String params[] = { getInstanceName() };
+
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CANNOT_RENEW_EXPIRED_CERTS",
+ params), "");
+ result = PolicyResult.REJECTED;
+ break;
+ }
+ }
+
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(
+ PROP_ALLOW_EXPIRED_CERTS + "=" + mAllowExpiredCerts);
+ confParams.addElement(PROP_RENEWAL_NOT_AFTER + "=" +
+ mRenewalNotAfter / DAYS_TO_MS_FACTOR);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java
new file mode 100644
index 000000000..60f294e36
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/RenewalValidityConstraints.java
@@ -0,0 +1,342 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * RenewalValidityConstraints is a default rule for Certificate
+ * Renewal. This policy enforces the no of days before which a
+ * currently active certificate can be renewed and sets new validity
+ * period for the renewed certificate starting from the the ending
+ * period in the old certificate.
+ *
+ * The main parameters are:
+ *
+ * The renewal leadtime in days: - i.e how many days before the
+ * expiry of the current certificate can one request the renewal.
+ * min and max validity duration.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RenewalValidityConstraints extends APolicyRule
+ implements IRenewalPolicy, IExtendedPluginInfo {
+ private long mMinValidity;
+ private long mMaxValidity;
+ private long mRenewalInterval;
+
+ private final static String PROP_MIN_VALIDITY = "minValidity";
+ private final static String PROP_MAX_VALIDITY = "maxValidity";
+ private final static String PROP_RENEWAL_INTERVAL = "renewalInterval";
+ public final static int DEF_MIN_VALIDITY = 180;
+ public final static int DEF_MAX_VALIDITY = 730;
+ public final static long DEF_RENEWAL_INTERVAL = 15;
+ public final static long DAYS_TO_MS_FACTOR = 24L * 3600 * 1000;
+ public static final String CERT_HEADER = "-----BEGIN CERTIFICATE-----\n";
+ public static final String CERT_TRAILER = "-----END CERTIFICATE-----\n";
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ defConfParams.addElement(PROP_MIN_VALIDITY + "=" +
+ DEF_MIN_VALIDITY);
+ defConfParams.addElement(PROP_MAX_VALIDITY + "=" +
+ DEF_MAX_VALIDITY);
+ defConfParams.addElement(PROP_RENEWAL_INTERVAL + "=" +
+ DEF_RENEWAL_INTERVAL);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MIN_VALIDITY + ";number;Specifies the minimum validity period, in days, for renewed certificates.",
+ PROP_MAX_VALIDITY + ";number;Specifies the maximum validity period, in days, for renewed certificates.",
+ PROP_RENEWAL_INTERVAL + ";number;Specifies how many days before its expiration that a certificate can be renewed.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-renewalvalidityconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Reject renewal request if the certificate is too far " +
+ "before it's expiry date"
+ };
+
+ return params;
+
+ }
+
+ public RenewalValidityConstraints() {
+ NAME = "RenewalValidityConstraints";
+ DESC = "Enforces minimum and maximum validity and renewal interval for certificate renewal.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ValidityConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.minValidity=30
+ * ra.Policy.rule.<ruleName>.maxValidity=180
+ * ra.Policy.rule.<ruleName>.renewalInterval=15
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ // Get min and max validity in days and onfigure them.
+ try {
+ String val = config.getString(PROP_MIN_VALIDITY, null);
+
+ if (val == null)
+ mMinValidity = DEF_MIN_VALIDITY * DAYS_TO_MS_FACTOR;
+ else
+ mMinValidity = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_MAX_VALIDITY, null);
+ if (val == null)
+ mMaxValidity = DEF_MAX_VALIDITY * DAYS_TO_MS_FACTOR;
+ else {
+ mMaxValidity = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+ }
+ val = config.getString(PROP_RENEWAL_INTERVAL, null);
+ if (val == null)
+ mRenewalInterval = DEF_RENEWAL_INTERVAL * DAYS_TO_MS_FACTOR;
+ else {
+ mRenewalInterval = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+ }
+
+ // minValidity can't be bigger than maxValidity.
+ if (mMinValidity > mMaxValidity) {
+ String params[] = {getInstanceName(),
+ String.valueOf(mMinValidity / DAYS_TO_MS_FACTOR),
+ String.valueOf(mMaxValidity / DAYS_TO_MS_FACTOR) };
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_RENEWAL_MIN_MAX", params));
+ }
+
+ // Renewal interval can't be more than maxValidity.
+ if (mRenewalInterval > mMaxValidity) {
+ String params[] = {getInstanceName(),
+ String.valueOf(mRenewalInterval / DAYS_TO_MS_FACTOR),
+ String.valueOf(mMaxValidity / DAYS_TO_MS_FACTOR) };
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_RENEWAL_INTERVAL", params));
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String[] params = {getInstanceName(), e.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", params));
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ if (agentApproved(req))
+ return result;
+
+ try {
+ // Get the certificate info from the request
+ X509CertInfo certInfo[] =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // Get the certificates being renwed.
+ X509CertImpl currentCerts[] =
+ req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ // Both certificate info and current certs should be set
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+ if (currentCerts == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_OLD_CERT",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+ if (certInfo.length != currentCerts.length) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_MISMATCHED_CERTINFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the renewal interval is okay and then
+ // set the validity.
+ for (int i = 0; i < certInfo.length; i++) {
+ X509CertInfo oldCertInfo = (X509CertInfo)
+ currentCerts[i].get(X509CertImpl.NAME +
+ "." + X509CertImpl.INFO);
+ CertificateValidity oldValidity = (CertificateValidity)
+ oldCertInfo.get(X509CertInfo.VALIDITY);
+ Date notAfter = (Date)
+ oldValidity.get(CertificateValidity.NOT_AFTER);
+
+ // Is the Certificate still valid?
+ Date now = CMS.getCurrentDate();
+
+ if (notAfter.after(now)) {
+ // Check if the renewal interval is alright.
+ long interval = notAfter.getTime() - now.getTime();
+
+ if (interval > mRenewalInterval) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_LONG_RENEWAL_LEAD_TIME",
+ getInstanceName(),
+ String.valueOf(mRenewalInterval / DAYS_TO_MS_FACTOR)), "");
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_EXISTING_CERT_DETAILS",
+ getInstanceName(),
+ getCertDetails(req, currentCerts[i])), "");
+
+ result = PolicyResult.REJECTED;
+ setDummyValidity(certInfo[i]);
+ continue;
+ }
+ }
+
+ // Else compute new validity.
+ Date renewedNotBef = notAfter;
+ Date renewedNotAfter = new Date(notAfter.getTime() +
+ mMaxValidity);
+
+ // If the new notAfter is within renewal interval days from
+ // today or already expired, set the notBefore to today.
+ if (renewedNotAfter.before(now) ||
+ (renewedNotAfter.getTime() - now.getTime()) <=
+ mRenewalInterval) {
+ renewedNotBef = now;
+ renewedNotAfter = new Date(now.getTime() +
+ mMaxValidity);
+ }
+ CertificateValidity newValidity =
+ new CertificateValidity(renewedNotBef, renewedNotAfter);
+
+ certInfo[i].set(X509CertInfo.VALIDITY, newValidity);
+ }
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_MIN_VALIDITY + "=" +
+ mMinValidity / DAYS_TO_MS_FACTOR);
+ confParams.addElement(PROP_MAX_VALIDITY + "=" +
+ mMaxValidity / DAYS_TO_MS_FACTOR);
+ confParams.addElement(PROP_RENEWAL_INTERVAL + "=" +
+ mRenewalInterval / DAYS_TO_MS_FACTOR);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+
+ // Set dummy validity field so the request will serialize properly
+ private void setDummyValidity(X509CertInfo certInfo) {
+ try {
+ certInfo.set(X509CertInfo.VALIDITY,
+ new CertificateValidity(CMS.getCurrentDate(), new Date()));
+ } catch (Exception e) {
+ }
+ }
+
+ private String getCertDetails(IRequest req, X509CertImpl cert) {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("\n");
+ sb.append("Serial No: " + cert.getSerialNumber().toString(16));
+ sb.append("\n");
+ sb.append("Validity: " + cert.getNotBefore().toString() +
+ " - " + cert.getNotAfter().toString());
+ sb.append("\n");
+ String certType = req.getExtDataInString(IRequest.CERT_TYPE);
+
+ if (certType == null)
+ certType = IRequest.SERVER_CERT;
+ if (certType.equals(IRequest.CLIENT_CERT)) {
+
+ /*** Take this our - URL formulation hard to do here.
+ sb.append("Use the following url with your CA/RA gateway spec to download the certificate.");
+ sb.append("\n");
+ sb.append("/query/certImport?op=displayByserial&serialNumber=");
+ sb.append(cert.getSerialNumber().toString(16));
+ ***/
+ sb.append("\n");
+ } else {
+ sb.append("Certificate Content is as follows:");
+ sb.append("\n");
+ try {
+ byte[] ba = cert.getEncoded();
+ String encodedCert = com.netscape.osutil.OSUtil.BtoA(ba);
+
+ sb.append(CERT_HEADER + encodedCert + CERT_TRAILER);
+ } catch (Exception e) {
+ //throw new AssertionException(e.toString());
+ }
+ }
+ return sb.toString();
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java
new file mode 100644
index 000000000..1afb9cbba
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/RevocationConstraints.java
@@ -0,0 +1,208 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Whether to allow revocation of an expired cert.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RevocationConstraints extends APolicyRule
+ implements IRevocationPolicy, IExtendedPluginInfo {
+ private static final String PROP_ALLOW_EXPIRED_CERTS = "allowExpiredCerts";
+ private static final String PROP_ALLOW_ON_HOLD = "allowOnHold";
+
+ private boolean mAllowExpiredCerts = true;
+ private boolean mAllowOnHold = true;
+
+ private final static Vector defConfParams = new Vector();
+ static {
+ defConfParams.addElement(PROP_ALLOW_EXPIRED_CERTS + "=" + true);
+ defConfParams.addElement(PROP_ALLOW_ON_HOLD + "=" + true);
+ }
+
+ public RevocationConstraints() {
+ NAME = "RevocationConstraints";
+ DESC = "Whether to allow revocation of expired certs and on-hold.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_ALLOW_EXPIRED_CERTS + ";boolean;Allow a user to revoke an already-expired certificate",
+ PROP_ALLOW_ON_HOLD + ";boolean;Allow a user to set reason to On-Hold",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-revocationconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Allow administrator to decide policy on whether to allow " +
+ "recovation of expired certificates" +
+ "and set reason to On-Hold"
+
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ValidityConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.allowExpiredCerts=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+ // Get min and max validity in days and onfigure them.
+ try {
+ mAllowExpiredCerts =
+ config.getBoolean(PROP_ALLOW_EXPIRED_CERTS, true);
+ mAllowOnHold =
+ config.getBoolean(PROP_ALLOW_ON_HOLD, true);
+ } catch (EBaseException e) {
+ // never happen.
+ }
+
+ CMS.debug("RevocationConstraints: allow expired certs " + mAllowExpiredCerts);
+ CMS.debug("RevocationConstraints: allow on hold " + mAllowOnHold);
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ CMS.debug("RevocationConstraints: apply begins");
+ if (req.getExtDataInInteger(IRequest.REVOKED_REASON) == null) {
+ CMS.debug("RevocationConstraints: apply: no revocationReason found in request");
+ return PolicyResult.REJECTED;
+ }
+ RevocationReason rr = RevocationReason.fromInt(
+ req.getExtDataInInteger(IRequest.REVOKED_REASON).intValue());
+
+ if (!mAllowOnHold && (rr != null)) {
+ int reason = rr.toInt();
+
+ if (reason == RevocationReason.CERTIFICATE_HOLD.toInt()) {
+ String params[] = { getInstanceName() };
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_ON_HOLD_ALLOWED", params), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ if (mAllowExpiredCerts)
+ // nothing to check.
+ return PolicyResult.ACCEPTED;
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificates being renwed.
+ X509CertImpl[] oldCerts =
+ req.getExtDataInCertArray(IRequest.OLD_CERTS);
+
+ if (oldCerts == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_OLD_CERT"),
+ getInstanceName());
+ return PolicyResult.REJECTED;
+ }
+
+ // check if each cert to be renewed is expired.
+ for (int i = 0; i < oldCerts.length; i++) {
+ X509CertInfo oldCertInfo = (X509CertInfo)
+ oldCerts[i].get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ CertificateValidity oldValidity = (CertificateValidity)
+ oldCertInfo.get(X509CertInfo.VALIDITY);
+ Date notAfter = (Date)
+ oldValidity.get(CertificateValidity.NOT_AFTER);
+
+ // Is the Certificate still valid?
+ Date now = CMS.getCurrentDate();
+
+ if (notAfter.before(now)) {
+ String params[] = { getInstanceName() };
+
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CANNOT_REVOKE_EXPIRED_CERTS",
+ params), "");
+ result = PolicyResult.REJECTED;
+ break;
+ }
+ }
+
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(
+ PROP_ALLOW_EXPIRED_CERTS + "=" + mAllowExpiredCerts);
+ confParams.addElement(
+ PROP_ALLOW_ON_HOLD + "=" + mAllowOnHold);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java
new file mode 100644
index 000000000..be9870935
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/SigningAlgorithmConstraints.java
@@ -0,0 +1,442 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import java.io.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.CMS;
+import netscape.security.x509.*;
+import com.netscape.certsrv.ca.*;
+import netscape.security.extensions.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * SigningAlgorithmConstraints enforces that only a supported
+ * signing algorithm be requested.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SigningAlgorithmConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ private String[] mAllowedAlgs = null; // algs allowed by this policy
+ static String[] mDefaultAllowedAlgs = null; // default algs allowed by this policy based on CA's key
+ private String[] mConfigAlgs = null; // algs listed in config file
+ private boolean winnowedByKey = false;
+ IAuthority mAuthority = null;
+ private final static String PROP_ALGORITHMS = "algorithms";
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ StringBuffer sb = new StringBuffer();
+ sb.append(PROP_ALGORITHMS);
+ sb.append("=");
+ int i = 0;
+ boolean first = true;
+
+ mDefaultAllowedAlgs = new String[AlgorithmId.ALL_SIGNING_ALGORITHMS.length];
+ for (i = 0; i < AlgorithmId.ALL_SIGNING_ALGORITHMS.length; i++) {
+ mDefaultAllowedAlgs[i] = AlgorithmId.ALL_SIGNING_ALGORITHMS[i];
+ if (first == true) {
+ sb.append(AlgorithmId.ALL_SIGNING_ALGORITHMS[i]);
+ first = false;
+ } else {
+ sb.append(",");
+ sb.append(AlgorithmId.ALL_SIGNING_ALGORITHMS[i]);
+ }
+ }
+ defConfParams.addElement(sb.toString());
+ }
+
+ public SigningAlgorithmConstraints() {
+ NAME = "SigningAlgorithmConstraints";
+ DESC = "Enforces Signing Algorithm Constraints.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form
+ * ra.Policy.rule.<ruleName>.implName=SigningAlgorithmConstraints
+ * ra.Policy.rule.<ruleName>.algorithms=SHA-1WithRSA, SHA-1WithDSA
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mAuthority = (IAuthority) ((IPolicyProcessor) owner).getAuthority();
+
+ // Get allowed algorithms from config file
+ if (config != null) {
+ String algNames = null;
+
+ try {
+ algNames = config.getString(PROP_ALGORITHMS, null);
+ } catch (Exception e) {
+ String[] params = {getInstanceName(), e.toString(), PROP_ALGORITHMS};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_PARAM_CONFIG_ERROR", params));
+ }
+
+ if (algNames != null) {
+ // parse alg names into Vector
+ StringTokenizer tok = new StringTokenizer(algNames, ",");
+ Vector algs = new Vector();
+
+ while (tok.hasMoreTokens()) {
+ algs.addElement(tok.nextToken().trim());
+ }
+
+ // convert to array for speedy traversals during apply()
+ int itemCount = algs.size();
+
+ mAllowedAlgs = new String[itemCount];
+ for (int i = 0; i < itemCount; i++) {
+ mAllowedAlgs[i] = (String) algs.elementAt(i);
+ }
+
+ }
+
+ }
+
+ // these are the algorithms from the config file
+ mConfigAlgs = mAllowedAlgs;
+ if (mConfigAlgs == null) {
+ mConfigAlgs = new String[0];
+ }
+
+ if (mAllowedAlgs != null) {
+ // winnow out unknown algorithms
+ winnowAlgs(AlgorithmId.ALL_SIGNING_ALGORITHMS,
+ "CMS_POLICY_UNKNOWN_SIGNING_ALG", true);
+ } else {
+ // if nothing was in the config file, allow all known algs
+ mAllowedAlgs = AlgorithmId.ALL_SIGNING_ALGORITHMS;
+ }
+
+ // winnow out algorithms that don't make sense for the key
+ winnowByKey();
+
+ if (mAllowedAlgs.length == 0) {
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SIGNALG_NOT_MATCH_CAKEY", NAME));
+ }
+
+ }
+
+ /**
+ * winnow out algorithms that don't make sense for the CA's key
+ */
+ private synchronized void winnowByKey() throws EBaseException {
+ // only do this successfully once
+ if (winnowedByKey) {
+ return;
+ }
+
+ // don't do this ever for DRM
+ if (!(mAuthority instanceof ICertAuthority)) {
+ winnowedByKey = true;
+ return;
+ }
+
+ // get list of algorithms allowed for the key
+ String[] allowedByKey =
+ ((ICertAuthority) mAuthority).getCASigningAlgorithms();
+
+ if (allowedByKey != null) {
+ // don't show algorithms that don't match CA's key in UI.
+ mDefaultAllowedAlgs = new String[allowedByKey.length];
+ for (int i = 0; i < allowedByKey.length; i++)
+ mDefaultAllowedAlgs[i] = allowedByKey[i];
+ // winnow out algorithms that don't match CA's signing key
+ winnowAlgs(allowedByKey,
+ "CMS_POLICY_SIGNALG_NOT_MATCH_CAKEY_1", false);
+ winnowedByKey = true;
+ } else {
+ // We don't know the CA's signing algorithms. Maybe we're
+ // an RA that hasn't talked to the CA yet? Try again later.
+ }
+ }
+
+ /**
+ * Winnows out of mAllowedAlgorithms those algorithms that aren't allowed
+ * for some reason.
+ *
+ * @param allowed An array of allowed algorithms. Only algorithms in this
+ * list will survive the winnowing process.
+ * @param reason A string describing the problem with an algorithm
+ * that is not allowed by this list. Must be a predefined string in PolicyResources.
+ */
+ private void winnowAlgs(String[] allowed, String reason, boolean isError)
+ throws EBaseException {
+ int i, j, goodSize;
+
+ // validate the currently-allowed algorithms
+ Vector goodAlgs = new Vector();
+
+ for (i = 0; i < mAllowedAlgs.length; i++) {
+ for (j = 0; j < allowed.length; j++) {
+ if (mAllowedAlgs[i].equals(allowed[j])) {
+ goodAlgs.addElement(mAllowedAlgs[i]);
+ break;
+ }
+ }
+ // if algorithm is not allowed, log a warning
+ if (j == allowed.length) {
+ EPolicyException e = new EPolicyException(CMS.getUserMessage(reason, NAME, mAllowedAlgs[i]));
+
+ if (isError) {
+ log(ILogger.LL_FAILURE, e.toString());
+ throw new EPolicyException(CMS.getUserMessage(reason,
+ NAME, mAllowedAlgs[i]));
+ } else {
+ log(ILogger.LL_WARN, e.toString());
+ }
+ }
+ }
+
+ // convert back into an array
+ goodSize = goodAlgs.size();
+ if (mAllowedAlgs.length != goodSize) {
+ mAllowedAlgs = new String[ goodSize ];
+ for (i = 0; i < goodSize; i++) {
+ mAllowedAlgs[i] = (String) goodAlgs.elementAt(i);
+ }
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ int i, j;
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+
+ // Get the certificate info from the request
+ //X509CertInfo certInfo[] = (X509CertInfo[])
+ // req.get(IRequest.CERT_INFO);
+ X509CertInfo certInfo[] = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // We need to have a certificate info set
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if the key algorithm is supported.
+ for (i = 0; i < certInfo.length; i++) {
+ // make sure our list of allowed algorithms makes
+ // sense for our key. Do this each time.
+ if (!winnowedByKey) {
+ winnowByKey();
+ }
+
+ CertificateAlgorithmId certAlgId = (CertificateAlgorithmId)
+ certInfo[i].get(X509CertInfo.ALGORITHM_ID);
+
+ AlgorithmId algId = (AlgorithmId)
+ certAlgId.get(CertificateAlgorithmId.ALGORITHM);
+ String alg = algId.getName();
+
+ // test against the list of allowed algorithms
+ for (j = 0; j < mAllowedAlgs.length; j++) {
+ if (mAllowedAlgs[j].equals(alg)) {
+ break;
+ }
+ }
+ if (j == mAllowedAlgs.length) {
+ // if the algor doesn't match the CA's key replace
+ // it with one that does.
+ if (mAllowedAlgs[0].equals("SHA1withDSA") ||
+ alg.equals("SHA1withDSA")) {
+ certInfo[i].set(X509CertInfo.ALGORITHM_ID,
+ new CertificateAlgorithmId(
+ AlgorithmId.get(mAllowedAlgs[0])));
+ return PolicyResult.ACCEPTED;
+ }
+
+ // didn't find a match, alg not allowed
+ setError(req, CMS.getUserMessage("CMS_POLICY_SIGNING_ALG_VIOLATION",
+ getInstanceName(), alg), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < mConfigAlgs.length; i++) {
+ sb.append(mConfigAlgs[i]);
+ sb.append(",");
+ }
+ if (sb.length() > 0)
+ sb.setLength(sb.length() - 1);
+ confParams.addElement(PROP_ALGORITHMS + "=" + sb.toString());
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(PROP_ALGORITHMS);
+ sb.append("=");
+ boolean first = true;
+
+ defConfParams.removeAllElements();
+
+ for (int i = 0; i < mDefaultAllowedAlgs.length; i++) {
+ if (first == true) {
+ sb.append(mDefaultAllowedAlgs[i]);
+ first = false;
+ } else {
+ sb.append(",");
+ sb.append(mDefaultAllowedAlgs[i]);
+ }
+ }
+ defConfParams.addElement(sb.toString());
+
+ return defConfParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ if (!winnowedByKey) {
+ try {
+ winnowByKey();
+ } catch (Exception e) {
+ }
+ }
+
+ String[] params = null;
+
+ String[] params_BOTH = {
+ PROP_ALGORITHMS + ";" + "choice(MD2withRSA\\,MD5withRSA\\,SHA1withRSA\\,SHA256withRSA\\,SHA512withRSA\\,SHA1withDSA," +
+ "MD2withRSA\\,MD5withRSA\\,SHA1withRSA\\,SHA1withDSA,"+
+ "MD2withRSA\\,MD5withRSA\\,SHA1withRSA," +
+ "MD2withRSA\\,SHA1withRSA\\,SHA1withDSA," +
+ "MD5withRSA\\,SHA1withRSA\\,SHA1withDSA," +
+ "MD2withRSA\\,MD5withRSA\\,SHA1withDSA," +
+ "MD2withRSA\\,MD5withRSA," +
+ "MD2withRSA\\,SHA1withRSA," +
+ "MD2withRSA\\,SHA1withDSA," +
+ "MD5withRSA\\,SHA1withRSA," +
+ "MD5withRSA\\,SHA1withDSA," +
+ "SHA1withRSA\\,SHA1withDSA," +
+ "MD2withRSA," +
+ "MD5withRSA," +
+ "SHA1withRSA," +
+ "SHA1withDSA);List of algorithms to restrict the requested signing algorithm " +
+ "to be one of the algorithms supported by Certificate System",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-signingalgconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Restricts the requested signing algorithm to be one of" +
+ " the algorithms supported by Certificate System"
+ };
+
+ String[] params_RSA = {
+ PROP_ALGORITHMS + ";" + "choice(MD2withRSA\\,MD5withRSA\\,SHA1withRSA," +
+ "MD2withRSA\\,MD5withRSA," +
+ "MD2withRSA\\,SHA1withRSA," +
+ "MD5withRSA\\,SHA1withRSA," +
+ "MD2withRSA," +
+ "MD5withRSA," +
+ "SHA1withRSA);Restrict the requested signing algorithm to be " +
+ "one of the algorithms supported by Certificate System",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-signingalgconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Restricts the requested signing algorithm to be one of" +
+ " the algorithms supported by Certificate System"
+ };
+
+ String[] params_DSA = {
+ PROP_ALGORITHMS + ";" + "choice(SHA1withDSA);Restrict the requested signing " +
+ "algorithm to be one of the algorithms supported by Certificate " +
+ "System",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-signingalgconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Restricts the requested signing algorithm to be one of" +
+ " the algorithms supported by Certificate System"
+ };
+
+ switch (mDefaultAllowedAlgs.length) {
+ case 1:
+ params = params_DSA;
+ break;
+
+ case 3:
+ params = params_RSA;
+ break;
+
+ case 4:
+ default:
+ params = params_BOTH;
+ break;
+
+ }
+
+ return params;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java
new file mode 100644
index 000000000..dffde5806
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/SubCANameConstraints.java
@@ -0,0 +1,189 @@
+// --- 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.policy.constraints;
+
+
+import org.mozilla.jss.crypto.*;
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.security.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This simple policy checks the subordinate CA CSR to see
+ * if it is the same as the local CA.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubCANameConstraints extends APolicyRule implements IEnrollmentPolicy, IExtendedPluginInfo {
+ public ICertificateAuthority mCA = null;
+ public String mIssuerNameStr = null;
+
+ public SubCANameConstraints() {
+ NAME = "SubCANameConstraints";
+ DESC = "Enforces Subordinate CA name.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subcanamecheck",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Checks if subordinate CA request matches the local CA. There are no parameters to change"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form
+ * ra.Policy.rule.<ruleName>.implName=KeyAlgorithmConstraints
+ * ra.Policy.rule.<ruleName>.algorithms=RSA,DSA
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // get CA's public key to create authority key id.
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ // should never get here.
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot find the Certificate Manager"));
+ }
+ if (!(certAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot find the Certificate Manager"));
+ }
+ mCA = (ICertificateAuthority) certAuthority;
+ ISigningUnit su = mCA.getSigningUnit();
+ if( su == null || CMS.isPreOpMode() ) {
+ return;
+ }
+
+ X509CertImpl cert = su.getCertImpl();
+
+ if (cert == null)
+ return;
+ X500Name issuerName = (X500Name) cert.getSubjectDN();
+
+ if (issuerName == null)
+ return;
+ mIssuerNameStr = issuerName.toString();
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+
+ // Get the certificate templates
+ X509CertInfo[] certInfos = req.getExtDataInCertInfoArray(
+ IRequest.CERT_INFO);
+
+ if (certInfos == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_NO_CERT_INFO", getInstanceName()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME + ":" + getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // retrieve the subject name and check its unqiueness
+ for (int i = 0; i < certInfos.length; i++) {
+ CertificateSubjectName subName = (CertificateSubjectName) certInfos[i].get(X509CertInfo.SUBJECT);
+
+ // if there is no name set, set one here.
+ if (subName == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_NO_SUBJECT_NAME_1", getInstanceName()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_SUBJECT_NAME", NAME + ":" + getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+ String certSubjectName = subName.toString();
+
+ if (certSubjectName.equalsIgnoreCase(mIssuerNameStr)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_SUBJECT_NAME_EXIST_1", mIssuerNameStr));
+ setError(req, CMS.getUserMessage("CMS_POLICY_SUBJECT_NAME_EXIST", NAME + ":" + "Same As Issuer Name " + mIssuerNameStr), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_NO_SUBJECT_NAME_1", getInstanceName()));
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector v = new Vector();
+
+ return v;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java b/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java
new file mode 100644
index 000000000..a2aeef09d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectName.java
@@ -0,0 +1,47 @@
+// --- 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.policy.constraints;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This class is used to help migrate CMS4.1 to CMS4.2.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class UniqueSubjectName extends UniqueSubjectNameConstraints {
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java
new file mode 100644
index 000000000..040b5e205
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/UniqueSubjectNameConstraints.java
@@ -0,0 +1,299 @@
+// --- 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.policy.constraints;
+
+
+import java.io.*;
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.dbs.certdb.*;
+import com.netscape.cms.policy.APolicyRule;
+import com.netscape.certsrv.apps.*;
+
+
+/**
+ * Checks the uniqueness of the subject name. This policy
+ * can only be used (installed) in Certificate Authority
+ * subsystem.
+ *
+ * This policy can perform pre-agent-approval checking or
+ * post-agent-approval checking based on configuration
+ * setting.
+ *
+ * In some situations, user may want to have 2 certificates with
+ * the same subject name. For example, one key for encryption,
+ * and one for signing. This policy does not deal with this case
+ * directly. But it can be easily extended to do that.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class UniqueSubjectNameConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_PRE_AGENT_APPROVAL_CHECKING =
+ "enablePreAgentApprovalChecking";
+ protected static final String PROP_KEY_USAGE_EXTENSION_CHECKING =
+ "enableKeyUsageExtensionChecking";
+
+ public ICertificateAuthority mCA = null;
+
+ public boolean mPreAgentApprovalChecking = false;
+ public boolean mKeyUsageExtensionChecking = true;
+
+ public UniqueSubjectNameConstraints() {
+ NAME = "UniqueSubjectName";
+ DESC = "Ensure the uniqueness of the subject name.";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_PRE_AGENT_APPROVAL_CHECKING + ";boolean;If checked, check subject name uniqueness BEFORE agent approves, (else checks AFTER approval)",
+ PROP_KEY_USAGE_EXTENSION_CHECKING + ";boolean;If checked, allow non-unique subject names if Key Usage Extension differs",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-uniquesubjectname",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Rejects a request if there exists an unrevoked, unexpired " +
+ "certificate with the same subject name"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=UniqueSubjectName
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.enablePreAgentApprovalChecking=true
+ * ca.Policy.rule.<ruleName>.enableKeyUsageExtensionChecking=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // get CA's public key to create authority key id.
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ // should never get here.
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", "Cannot find the Certificate Manager or Registration Manager"));
+ }
+ if (!(certAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", "Cannot find the Certificate Manager"));
+ }
+
+ mCA = (ICertificateAuthority) certAuthority;
+ try {
+ mPreAgentApprovalChecking =
+ config.getBoolean(PROP_PRE_AGENT_APPROVAL_CHECKING, false);
+ } catch (EBaseException e) {
+ }
+ try {
+ mKeyUsageExtensionChecking =
+ config.getBoolean(PROP_KEY_USAGE_EXTENSION_CHECKING, true);
+ } catch (EBaseException e) {
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ if (!mPreAgentApprovalChecking) {
+ // post agent approval checking
+ if (!agentApproved(req))
+ return PolicyResult.ACCEPTED;
+ }
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+
+ // Get the certificate templates
+ X509CertInfo[] certInfos = req.getExtDataInCertInfoArray(
+ IRequest.CERT_INFO);
+
+ if (certInfos == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // retrieve the subject name and check its unqiueness
+ for (int i = 0; i < certInfos.length; i++) {
+ CertificateSubjectName subName = (CertificateSubjectName)
+ certInfos[i].get(X509CertInfo.SUBJECT);
+
+ // if there is no name set, set one here.
+ if (subName == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_SUBJECT_NAME",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+ String certSubjectName = subName.toString();
+ String filter = "x509Cert.subject=" + certSubjectName;
+ // subject name is indexed, so we only use subject name
+ // in the filter
+ Enumeration matched =
+ mCA.getCertificateRepository().findCertRecords(filter);
+
+ while (matched.hasMoreElements()) {
+ ICertRecord rec = (ICertRecord) matched.nextElement();
+ String status = rec.getStatus();
+
+ if (status.equals(ICertRecord.STATUS_REVOKED) || status.equals(ICertRecord.STATUS_EXPIRED) || status.equals(ICertRecord.STATUS_REVOKED_EXPIRED)) {
+ // accept this only if we have a REVOKED,
+ // EXPIRED or REVOKED_EXPIRED certificate
+ continue;
+
+ }
+ // you already have an VALID or INVALID (not yet valid) certificate
+ if (mKeyUsageExtensionChecking && agentApproved(req)) {
+ // This request is agent approved which
+ // means all requested extensions are finalized
+ // to the request,
+ // We will accept duplicated subject name with
+ // different keyUsage extension if
+ // keyUsageExtension is different.
+ if (!sameKeyUsageExtension(rec, certInfos[i])) {
+ continue;
+ }
+ }
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_SUBJECT_NAME_EXIST",
+ getInstanceName() + " " + certSubjectName), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Checks if the key extension in the issued certificate
+ * is the same as the one in the certificate template.
+ */
+ private boolean sameKeyUsageExtension(ICertRecord rec,
+ X509CertInfo certInfo) {
+ X509CertImpl impl = rec.getCertificate();
+ boolean bits[] = impl.getKeyUsage();
+
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ } catch (java.security.cert.CertificateException e) {
+ }
+ KeyUsageExtension ext = null;
+
+ if (extensions == null) {
+ if (bits != null)
+ return false;
+ } else {
+ try {
+ ext = (KeyUsageExtension) extensions.get(
+ KeyUsageExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+
+ if (ext == null) {
+ if (bits != null)
+ return false;
+ } else {
+ boolean[] InfoBits = ext.getBits();
+
+ if (InfoBits == null) {
+ if (bits != null)
+ return false;
+ } else {
+ if (bits == null)
+ return false;
+ if (InfoBits.length != bits.length) {
+ return false;
+ }
+ for (int i = 0; i < InfoBits.length; i++) {
+ if (InfoBits[i] != bits[i])
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_PRE_AGENT_APPROVAL_CHECKING +
+ "=" + mPreAgentApprovalChecking);
+ confParams.addElement(PROP_KEY_USAGE_EXTENSION_CHECKING +
+ "=" + mKeyUsageExtensionChecking);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_PRE_AGENT_APPROVAL_CHECKING + "=");
+ defParams.addElement(PROP_KEY_USAGE_EXTENSION_CHECKING + "=");
+ return defParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java b/pki/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java
new file mode 100644
index 000000000..832d77746
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/constraints/ValidityConstraints.java
@@ -0,0 +1,316 @@
+// --- 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.policy.constraints;
+
+
+import java.util.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.common.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * ValidityConstraints is a default rule for Enrollment and
+ * Renewal that enforces minimum and maximum validity periods
+ * and changes them if not met.
+ *
+ * Optionally the lead and lag times - i.e how far back into the
+ * front or back the notBefore date could go in minutes can also
+ * be specified.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class ValidityConstraints extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected long mMinValidity;
+ protected long mMaxValidity;
+ protected long mLeadTime;
+ protected long mLagTime;
+ protected long mNotBeforeSkew;
+
+ private final static String PROP_MIN_VALIDITY = "minValidity";
+ private final static String PROP_MAX_VALIDITY = "maxValidity";
+ private final static String PROP_LEAD_TIME = "leadTime";
+ private final static String PROP_LAG_TIME = "lagTime";
+ private final static String PROP_NOT_BEFORE_SKEW = "notBeforeSkew";
+ public final static int DEF_MIN_VALIDITY = 180;
+ public final static int DEF_MAX_VALIDITY = 730;
+ public final static int DEF_LEAD_TIME = 10;
+ public final static int DEF_LAG_TIME = 10;
+ public final static int DEF_NOT_BEFORE_SKEW = 5;
+ public final static long DAYS_TO_MS_FACTOR = 24L * 3600 * 1000;
+ public final static long MINS_TO_MS_FACTOR = 60L * 1000;
+
+ private final static Vector defConfParams = new Vector();
+
+ static {
+ defConfParams.addElement(PROP_MIN_VALIDITY + "=" +
+ DEF_MIN_VALIDITY);
+ defConfParams.addElement(PROP_MAX_VALIDITY + "=" +
+ DEF_MAX_VALIDITY);
+ defConfParams.addElement(PROP_LEAD_TIME + "=" +
+ DEF_LEAD_TIME);
+ defConfParams.addElement(PROP_LAG_TIME + "=" +
+ DEF_LAG_TIME);
+ defConfParams.addElement(PROP_NOT_BEFORE_SKEW + "=" +
+ DEF_NOT_BEFORE_SKEW);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MIN_VALIDITY + ";number;Minimum Validity time, in days",
+ PROP_MAX_VALIDITY + ";number;Maximum Validity time, in days",
+ PROP_LEAD_TIME + ";number;Number of minutes in the future a request's notBefore can be",
+ PROP_LAG_TIME + ";number;NOT CURRENTLY IN USE",
+ PROP_NOT_BEFORE_SKEW + ";number;Number of minutes a cert's notBefore should be in the past",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-validityconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Ensures that the user's requested validity period is " +
+ "acceptable. If not specified, as is usually the case, " +
+ "this policy will set the validity. See RFC 2459."
+ };
+
+ return params;
+
+ }
+
+ public ValidityConstraints() {
+ NAME = "ValidityConstraints";
+ DESC = "Enforces minimum and maximum validity constraints.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries probably are of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=ValidityConstraints
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.minValidity=30
+ * ra.Policy.rule.<ruleName>.maxValidity=180
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EPolicyException {
+
+ // Get min and max validity in days and configure them.
+ try {
+ String val = config.getString(PROP_MIN_VALIDITY, null);
+
+ if (val == null)
+ mMinValidity = DEF_MIN_VALIDITY * DAYS_TO_MS_FACTOR;
+ else
+ mMinValidity = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_MAX_VALIDITY, null);
+ if (val == null)
+ mMaxValidity = DEF_MAX_VALIDITY * DAYS_TO_MS_FACTOR;
+ else
+ mMaxValidity = Long.parseLong(val) * DAYS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_LEAD_TIME, null);
+ if (val != null)
+ mLeadTime = Long.parseLong(val) * MINS_TO_MS_FACTOR;
+ else
+ mLeadTime = DEF_LEAD_TIME * MINS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_LAG_TIME, null);
+ if (val != null)
+ mLagTime = Long.parseLong(val) * MINS_TO_MS_FACTOR;
+ else
+ mLagTime = DEF_LAG_TIME * MINS_TO_MS_FACTOR;
+
+ val = config.getString(PROP_NOT_BEFORE_SKEW, null);
+ if (val != null)
+ mNotBeforeSkew = Long.parseLong(val) * MINS_TO_MS_FACTOR;
+ else
+ mNotBeforeSkew = DEF_NOT_BEFORE_SKEW * MINS_TO_MS_FACTOR;
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String[] params = {getInstanceName(), e.toString()};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG", params));
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ PolicyResult result = PolicyResult.ACCEPTED;
+
+ try {
+ // Get the certificate info from the request
+ //X509CertInfo certInfo[] = (X509CertInfo[])
+ // req.get(IRequest.CERT_INFO);
+ X509CertInfo certInfo[] = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ // There should be a certificate info set.
+ if (certInfo == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO",
+ getInstanceName()), "");
+ return PolicyResult.REJECTED;
+ }
+
+ // Else check if validity is within the limit
+ for (int i = 0; i < certInfo.length; i++) {
+ CertificateValidity validity = (CertificateValidity)
+ certInfo[i].get(X509CertInfo.VALIDITY);
+
+ Date notBefore = null, notAfter = null;
+
+ if (validity != null) {
+ notBefore = (Date)
+ validity.get(CertificateValidity.NOT_BEFORE);
+ notAfter = (Date)
+ validity.get(CertificateValidity.NOT_AFTER);
+ }
+
+ // If no validity is supplied yet, make one. The default
+ // validity is supposed to pass the following checks, so
+ // bypass further checking.
+ // (date = 0 is hack for serialization)
+
+ if (validity == null ||
+ (notBefore.getTime() == 0 && notAfter.getTime() == 0)) {
+ certInfo[i].set(X509CertInfo.VALIDITY,
+ makeDefaultValidity(req));
+ continue;
+ }
+
+ Date now = CMS.getCurrentDate();
+
+ if (notBefore.getTime() > (now.getTime() + mLeadTime)) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_INVALID_BEGIN_TIME",
+ getInstanceName()), "");
+ result = PolicyResult.REJECTED;
+ }
+ if ((notAfter.getTime() - notBefore.getTime()) >
+ mMaxValidity) {
+ String params[] = {getInstanceName(),
+ String.valueOf(
+ ((notAfter.getTime() - notBefore.getTime()) / DAYS_TO_MS_FACTOR)),
+ String.valueOf(mMaxValidity / DAYS_TO_MS_FACTOR)};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_MORE_THAN_MAX_VALIDITY", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ if ((notAfter.getTime() - notBefore.getTime()) <
+ mMinValidity) {
+ String params[] = {getInstanceName(),
+ String.valueOf(
+ ((notAfter.getTime() - notBefore.getTime()) / DAYS_TO_MS_FACTOR)),
+ String.valueOf(mMinValidity / DAYS_TO_MS_FACTOR)};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_LESS_THAN_MIN_VALIDITY", params), "");
+ result = PolicyResult.REJECTED;
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ String params[] = {getInstanceName(), e.toString()};
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ params), "");
+ result = PolicyResult.REJECTED;
+ }
+ return result;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector confParams = new Vector();
+
+ confParams.addElement(PROP_MIN_VALIDITY + "=" +
+ mMinValidity / DAYS_TO_MS_FACTOR);
+ confParams.addElement(PROP_MAX_VALIDITY + "=" +
+ mMaxValidity / DAYS_TO_MS_FACTOR);
+ confParams.addElement(PROP_LEAD_TIME + "="
+ + mLeadTime / MINS_TO_MS_FACTOR);
+ confParams.addElement(PROP_LAG_TIME + "=" +
+ mLagTime / MINS_TO_MS_FACTOR);
+ confParams.addElement(PROP_NOT_BEFORE_SKEW + "=" +
+ mNotBeforeSkew / MINS_TO_MS_FACTOR);
+ return confParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return defConfParams;
+ }
+
+ /**
+ * Create a default validity value for a request
+ *
+ * This code can be easily overridden in a derived class, if the
+ * calculations here aren't accepatble.
+ *
+ * TODO: it might be good to base this calculation on the creation
+ * time of the request.
+ */
+ protected CertificateValidity makeDefaultValidity(IRequest req) {
+ long now = roundTimeToSecond((CMS.getCurrentDate()).getTime());
+
+ // We will set the max duration as the default validity.
+ long notBeforeTime = now - mNotBeforeSkew;
+ Date notBefore = new Date(notBeforeTime);
+ Date notAfter = new Date(notBeforeTime + mMaxValidity);
+
+ return new CertificateValidity(notBefore, notAfter);
+ }
+
+ /**
+ * convert a millisecond resolution time into one with 1 second
+ * resolution. Most times in certificates are storage at 1
+ * second resolution, so its better if we deal with things at
+ * that level.
+ */
+ protected long roundTimeToSecond(long input) {
+ return (input / 1000) * 1000;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java
new file mode 100644
index 000000000..054379bb5
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/AuthInfoAccessExt.java
@@ -0,0 +1,381 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.ldap.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Authority Information Access extension policy.
+ * If this policy is enabled, it adds an authority
+ * information access extension to the certificate.
+ *
+ * The following listed sample configuration parameters:
+ *
+ * ca.Policy.impl.AuthInfoAccess.class=com.netscape.certsrv.policy.AuthInfoAccessExt
+ * ca.Policy.rule.aia.ad0_location=uriName:http://ocsp1.netscape.com
+ * ca.Policy.rule.aia.ad0_method=ocsp
+ * ca.Policy.rule.aia.ad1_location_type=URI
+ * ca.Policy.rule.aia.ad1_location=http://ocsp2.netscape.com
+ * ca.Policy.rule.aia.ad1_method=ocsp
+ * ca.Policy.rule.aia.ad2_location=
+ * ca.Policy.rule.aia.ad2_method=
+ * ca.Policy.rule.aia.ad3_location=
+ * ca.Policy.rule.aia.ad3_method=
+ * ca.Policy.rule.aia.ad4_location=
+ * ca.Policy.rule.aia.ad4_method=
+ * ca.Policy.rule.aia.critical=true
+ * ca.Policy.rule.aia.enable=true
+ * ca.Policy.rule.aia.implName=AuthInfoAccess
+ * ca.Policy.rule.aia.predicate=
+ *
+ * Currently, this policy only supports the following location:
+ * uriName:[URI], dirName:[DN]
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AuthInfoAccessExt extends APolicyRule implements
+ IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL =
+ "critical";
+ protected static final String PROP_AD =
+ "ad";
+ protected static final String PROP_METHOD =
+ "method";
+ protected static final String PROP_LOCATION =
+ "location";
+ protected static final String PROP_LOCATION_TYPE =
+ "location_type";
+
+ protected static final String PROP_NUM_ADS =
+ "numADs";
+
+ public static final int MAX_AD = 5;
+
+ public IConfigStore mConfig = null;
+
+ public AuthInfoAccessExt() {
+ NAME = "AuthInfoAccessExt";
+ DESC = "Sets authority information access extension for certificates";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector v = new Vector();
+
+ v.addElement(PROP_CRITICAL +
+ ";boolean;RFC 2459 recommendation: This extension MUST be non-critical.");
+ v.addElement(PROP_NUM_ADS +
+ ";number;The total number of access descriptions.");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Authority Info Access Extension. Defined in RFC 2459 " + "(4.2.2.1)");
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-authinfoaccess");
+
+ for (int i = 0; i < MAX_AD; i++) {
+ v.addElement(PROP_AD + Integer.toString(i) + "_" + PROP_METHOD + ";string;" + "A unique,valid OID specified in dot-separated numeric component notation. e.g. 1.3.6.1.5.5.7.48.1 (ocsp), 1.3.6.1.5.5.7.48.2 (caIssuers), 2.16.840.1.113730.1.16.1 (renewal)");
+ v.addElement(PROP_AD + Integer.toString(i) + "_" + PROP_LOCATION_TYPE + ";" + IGeneralNameUtil.GENNAME_CHOICE_INFO);
+ v.addElement(PROP_AD + Integer.toString(i) + "_" + PROP_LOCATION + ";" + IGeneralNameUtil.GENNAME_VALUE_INFO);
+ }
+ return com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=AuthInfoAccessExt
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.predicate=
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ }
+
+ /**
+ * Returns a sequence of access descriptions.
+ */
+ private Enumeration getAccessDescriptions() throws EBaseException {
+ Vector ads = new Vector();
+
+ //
+ // read until there is *NO* ad<NUM>_method
+ //
+ for (int i = 0;; i++) {
+ ObjectIdentifier methodOID = null;
+ String method = mConfig.getString(PROP_AD +
+ Integer.toString(i) + "_" + PROP_METHOD, null);
+
+ if (method == null)
+ break;
+ method = method.trim();
+ if (method.equals(""))
+ break;
+
+ //
+ // method ::= ocsp | caIssuers | <OID>
+ // OID ::= [object identifier]
+ //
+ try {
+ if (method.equalsIgnoreCase("ocsp")) {
+ methodOID = ObjectIdentifier.getObjectIdentifier("1.3.6.1.5.5.7.48.1");
+ } else if (method.equalsIgnoreCase("caIssuers")) {
+ methodOID = ObjectIdentifier.getObjectIdentifier("1.3.6.1.5.5.7.48.2");
+ } else if (method.equalsIgnoreCase("renewal")) {
+ methodOID = ObjectIdentifier.getObjectIdentifier("2.16.840.1.113730.1.16.1");
+ } else {
+ // it could be an object identifier, test it
+ methodOID = ObjectIdentifier.getObjectIdentifier(method);
+ }
+ } catch (IOException e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_ATTRIBUTE_NAME_CAN_NOT_BE_RESOLVED", method));
+ }
+
+ //
+ // location ::= <TAG> : <VALUE>
+ // TAG ::= uriName | dirName
+ // VALUE ::= [value defined by TAG]
+ //
+ String location_type = mConfig.getString(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_LOCATION_TYPE, null);
+ String location = mConfig.getString(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_LOCATION, null);
+
+ if (location == null)
+ break;
+ GeneralName gn = CMS.form_GeneralName(location_type, location);
+ Vector e = new Vector();
+
+ e.addElement(methodOID);
+ e.addElement(gn);
+ ads.addElement(e);
+ }
+ return ads.elements();
+ }
+
+ /**
+ * If this policy is enabled, add the authority information
+ * access extension to the certificate.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ X509CertInfo certInfo;
+ X509CertInfo[] ci = req.getExtDataInCertInfoArray(
+ IRequest.CERT_INFO);
+
+ if (ci == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int j = 0; j < ci.length; j++) {
+
+ certInfo = ci[j];
+ if (certInfo == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, ""));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, "Configuration Info Error"), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ try {
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // add access descriptions
+ Enumeration e = getAccessDescriptions();
+
+ if (!e.hasMoreElements()) {
+ return res;
+ }
+
+ if (extensions == null) {
+ // create extension if not exist
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ // check to see if AIA is already exist
+ try {
+ extensions.delete(AuthInfoAccessExtension.NAME);
+ log(ILogger.LL_WARN, "Previous extension deleted: " + AuthInfoAccessExtension.NAME);
+ } catch (IOException ex) {
+ }
+ }
+
+ // Create the extension
+ AuthInfoAccessExtension aiaExt = new
+ AuthInfoAccessExtension(mConfig.getBoolean(
+ PROP_CRITICAL, false));
+
+ while (e.hasMoreElements()) {
+ Vector ad = (Vector) e.nextElement();
+ ObjectIdentifier oid = (ObjectIdentifier) ad.elementAt(0);
+ GeneralName gn = (GeneralName) ad.elementAt(1);
+
+ aiaExt.addAccessDescription(oid, gn);
+ }
+ extensions.set(AuthInfoAccessExtension.NAME, aiaExt);
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, e.getMessage()), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, "Configuration Info Error"), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, "Certificate Info Error"), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ return res;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ try {
+ params.addElement(PROP_CRITICAL + "=" +
+ mConfig.getBoolean(PROP_CRITICAL, false));
+ } catch (EBaseException e) {
+ params.addElement(PROP_CRITICAL + "=false");
+ }
+
+ int numADs = MAX_AD;
+
+ try {
+ numADs = mConfig.getInteger(PROP_NUM_ADS, MAX_AD);
+ params.addElement(PROP_NUM_ADS + "=" + numADs);
+ } catch (EBaseException e) {
+ params.addElement(PROP_NUM_ADS + "=" + MAX_AD);
+ }
+
+ for (int i = 0; i < numADs; i++) {
+ String method = null;
+
+ try {
+ method = mConfig.getString(PROP_AD +
+ Integer.toString(i) + "_" + PROP_METHOD,
+ "");
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_METHOD + "=" + method);
+ String location_type = null;
+
+ try {
+ location_type = mConfig.getString(PROP_AD +
+ Integer.toString(i) + "_" + PROP_LOCATION_TYPE,
+ IGeneralNameUtil.GENNAME_CHOICE_URL);
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_LOCATION_TYPE + "=" + location_type);
+ String location = null;
+
+ try {
+ location = mConfig.getString(PROP_AD +
+ Integer.toString(i) + "_" + PROP_LOCATION,
+ "");
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_AD +
+ Integer.toString(i) +
+ "_" + PROP_LOCATION + "=" + location);
+ }
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_NUM_ADS + "=" + MAX_AD);
+
+ //
+ // By default, we create MAX_AD access descriptions.
+ // If this is not enough, admin can manually edit
+ // the CMS.cfg
+ //
+ for (int i = 0; i < MAX_AD; i++) {
+ defParams.addElement(PROP_AD + Integer.toString(i) +
+ "_" + PROP_METHOD + "=");
+ defParams.addElement(PROP_AD + Integer.toString(i) +
+ "_" + PROP_LOCATION_TYPE + "=" + IGeneralNameUtil.GENNAME_CHOICE_URL);
+ defParams.addElement(PROP_AD + Integer.toString(i) +
+ "_" + PROP_LOCATION + "=");
+ }
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java
new file mode 100644
index 000000000..b170925c4
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/AuthorityKeyIdentifierExt.java
@@ -0,0 +1,418 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidKeyException;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Authority Public Key Extension Policy
+ * Adds the subject public key id extension to certificates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class AuthorityKeyIdentifierExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_ALT_KEYID_TYPE = "AltKeyIdType";
+
+ protected static final String ALT_KEYID_TYPE_SPKISHA1 = "SpkiSHA1";
+ protected static final String ALT_KEYID_TYPE_NONE = "None";
+ protected static final String ALT_KEYID_TYPE_EMPTY = "Empty";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final String DEF_ALT_KEYID_TYPE = ALT_KEYID_TYPE_SPKISHA1;
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ // config params.
+ protected boolean mCritical = DEF_CRITICAL;
+ protected String mAltKeyIdType = DEF_ALT_KEYID_TYPE;
+
+ // the extension to add to certs.
+ protected AuthorityKeyIdentifierExtension mTheExtension = null;
+
+ // instance params for console
+ protected Vector mInstanceParams = new Vector();
+
+ // default params for console.
+ protected static Vector mDefaultParams = new Vector();
+ static {
+ // form static default params.
+ mDefaultParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefaultParams.addElement(PROP_ALT_KEYID_TYPE + "=" + DEF_ALT_KEYID_TYPE);
+ }
+
+ public AuthorityKeyIdentifierExt() {
+ NAME = "AuthorityKeyIdentifierExt";
+ DESC = "Adds Authority Key Idenifier Extension to certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * Reads configuration file and creates a authority key identifier
+ * extension to add. Key identifier inside the extension is constructed as
+ * the CA's subject key identifier extension if it exists.
+ * If it does not exist this can be configured to use:
+ * (1) sha-1 hash of the CA's subject public key info
+ * (what communicator expects if the CA does not have a subject key
+ * identifier extension) or (2) No extension set (3) Empty sequence
+ * in Authority Key Identifier extension.
+ *
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mAltKeyIdType = mConfig.getString(
+ PROP_ALT_KEYID_TYPE, DEF_ALT_KEYID_TYPE);
+
+ if (mAltKeyIdType.equalsIgnoreCase(ALT_KEYID_TYPE_SPKISHA1))
+ mAltKeyIdType = ALT_KEYID_TYPE_SPKISHA1;
+
+ /*
+ else if (mAltKeyIdType.equalsIgnoreCase(ALT_KEYID_TYPE_EMPTY))
+ mAltKeyIdType = ALT_KEYID_TYPE_EMPTY;
+ */
+ else if (mAltKeyIdType.equalsIgnoreCase(ALT_KEYID_TYPE_NONE))
+ mAltKeyIdType = ALT_KEYID_TYPE_NONE;
+ else {
+ log(ILogger.LL_FAILURE, NAME +
+ CMS.getLogMessage("CA_UNKNOWN_ALT_KEY_ID_TYPE", mAltKeyIdType));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE", PROP_ALT_KEYID_TYPE,
+ "value must be one of " + ALT_KEYID_TYPE_SPKISHA1 + ", " + ALT_KEYID_TYPE_NONE));
+ }
+
+ // create authority key id extension.
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ // should never get here.
+ String msg = NAME + ": " +
+ "Cannot find the Certificate Manager or Registration Manager";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", msg));
+ }
+ if (!(certAuthority instanceof ICertificateAuthority)) {
+ log(ILogger.LL_FAILURE, NAME +
+ CMS.getLogMessage("POLICY_INVALID_POLICY", NAME));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ NAME + " policy can only be used in a Certificate Authority."));
+ }
+ //CertificateChain caChain = certAuthority.getCACertChain();
+ //X509Certificate caCert = caChain.getFirstCertificate();
+ X509CertImpl caCert = certAuthority.getCACert();
+ if( caCert == null || CMS.isPreOpMode() ) {
+ return;
+ }
+ KeyIdentifier keyId = formKeyIdentifier(caCert);
+
+ if (keyId != null) {
+ try {
+ mTheExtension = new AuthorityKeyIdentifierExtension(
+ mCritical, keyId, null, null);
+ } catch (IOException e) {
+ String msg = NAME + ": " +
+ "Error forming Authority Key Identifier extension: " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_AUTHORITY_KEY_ID_1", NAME));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", msg));
+ }
+ } else {
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(PROP_ALT_KEYID_TYPE + "=" + mAltKeyIdType);
+ }
+
+ /**
+ * Adds Authority Key Identifier Extension to a certificate.
+ * If the extension is already there, accept it if it's from the agent,
+ * else replace it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME), "");
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certResult = applyCert(req, ci[i]);
+
+ if (certResult == PolicyResult.REJECTED)
+ return certResult;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ try {
+ // if authority key id extension already exists, leave it if
+ // from agent. else replace it.
+ AuthorityKeyIdentifierExtension authorityKeyIdExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ authorityKeyIdExt = (AuthorityKeyIdentifierExtension)
+ extensions.get(AuthorityKeyIdentifierExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+ if (authorityKeyIdExt != null) {
+ if (agentApproved(req)) {
+ CMS.debug(
+ "AuthorityKeyIdentifierKeyExt: agent approved request id " + req.getRequestId() +
+ " already has authority key id extension with value " +
+ authorityKeyIdExt);
+ return PolicyResult.ACCEPTED;
+ } else {
+ CMS.debug(
+ "AuthorityKeyIdentifierKeyExt: request id from user " + req.getRequestId() +
+ " had authority key identifier - deleted");
+ extensions.delete(AuthorityKeyIdentifierExtension.NAME);
+ }
+ }
+
+ // if no authority key identifier should be set b/c CA does not
+ // have a subject key identifier, return here.
+ if (mTheExtension == null)
+ return PolicyResult.ACCEPTED;
+
+ // add authority key id extension.
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ AuthorityKeyIdentifierExtension.NAME, mTheExtension);
+ CMS.debug(
+ "AuthorityKeyIdentifierKeyExt: added authority key id ext to request " + req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, e.getMessage()), "");
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_INVALID_CERT", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR",
+ NAME, "Certificate Info Error"), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Form the Key Identifier in the Authority Key Identifier extension.
+ * from the CA's cert.
+ * <p>
+ * @param caCertImpl Certificate Info
+ * @return A Key Identifier.
+ * @throws com.netscape.certsrv.base.EBaseException on error
+ */
+ protected KeyIdentifier formKeyIdentifier(X509CertImpl caCertImpl)
+ throws EBaseException {
+ KeyIdentifier keyId = null;
+
+ // get CA's certInfo.
+ X509CertInfo certInfo = null;
+
+ try {
+ certInfo = (X509CertInfo) caCertImpl.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ if (certInfo == null) {
+ String msg = "Bad CA certificate encountered. " +
+ "TBS Certificate missing.";
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_CERT_FORMAT"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", NAME + ": " + msg));
+ }
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, NAME + ": " +
+ CMS.getLogMessage("BASE_DECODE_CERT_FAILED_1", e.toString()));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ NAME + " Error decoding the CA Certificate: " + e));
+ }
+
+ // get Key Id from CA's Subject Key Id extension in CA's CertInfo.
+ keyId = getKeyIdentifier(certInfo);
+ if (keyId != null)
+ return keyId;
+
+ // if none exists use the configured alternate.
+ if (mAltKeyIdType == ALT_KEYID_TYPE_SPKISHA1) {
+ keyId = formSpkiSHA1KeyId(certInfo);
+ } /*
+ else if (mAltKeyIdType == ALT_KEYID_TYPE_EMPTY) {
+ keyId = formEmptyKeyId(certInfo);
+ }
+ */ else if (mAltKeyIdType == ALT_KEYID_TYPE_NONE) {
+ keyId = null;
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mAltKeyIdType,
+ "Unknown Alternate Key Identifier type."));
+ }
+ return keyId;
+ }
+
+ /**
+ * Get the Key Identifier in a subject key identifier extension from a
+ * CertInfo.
+ * @param certInfo the CertInfo structure.
+ * @return Key Identifier in a Subject Key Identifier extension if any.
+ */
+ protected KeyIdentifier getKeyIdentifier(X509CertInfo certInfo)
+ throws EBaseException {
+ CertificateExtensions exts = null;
+ SubjectKeyIdentifierExtension subjKeyIdExt = null;
+ KeyIdentifier keyId = null;
+
+ try {
+ exts = (CertificateExtensions) certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ // extension isn't there.
+ CMS.debug(NAME + ": " + "No extensions found. Error " + e);
+ return null;
+ } catch (CertificateException e) {
+ // extension isn't there.
+ CMS.debug(NAME + ": " + "No extensions found. Error " + e);
+ return null;
+ }
+ if (exts == null)
+ return null;
+
+ try {
+ subjKeyIdExt = (SubjectKeyIdentifierExtension)
+ exts.get(SubjectKeyIdentifierExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there.
+ CMS.debug(
+ "AuthorityKeyIdentifierKeyExt: No Subject Key Identifier Extension found. Error: " + e);
+ return null;
+ }
+ if (subjKeyIdExt == null)
+ return null;
+
+ try {
+ keyId = (KeyIdentifier) subjKeyIdExt.get(
+ SubjectKeyIdentifierExtension.KEY_ID);
+ } catch (IOException e) {
+ // no key identifier in subject key id extension.
+ String msg = NAME + ": " +
+ "Bad Subject Key Identifier Extension found. Error: " + e;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_AUTHORITY_KEY_ID_1", NAME));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", msg));
+ }
+ return keyId;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefaultParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;" +
+ "RFC 2459 recommendation: MUST NOT be marked critical.",
+ PROP_ALT_KEYID_TYPE + ";" +
+ "choice(" + ALT_KEYID_TYPE_SPKISHA1 + "," + ALT_KEYID_TYPE_NONE + ");" +
+ "Specifies whether to use a SHA1 hash of the CA's subject " +
+ "public key info for key identifier or leave out the " +
+ "authority key identifier extension if the CA certificate " +
+ "does not have a Subject Key Identifier extension.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-authkeyid",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Authority Key Identifier Extension. " +
+ "See RFC 2459 (4.2.1.1)"
+ };
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java
new file mode 100644
index 000000000..73a6b58af
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/BasicConstraintsExt.java
@@ -0,0 +1,498 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Basic Constraints policy.
+ * Adds the Basic constraints extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class BasicConstraintsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_MAXPATHLEN = "maxPathLen";
+ protected static final String PROP_IS_CA = "isCA";
+ protected static final String PROP_IS_CRITICAL = "critical";
+
+ protected static final String ARG_PATHLEN = "BasicConstraintsPathLen";
+
+ protected int mMaxPathLen = 0; // < 0 means unlimited
+ protected String mOrigMaxPathLen = ""; // for UI display only
+ protected boolean mCritical = true;
+ protected int mDefaultMaxPathLen = 0; // depends on the CA's path length.
+ protected int mCAPathLen = 0;
+ protected boolean mRemoveExt = true;
+ protected boolean mIsCA = true;
+
+ public static final boolean DEFAULT_CRITICALITY = true;
+
+ /**
+ * Adds the basic constraints extension as a critical extension in
+ * CA certificates i.e. certype is ca, with either a requested
+ * or configured path len.
+ * The requested or configured path length cannot be greater than
+ * or equal to the CA's basic constraints path length.
+ * If the CA path length is 0, all requests for CA certs are rejected.
+ */
+ public BasicConstraintsExt() {
+ NAME = "BasicConstraintsExt";
+ DESC =
+ "Sets critical basic constraints extension in subordinate CA certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <p>
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=BasicConstraintsExtImpl
+ * ca.Policy.rule.<ruleName>.pathLen=<n>, -1 for undefined.
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+ // get the CA's path len to check against configured max path len.
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ // should never get here.
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot find the Certificate Manager or Registration Manager"));
+ }
+ if (certAuthority instanceof IRegistrationAuthority) {
+ log(ILogger.LL_WARN,
+ "default basic constraints extension path len to -1.");
+ mCAPathLen = -1;
+ } else {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ if( caChain == null || CMS.isPreOpMode() ) {
+ return;
+ }
+ X509Certificate caCert = caChain.getFirstCertificate();
+
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ // set default to one less than the CA's pathlen or 0 if CA's
+ // pathlen is 0.
+ // If it's unlimited default the max pathlen also to unlimited.
+ if (mCAPathLen < 0)
+ mDefaultMaxPathLen = -1;
+ else if (mCAPathLen > 0)
+ mDefaultMaxPathLen = mCAPathLen - 1;
+ else // (mCAPathLen == 0)
+ {
+ log(ILogger.LL_WARN,
+ CMS.getLogMessage("POLICY_PATHLEN_ZERO"));
+ //return;
+ }
+
+ // get configured max path len, use defaults if not configured.
+ boolean pathLenConfigured = true;
+
+ try {
+ mCritical = config.getBoolean(PROP_IS_CRITICAL, true);
+ mIsCA = config.getBoolean(PROP_IS_CA, true);
+ mMaxPathLen = config.getInteger(PROP_MAXPATHLEN);
+ if (mMaxPathLen < 0) {
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("POLICY_INVALID_MAXPATHLEN_4", "",
+ String.valueOf(mMaxPathLen)));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_MAXPATHLEN_1",
+ NAME, String.valueOf(mMaxPathLen)));
+ }
+ mOrigMaxPathLen = Integer.toString(mMaxPathLen);
+ } catch (EBaseException e) {
+ if (!(e instanceof EPropertyNotFound) &&
+ !(e instanceof EPropertyNotDefined)) {
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("POLICY_INVALID_MAXPATHLEN"));
+ throw e;
+ }
+
+ // Set the max path len to default if not configured.
+ pathLenConfigured = false;
+ mMaxPathLen = mDefaultMaxPathLen;
+ mOrigMaxPathLen = "";
+ }
+
+ // check if configured path len is valid.
+ if (pathLenConfigured) {
+ // if CA's pathlen is unlimited, any max pathlen is ok.
+ // else maxPathlen must be at most one less than the CA's
+ // pathlen or 0 if CA's pathlen is 0.
+
+ if (mCAPathLen > 0 &&
+ (mMaxPathLen >= mCAPathLen || mMaxPathLen < 0)) {
+ String maxStr = (mMaxPathLen < 0) ?
+ String.valueOf(mMaxPathLen) + "(unlimited)" :
+ String.valueOf(mMaxPathLen);
+
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("POLICY_MAXPATHLEN_TOO_BIG_3", "",
+ maxStr,
+ String.valueOf(mCAPathLen)));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_MAXPATHLEN_TOO_BIG_1",
+ NAME, maxStr, Integer.toString(mCAPathLen)));
+ } else if (mCAPathLen == 0 && mMaxPathLen != 0) {
+ log(ILogger.LL_MISCONF,
+ CMS.getLogMessage("POLICY_INVALID_MAXPATHLEN_2", "", String.valueOf(mMaxPathLen)));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_MAXPATHLEN",
+ NAME, String.valueOf(mMaxPathLen)));
+ }
+ }
+
+ }
+
+ /**
+ * Checks if the basic contraints extension in certInfo is valid and
+ * add the basic constraints extension for CA certs if none exists.
+ * Non-CA certs do not get a basic constraints extension.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ X509CertInfo certInfo = null;
+
+ if (ci == null || (certInfo = ci[0]) == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ // get cert type
+ boolean isCA = mIsCA;
+
+ /**
+ boolean isCA = false;
+ String type = (String)req.get(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+ if (type != null && type.equalsIgnoreCase(IRequest.CA_CERT)) {
+ isCA = true;
+ }
+ **/
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certResult = applyCert(req, isCA, certInfo);
+
+ if (certResult == PolicyResult.REJECTED)
+ return certResult;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(
+ IRequest req, boolean isCA, X509CertInfo certInfo) {
+
+ // get basic constraints extension from cert info if any.
+ CertificateExtensions extensions = null;
+ BasicConstraintsExtension basicExt = null;
+
+ try {
+ // get basic constraints extension if any.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ if (extensions != null) {
+ basicExt = (BasicConstraintsExtension)
+ extensions.get(BasicConstraintsExtension.NAME);
+ }
+ } catch (IOException e) {
+ // no extensions or basic constraints extension.
+ } catch (CertificateException e) {
+ // no extensions or basic constraints extension.
+ }
+
+ // for non-CA certs, pkix says it SHOULD NOT have the extension
+ // so remove it.
+ if (!isCA) {
+ if (extensions == null) {
+ try {
+ // create extensions set if none.
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (CertificateException e) {
+ } catch (IOException e) {
+ // not possible
+ }
+ }
+ if (basicExt != null) {
+ try {
+ extensions.delete(BasicConstraintsExtension.NAME);
+ } catch (IOException e) {
+ }
+ }
+
+ BasicConstraintsExtension critExt;
+
+ try {
+ critExt = new BasicConstraintsExtension(isCA, mCritical, mMaxPathLen);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_BASIC_CONSTRAINTS_2",
+ e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_BASIC_CONSTRAINTS_ERROR", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ try {
+ extensions.set(BasicConstraintsExtension.NAME, critExt);
+ } catch (IOException e) {
+ }
+ CMS.debug(
+ "BasicConstraintsExt: PolicyRule BasicConstraintsExt: added the extension to request " +
+ req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ }
+
+ // For CA certs, check if existing extension is valid, and adjust.
+ // Extension must be marked critial and pathlen must be < CA's pathlen.
+ // if CA's pathlen is 0 all ca certs are rejected.
+
+ if (mCAPathLen == 0) {
+ // reject all subordinate CA cert requests because CA's
+ // path length is 0.
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_NO_SUB_CA_CERTS_ALLOWED_1", NAME));
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_SUB_CA_CERTS_ALLOWED", NAME), "");
+ return PolicyResult.REJECTED;
+ }
+
+ if (basicExt != null) {
+ try {
+ boolean extIsCA =
+ ((Boolean) basicExt.get(BasicConstraintsExtension.IS_CA)).booleanValue();
+ int pathLen =
+ ((Integer) basicExt.get(BasicConstraintsExtension.PATH_LEN)).intValue();
+
+ if (mMaxPathLen > -1) {
+ if (pathLen > mMaxPathLen || pathLen < 0) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_MAXPATHLEN_TOO_BIG_3", NAME, "unlimited", String.valueOf(pathLen)));
+ if (pathLen < 0)
+ setError(req, CMS.getUserMessage("CMS_POLICY_MAXPATHLEN_TOO_BIG",
+ NAME, "unlimited", Integer.toString(mMaxPathLen)), "");
+ else
+ setError(req, CMS.getUserMessage("CMS_POLICY_MAXPATHLEN_TOO_BIG",
+ NAME, Integer.toString(pathLen),
+ Integer.toString(mMaxPathLen)), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ // adjust isCA field
+ if (!extIsCA) {
+ basicExt.set(BasicConstraintsExtension.IS_CA,
+ Boolean.valueOf(true));
+ }
+
+ // adjust path length field.
+ if (mMaxPathLen == 0) {
+ if (pathLen != 0) {
+ basicExt.set(BasicConstraintsExtension.PATH_LEN,
+ Integer.valueOf(0));
+ pathLen = 0;
+ }
+ } else if (mMaxPathLen > 0 && pathLen > mMaxPathLen) {
+ basicExt.set(BasicConstraintsExtension.PATH_LEN,
+ Integer.valueOf(mMaxPathLen));
+ pathLen = mMaxPathLen;
+ }
+
+ // adjust critical field.
+ if (!basicExt.isCritical()) {
+ BasicConstraintsExtension critExt;
+
+ try {
+ critExt = new BasicConstraintsExtension(isCA, mCritical, pathLen);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_BASIC_CONSTRAINTS_1", NAME));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_BASIC_CONSTRAINTS_ERROR", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ extensions.delete(BasicConstraintsExtension.NAME);
+ extensions.set(BasicConstraintsExtension.NAME, critExt);
+ }
+ } catch (IOException e) {
+ // not possible in these cases.
+ }
+ CMS.debug(
+ "BasicConstraintsExt: PolicyRule BasicConstraintsExt: added the extension to request " +
+ req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ }
+
+ // add the extension for the CA cert.
+ if (extensions == null) {
+ try {
+ // create extensions set if none.
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (CertificateException e) {
+ // not possible
+ } catch (IOException e) {
+ // not possible
+ }
+ }
+
+ // set path len to requested path len if it's valid.
+ // if no path len requested set path len to max allowed path len.
+ String reqPathLenStr = req.getExtDataInString(ARG_PATHLEN);
+ int reqPathLen;
+
+ if (reqPathLenStr == null) {
+ reqPathLen = mMaxPathLen;
+ } else {
+ try {
+ reqPathLen = Integer.parseInt(reqPathLenStr);
+ if ((mMaxPathLen == 0 && reqPathLen != 0) ||
+ (mMaxPathLen > 0 &&
+ (reqPathLen > mMaxPathLen || reqPathLen < 0))) {
+ String plenStr =
+ ((reqPathLen < 0) ?
+ reqPathLenStr + "(unlimited)" : reqPathLenStr);
+
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_PATHLEN_TOO_BIG_3", plenStr,
+ String.valueOf(mMaxPathLen)));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_PATHLEN_TOO_BIG",
+ NAME, plenStr, String.valueOf(mMaxPathLen)), "");
+ return PolicyResult.REJECTED;
+ }
+ } catch (NumberFormatException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_INVALID_PATHLEN_FORMAT_2", NAME, reqPathLenStr));
+ setError(req, CMS.getUserMessage("CMS_POLICY_INVALID_PATHLEN_FORMAT",
+ NAME, reqPathLenStr), "");
+ return PolicyResult.REJECTED;
+ }
+ }
+ BasicConstraintsExtension newExt;
+
+ try {
+ newExt = new BasicConstraintsExtension(isCA, mCritical, reqPathLen);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_BASIC_CONSTRAINTS_2", e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_BASIC_CONSTRAINTS_ERROR", NAME), "");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ try {
+ extensions.set(BasicConstraintsExtension.NAME, newExt);
+ }catch (IOException e) {
+ // doesn't happen.
+ }
+ CMS.debug(
+ "BasicConstraintsExt: added the extension to request " +
+ req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ // Because of one of the UI bugs 385273, we should leave the empty space
+ // as is. Do not convert the space to some definite numbers.
+ params.addElement(PROP_MAXPATHLEN + "=" + mOrigMaxPathLen);
+ params.addElement(PROP_IS_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_IS_CA + "=" + mIsCA);
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_IS_CRITICAL + "=true");
+ defParams.addElement(PROP_MAXPATHLEN + "=");
+ defParams.addElement(PROP_IS_CA + "=true");
+ return defParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_MAXPATHLEN + ";number;'0' means : no subordinates allowed, 'n' means : at most n subordinates allowed.",
+ PROP_IS_CRITICAL + ";boolean;" +
+ "RFC 2459 recommendation: MUST be critical in CA certs, SHOULD NOT appear in EE certs.",
+ PROP_IS_CA + ";boolean;" +
+ "Identifies the subject of the certificate is a CA or not.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-basicconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds the Basic Constraints extension. See RFC 2459 (4.2.1.10)"
+ };
+
+ return params;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java
new file mode 100644
index 000000000..84664b09d
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/CRLDistributionPointsExt.java
@@ -0,0 +1,464 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.util.BitArray;
+import netscape.security.x509.*;
+import netscape.security.x509.CRLDistributionPointsExtension.Reason;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * The type of the distribution point or issuer name. The name is expressed
+ * as a simple string in the configuration file, so this attribute is needed
+ * to tell whether the simple string should be stored in an X.500 Name,
+ * a URL, or an RDN.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+class NameType {
+ private NameType() {
+ } // no default constructor
+
+ private String stringRep; // string representation of this type
+
+ private NameType(String s) {
+ map.put(s, this);
+ stringRep = s;
+ }
+
+ private static Hashtable map = new Hashtable();
+
+ /**
+ * Looks up a NameType from its string representation. Returns null
+ * if no matching NameType was found.
+ */
+ public static NameType fromString(String s) {
+ return (NameType) map.get(s);
+ }
+
+ public String toString() {
+ return stringRep;
+ }
+
+ public static final NameType DIRECTORY_NAME = new NameType("DirectoryName");
+ public static final NameType URI = new NameType("URI");
+ public static final NameType RELATIVE_TO_ISSUER =
+ new NameType("RelativeToIssuer");
+}
+
+
+/**
+ * These are the parameters that may be given in the configuration file
+ * for each distribution point. They are parsed by DPParamsToDP().
+ * Any of them may be null.
+ */
+class DistPointParams {
+ public String pointName;
+ public String pointType;
+
+ public String reasons;
+
+ public String issuerName;
+ public String issuerType;
+
+ public DistPointParams() {
+ }
+
+ public DistPointParams(DistPointParams old) {
+ pointName = old.pointName;
+ pointType = old.pointType;
+ reasons = old.reasons;
+ issuerName = old.issuerName;
+ issuerType = old.issuerType;
+ }
+
+}
+
+
+/**
+ * CRL Distribution Points policy.
+ * Adds the CRL Distribution Points extension to the certificate.
+ */
+public class CRLDistributionPointsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ public static final String PROP_IS_CRITICAL = "critical";
+ public static final String PROP_NUM_POINTS = "numPoints";
+ public static final String PROP_POINT_TYPE = "pointType";
+ public static final String PROP_POINT_NAME = "pointName";
+ public static final String PROP_REASONS = "reasons";
+ public static final String PROP_ISSUER_NAME = "issuerName";
+ public static final String PROP_ISSUER_TYPE = "issuerType";
+
+ private static final int MAX_POINTS = 10;
+ private static final int DEFAULT_NUM_BLANK_POINTS = 3;
+ private int mNumPoints = DEFAULT_NUM_BLANK_POINTS;
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ private Vector defaultParams = new Vector();
+
+ private Vector mParams = new Vector();
+ private String mExtParams[] = null;
+ private CRLDistributionPointsExtension mCrldpExt = null;
+
+ public CRLDistributionPointsExt() {
+ NAME = "CRLDistributionPointsExt";
+ DESC = "Sets CRL distribution points extension";
+ defaultParams.addElement(PROP_IS_CRITICAL + "=" + DEFAULT_CRITICALITY);
+ defaultParams.addElement(PROP_NUM_POINTS + "=0");
+ for (int i = 0; i < DEFAULT_NUM_BLANK_POINTS; i++) {
+ defaultParams.addElement(PROP_POINT_NAME + i + "=");
+ defaultParams.addElement(PROP_POINT_TYPE + i + "=");
+ defaultParams.addElement(PROP_REASONS + i + "=");
+ defaultParams.addElement(PROP_ISSUER_NAME + i + "=");
+ defaultParams.addElement(PROP_ISSUER_TYPE + i + "=");
+ }
+ }
+
+ private void setExtendedPluginInfo() {
+ Vector v = new Vector();
+
+ // should replace MAX_POINTS with mNumPoints if bug 385118 is fixed
+ for (int i = 0; i < MAX_POINTS; i++) {
+ v.addElement(PROP_POINT_TYPE + Integer.toString(i) + ";choice(" +
+ "DirectoryName,URI,RelativeToIssuer);" +
+ "The type of the CRL distribution point.");
+ v.addElement(PROP_POINT_NAME + Integer.toString(i) + ";string;" +
+ "The name of the CRL distribution point depending on the CRLDP type.");
+ v.addElement(PROP_REASONS + Integer.toString(i) + ";string;" +
+ "The revocation reasons for the CRL maintained at this distribution point. It's a comma-seperated list of the following constants: unused, keyCompromise, cACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold.");
+ v.addElement(PROP_ISSUER_TYPE + Integer.toString(i) + ";choice(" +
+ "DirectoryName,URI);" +
+ "The type of the issuer that has signed the CRL maintained at this distribution point.");
+ v.addElement(PROP_ISSUER_NAME + Integer.toString(i) + ";string;" +
+ "The name of the issuer that has signed the CRL maintained at this distribution point. The value depends on the issuer type.");
+ }
+
+ v.addElement(PROP_NUM_POINTS +
+ ";number;The total number of CRL distribution points to be contained or allowed in the extension.");
+ v.addElement(PROP_IS_CRITICAL +
+ ";boolean;RFC 2459 recommendation: SHOULD be non-critical. But recommends support for this extension by CAs and applications.");
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-crldistributionpoints");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";This policy inserts the CRL Distribution Points " +
+ "Extension into the certificate. See RFC 2459 (4.2.1.14). "
+ );
+
+ mExtParams = com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ if (mExtParams == null) {
+ setExtendedPluginInfo();
+ }
+ return mExtParams;
+
+ }
+
+ /**
+ * Performs one-time initialization of the policy.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // Register the CRL Distribution Points extension.
+ try {
+ netscape.security.x509.OIDMap.addAttribute(
+ CRLDistributionPointsExtension.class.getName(),
+ CRLDistributionPointsExtension.OID,
+ CRLDistributionPointsExtension.NAME);
+ } catch (CertificateException e) {
+ // ignore, just means it has already been added
+ }
+
+ // assemble the list of Distribution Points from the config file
+ int numPoints = config.getInteger(PROP_NUM_POINTS, 0);
+
+ mParams.addElement(PROP_NUM_POINTS + "=" + numPoints);
+ mNumPoints = numPoints;
+
+ for (int i = 0; i < numPoints; i++) {
+ // construct a distribution point from the parameters
+ DistPointParams params = new DistPointParams();
+
+ params.pointType = config.getString(PROP_POINT_TYPE + i, "");
+ params.pointName = config.getString(PROP_POINT_NAME + i, "");
+ params.reasons = config.getString(PROP_REASONS + i, "");
+ params.issuerType = config.getString(PROP_ISSUER_TYPE + i, "");
+ params.issuerName = config.getString(PROP_ISSUER_NAME + i, "");
+
+ DistPointParams configparams = new DistPointParams(params);
+ CRLDistributionPoint crldp = DPParamsToDP(params);
+
+ mParams.addElement(PROP_POINT_TYPE + i + "=" + configparams.pointType);
+ mParams.addElement(PROP_POINT_NAME + i + "=" + configparams.pointName);
+ mParams.addElement(PROP_REASONS + i + "=" + configparams.reasons);
+ mParams.addElement(PROP_ISSUER_TYPE + i + "=" + configparams.issuerType);
+ mParams.addElement(PROP_ISSUER_NAME + i + "=" + configparams.issuerName);
+
+ // add the distribution point to the extension
+ if (mCrldpExt == null) {
+ mCrldpExt = new CRLDistributionPointsExtension(crldp);
+ } else {
+ mCrldpExt.addPoint(crldp);
+ }
+ }
+
+ boolean crit = config.getBoolean(PROP_IS_CRITICAL,
+ DEFAULT_CRITICALITY);
+
+ mParams.addElement(PROP_IS_CRITICAL + "=" + crit);
+ if (mCrldpExt != null) {
+ // configure the extension itself
+ mCrldpExt.setCritical(crit);
+ }
+ setExtendedPluginInfo();
+
+ }
+
+ /**
+ * Parses the parameters in the config file to create an
+ * actual CRL Distribution Point object.
+ */
+ private CRLDistributionPoint DPParamsToDP(DistPointParams params)
+ throws EBaseException {
+ CRLDistributionPoint crlDP = new CRLDistributionPoint();
+
+ try {
+
+ if (params.pointName != null && params.pointName.length() == 0) {
+ params.pointName = null;
+ }
+ if (params.pointType != null && params.pointType.length() == 0) {
+ params.pointType = null;
+ }
+ if (params.reasons != null && params.reasons.length() == 0) {
+ params.reasons = null;
+ }
+ if (params.issuerName != null && params.issuerName.length() == 0) {
+ params.issuerName = null;
+ }
+ if (params.issuerType != null && params.issuerType.length() == 0) {
+ params.issuerType = null;
+ }
+
+ // deal with the distribution point name
+ if (params.pointName != null && params.pointType != null) {
+ // decode the type of the name
+ NameType nType = NameType.fromString(params.pointType);
+
+ if (nType == null) {
+ String err = "Unknown name type: " + params.pointType;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_NAME_TYPE", params.pointType));
+ throw new EBaseException(err);
+ }
+
+ if (nType == NameType.DIRECTORY_NAME) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(new GeneralName(new X500Name(params.pointName)));
+ crlDP.setFullName(gen);
+ } else if (nType == NameType.URI) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(new GeneralName(new URIName(params.pointName)));
+ crlDP.setFullName(gen);
+ } else if (nType == NameType.RELATIVE_TO_ISSUER) {
+ crlDP.setRelativeName(new RDN(params.pointName));
+ } else {
+ String err = "Unknown name type: " + nType.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_NAME_TYPE", nType.toString()));
+ throw new EBaseException(err);
+ }
+ }
+
+ // deal with the reasons
+ if (params.reasons != null) {
+ StringTokenizer tok = new StringTokenizer(params.reasons, ", \t");
+ byte reasonBits = 0;
+
+ while (tok.hasMoreTokens()) {
+ String s = tok.nextToken();
+ Reason r = Reason.fromString(s);
+
+ if (r == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_REASON", s));
+ throw new EBaseException("Unknown reason: " + s);
+ } else {
+ reasonBits |= r.getBitMask();
+ }
+ }
+ if (reasonBits != 0) {
+ BitArray ba = new BitArray(8, new byte[] { reasonBits }
+ );
+
+ crlDP.setReasons(ba);
+ }
+ }
+
+ // deal with the issuer name
+ if (params.issuerName != null && params.issuerType != null) {
+ // decode the type of the name
+ NameType nType = NameType.fromString(params.issuerType);
+
+ if (nType == null) {
+ String err = "Unknown name type: " + params.issuerType;
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_NAME_TYPE", params.issuerType));
+ throw new EBaseException(err);
+ }
+
+ if (nType == NameType.DIRECTORY_NAME) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(new GeneralName(new X500Name(params.issuerName)));
+ crlDP.setCRLIssuer(gen);
+ } else if (nType == NameType.URI) {
+ GeneralNames gen = new GeneralNames();
+
+ gen.addElement(new GeneralName(new URIName(params.issuerName)));
+ crlDP.setCRLIssuer(gen);
+ } else {
+ String err = "Unknown name type: " + nType.toString();
+
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_UNKNOWN_NAME_TYPE", nType.toString()));
+ throw new EBaseException(err);
+ }
+ }
+
+ } catch (GeneralNamesException e) {
+ throw new EBaseException(e.getMessage());
+ } catch (IOException e) {
+ throw new EBaseException(e.getMessage());
+ }
+
+ // done, return this distribution point
+ return crlDP;
+ }
+
+ /**
+ * Applies the policy to the given request.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // if the extension was not configured correctly, just skip it
+ if (mCrldpExt == null) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ X509CertInfo[] ci = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ try {
+ // find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // prepare the extensions data structure
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(CRLDistributionPointsExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there
+ }
+ }
+ extensions.set(CRLDistributionPointsExtension.NAME, mCrldpExt);
+
+ return PolicyResult.ACCEPTED;
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR", NAME, e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR",
+ e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ // parameters must be entered in the config file
+ public Vector getDefaultParams() {
+ for (int i = DEFAULT_NUM_BLANK_POINTS; i < mNumPoints; i++) {
+ defaultParams.addElement(PROP_POINT_NAME + i + "=");
+ defaultParams.addElement(PROP_POINT_TYPE + i + "=");
+ defaultParams.addElement(PROP_REASONS + i + "=");
+ defaultParams.addElement(PROP_ISSUER_NAME + i + "=");
+ defaultParams.addElement(PROP_ISSUER_TYPE + i + "=");
+ }
+ return defaultParams;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java
new file mode 100644
index 000000000..bcf9d11cb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificatePoliciesExt.java
@@ -0,0 +1,521 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.x509.PolicyQualifierInfo;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Certificate Policies.
+ * Adds certificate policies extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class CertificatePoliciesExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_NUM_CERTPOLICIES = "numCertPolicies";
+
+ protected static final String PROP_CERTPOLICY = "certPolicy";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final int DEF_NUM_CERTPOLICIES = 1;
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mNumCertPolicies = DEF_NUM_CERTPOLICIES;
+ protected CertPolicy[] mCertPolicies = null;
+
+ protected Vector mInstanceParams = new Vector();
+ protected CertificatePoliciesExtension mCertificatePoliciesExtension = null;
+
+ public CertificatePoliciesExt() {
+ NAME = "CertificatePoliciesExt";
+ DESC = "Sets non-critical certificate policies extension in certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=certType==ca
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mNumCertPolicies = mConfig.getInteger(
+ PROP_NUM_CERTPOLICIES, DEF_NUM_CERTPOLICIES);
+ if (mNumCertPolicies < 1) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_ATTR_VALUE_2", NAME, ""));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_NUM_CERTPOLICIES,
+ "value must be greater than or equal to 1"));
+ }
+
+ // init Policy Mappings, check values if enabled.
+ mCertPolicies = new CertPolicy[mNumCertPolicies];
+ for (int i = 0; i < mNumCertPolicies; i++) {
+ String subtreeName = PROP_CERTPOLICY + i;
+
+ try {
+ mCertPolicies[i] = new CertPolicy(subtreeName, mConfig, mEnabled);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, NAME + ": " +
+ CMS.getLogMessage("POLICY_ERROR_CREATE_CERT_POLICY", e.toString()));
+ throw e;
+ }
+ }
+
+ // create instance of certificate policy extension if enabled.
+ if (mEnabled) {
+ try {
+ Vector CertPolicies = new Vector();
+
+ for (int j = 0; j < mNumCertPolicies; j++) {
+ CertPolicies.addElement(
+ mCertPolicies[j].mCertificatePolicyInfo);
+ }
+ mCertificatePoliciesExtension =
+ new CertificatePoliciesExtension(mCritical, CertPolicies);
+ } catch (IOException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Error initializing " + NAME + " Error: " + e));
+ }
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_NUM_CERTPOLICIES + "=" + mNumCertPolicies);
+ for (int i = 0; i < mNumCertPolicies; i++) {
+ mCertPolicies[i].getInstanceParams(mInstanceParams);
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <p>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ try {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (Exception e) {
+ }
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(CertificatePoliciesExtension.NAME);
+ } catch (IOException e) {
+ // this is the hack: for some reason, the key which is the name
+ // of the policy has been converted into the OID
+ try {
+ extensions.delete("2.5.29.32");
+ } catch (IOException ee) {
+ }
+ }
+ }
+ extensions.set(CertificatePoliciesExtension.NAME,
+ mCertificatePoliciesExtension);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1",
+ e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1",
+ e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1",
+ e.toString()));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Default config parameters.
+ * To add more permitted or excluded subtrees,
+ * increase the num to greater than 0 and more configuration params
+ * will show up in the console.
+ */
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(
+ PROP_NUM_CERTPOLICIES + "=" + DEF_NUM_CERTPOLICIES);
+ String certPolicy0Dot = PROP_CERTPOLICY + "0.";
+
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_POLICY_IDENTIFIER + "=" + "");
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_NOTICE_REF_ORG + "=" + "");
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_NOTICE_REF_NUMS + "=" + "");
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_USER_NOTICE_TEXT + "=" + "");
+ mDefParams.addElement(
+ certPolicy0Dot + CertPolicy.PROP_CPS_URI + "=" + "");
+
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector theparams = new Vector();
+
+ theparams.addElement(PROP_CRITICAL + ";boolean;RFC 3280 recommendation: MUST be non-critical.");
+ theparams.addElement(PROP_NUM_CERTPOLICIES + ";number; Number of certificate policies. The value must be greater than or equal to 1");
+
+ for (int k = 0; k < 5; k++) {
+ String certPolicykDot = PROP_CERTPOLICY + k + ".";
+
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_POLICY_IDENTIFIER + ";string,required;An object identifier in the form n.n.n.n");
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_NOTICE_REF_ORG + ";string;See RFC 3280 sec 4.2.1.5");
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_NOTICE_REF_NUMS +
+ ";string;comma-separated list of numbers. See RFC 3280 sec 4.2.1.5");
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_USER_NOTICE_TEXT + ";string;See RFC 3280 sec 4.2.1.5");
+ theparams.addElement(certPolicykDot +
+ CertPolicy.PROP_CPS_URI + ";string;See RFC 3280 sec 4.2.1.5");
+ }
+
+ theparams.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-certificatepolicies");
+ theparams.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Certificate Policies Extension. See RFC 3280 (4.2.1.5)");
+
+ String[] params = new String[theparams.size()];
+
+ theparams.copyInto(params);
+ return params;
+ }
+}
+
+
+class CertPolicy {
+
+ protected static final String PROP_POLICY_IDENTIFIER = "policyId";
+ protected static final String PROP_NOTICE_REF_ORG = "noticeRefOrganization";
+ protected static final String PROP_NOTICE_REF_NUMS = "noticeRefNumbers";
+ protected static final String PROP_USER_NOTICE_TEXT = "userNoticeExplicitText";
+ protected static final String PROP_CPS_URI = "cpsURI";
+
+ protected String mName = null;
+ protected String mNameDot = null;
+ protected IConfigStore mConfig = null;
+
+ protected String mPolicyId = null;
+ protected String mNoticeRefOrg = null;
+ protected String mNoticeRefNums = null;
+ protected String mNoticeRefExplicitText = null;
+ protected String mCpsUri = null;
+
+ protected CertificatePolicyInfo mCertificatePolicyInfo = null;
+
+ /**
+ * forms policy map parameters.
+ * @param name name of this policy map, for example certPolicy0
+ * @param config parent's config from where we find this configuration.
+ * @param enabled whether policy was enabled.
+ */
+ protected CertPolicy(String name, IConfigStore config, boolean enabled)
+ throws EBaseException {
+ mName = name;
+ mConfig = config.getSubStore(mName);
+ mNameDot = mName + ".";
+
+ if( mConfig == null ) {
+ CMS.debug( "CertificatePoliciesExt::CertPolicy - mConfig is " +
+ "null!" );
+ throw new EBaseException( "mConfig is null" );
+ }
+
+ // if there's no configuration for this policy put it there.
+ if (mConfig.size() == 0) {
+ config.putString(mNameDot + PROP_POLICY_IDENTIFIER, "");
+ config.putString(mNameDot + PROP_NOTICE_REF_ORG, "");
+ config.putString(mNameDot + PROP_NOTICE_REF_NUMS, "");
+ config.putString(mNameDot + PROP_USER_NOTICE_TEXT, "");
+ config.putString(mNameDot + PROP_CPS_URI, "");
+ mConfig = config.getSubStore(mName);
+ if(mConfig == null || mConfig.size() == 0) {
+ CMS.debug( "CertificatePoliciesExt::CertPolicy - mConfig " +
+ "is null or empty!" );
+ throw new EBaseException( "mConfig is null or empty" );
+ }
+ }
+
+ // get policy ids from configuration.
+ mPolicyId = mConfig.getString(PROP_POLICY_IDENTIFIER, null);
+ mNoticeRefOrg = mConfig.getString(PROP_NOTICE_REF_ORG, null);
+ mNoticeRefNums = mConfig.getString(PROP_NOTICE_REF_NUMS, null);
+ mNoticeRefExplicitText = mConfig.getString(PROP_USER_NOTICE_TEXT, null);
+ mCpsUri = mConfig.getString(PROP_CPS_URI, null);
+
+ // adjust for "" and console returning "null"
+ if (mPolicyId != null &&
+ (mPolicyId.length() == 0 ||
+ mPolicyId.equals("null"))) {
+ mPolicyId = null;
+ }
+ if (mNoticeRefOrg != null &&
+ (mNoticeRefOrg.length() == 0 ||
+ mNoticeRefOrg.equals("null"))) {
+ mNoticeRefOrg = null;
+ }
+ if (mNoticeRefNums != null &&
+ (mNoticeRefNums.length() == 0 ||
+ mNoticeRefNums.equals("null"))) {
+ mNoticeRefNums = null;
+ }
+ if (mNoticeRefExplicitText != null &&
+ (mNoticeRefExplicitText.length() == 0 ||
+ mNoticeRefExplicitText.equals("null"))) {
+ mNoticeRefExplicitText = null;
+ }
+ if (mCpsUri != null &&
+ (mCpsUri.length() == 0 ||
+ mCpsUri.equals("null"))) {
+ mCpsUri = null;
+ }
+
+ // policy ids cannot be null if policy is enabled.
+ String msg = "value cannot be null.";
+
+ if (mPolicyId == null && enabled)
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mNameDot + PROP_POLICY_IDENTIFIER, msg));
+ msg = "NoticeReference is optional; If chosen to include, NoticeReference must at least has 'organization'";
+ if (mNoticeRefOrg == null && mNoticeRefNums != null && enabled)
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mNameDot + PROP_NOTICE_REF_ORG, msg));
+
+ // if a policy id is not null check that it is a valid OID.
+ ObjectIdentifier policyId = null;
+
+ if (mPolicyId != null)
+ policyId = CMS.checkOID(
+ mNameDot + PROP_POLICY_IDENTIFIER, mPolicyId);
+
+ // if enabled, form CertificatePolicyInfo to be encoded in
+ // extension. Policy ids should be all set.
+ if (enabled) {
+ CMS.debug("CertPolicy: in CertPolicy");
+ DisplayText displayText = null;
+
+ if (mNoticeRefExplicitText != null &&
+ !mNoticeRefExplicitText.equals(""))
+ displayText = new DisplayText(DisplayText.tag_VisibleString, mNoticeRefExplicitText);
+ // new DisplayText(DisplayText.tag_IA5String, mNoticeRefExplicitText);
+ DisplayText orgName = null;
+
+ if (mNoticeRefOrg != null &&
+ !mNoticeRefOrg.equals(""))
+ orgName =
+ new DisplayText(DisplayText.tag_VisibleString, mNoticeRefOrg);
+ // new DisplayText(DisplayText.tag_VisibleString, mNoticeRefOrg);
+
+ int[] nums = new int[0];;
+ if (mNoticeRefNums != null &&
+ !mNoticeRefNums.equals("")) {
+
+ // should add a method to NoticeReference to take a
+ // Vector...but let's do this for now
+
+ Vector numsVector = new Vector();
+ StringTokenizer tokens = new StringTokenizer(mNoticeRefNums,
+ ",");
+
+ while (tokens.hasMoreTokens()) {
+ String num = tokens.nextToken().trim();
+
+ numsVector.addElement(num);
+ }
+
+ nums = new int[numsVector.size()];
+
+ for (int i = 0; i < numsVector.size(); i++) {
+ Integer ii = new Integer((String) numsVector.elementAt(i));
+
+ nums[i] = ii.intValue();
+ }
+ }
+ CertificatePolicyId cpolicyId = null;
+
+ try {
+ cpolicyId = new CertificatePolicyId(ObjectIdentifier.getObjectIdentifier(mPolicyId));
+ } catch (Exception e) {
+ throw new
+ EBaseException(CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR", mPolicyId));
+ }
+
+ PolicyQualifiers policyQualifiers = new PolicyQualifiers();
+
+ NoticeReference noticeReference = null;
+
+ if (orgName != null)
+ noticeReference = new NoticeReference(orgName, nums);
+
+ UserNotice userNotice = null;
+
+ if (displayText != null || noticeReference != null) {
+ userNotice = new UserNotice (noticeReference, displayText);
+
+ PolicyQualifierInfo policyQualifierInfo1 =
+ new PolicyQualifierInfo(PolicyQualifierInfo.QT_UNOTICE, userNotice);
+
+ policyQualifiers.add(policyQualifierInfo1);
+ }
+
+ CPSuri cpsUri = null;
+
+ if (mCpsUri != null && mCpsUri.length() > 0) {
+ cpsUri = new CPSuri (mCpsUri);
+ PolicyQualifierInfo policyQualifierInfo2 =
+ new PolicyQualifierInfo(PolicyQualifierInfo.QT_CPS, cpsUri);
+
+ policyQualifiers.add(policyQualifierInfo2);
+ }
+
+ if ((mNoticeRefOrg == null || mNoticeRefOrg.equals("")) &&
+ (mNoticeRefExplicitText == null || mNoticeRefExplicitText.equals("")) &&
+ (mCpsUri == null || mCpsUri.equals(""))) {
+ CMS.debug("CertPolicy mNoticeRefOrg = "+mNoticeRefOrg);
+ CMS.debug("CertPolicy mNoticeRefExplicitText = "+mNoticeRefExplicitText);
+ CMS.debug("CertPolicy mCpsUri = "+mCpsUri);
+
+ mCertificatePolicyInfo = new CertificatePolicyInfo(cpolicyId);
+ } else {
+ CMS.debug("CertPolicy mNoticeRefOrg = "+mNoticeRefOrg);
+ CMS.debug("CertPolicy mNoticeRefExplicitText = "+mNoticeRefExplicitText);
+ CMS.debug("CertPolicy mCpsUri = "+mCpsUri);
+ mCertificatePolicyInfo = new CertificatePolicyInfo(cpolicyId, policyQualifiers);
+ }
+ }
+ }
+
+ protected void getInstanceParams(Vector instanceParams) {
+ instanceParams.addElement(
+ mNameDot + PROP_POLICY_IDENTIFIER + "=" + (mPolicyId == null ? "" :
+ mPolicyId));
+ instanceParams.addElement(
+ mNameDot + PROP_NOTICE_REF_ORG + "=" + (mNoticeRefOrg == null ? "" :
+ mNoticeRefOrg));
+ instanceParams.addElement(
+ mNameDot + PROP_NOTICE_REF_NUMS + "=" + (mNoticeRefNums == null ? "" :
+ mNoticeRefNums));
+ instanceParams.addElement(
+ mNameDot + PROP_USER_NOTICE_TEXT + "=" + (mNoticeRefExplicitText == null ? "" :
+ mNoticeRefExplicitText));
+ instanceParams.addElement(
+ mNameDot + PROP_CPS_URI + "=" + (mCpsUri == null ? "" :
+ mCpsUri));
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java
new file mode 100644
index 000000000..e761ecfab
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateRenewalWindowExt.java
@@ -0,0 +1,247 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Certificate Renewal Window Extension Policy
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class CertificateRenewalWindowExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ protected static final String PROP_END_TIME = "relativeEndTime";
+ protected static final String PROP_BEGIN_TIME = "relativeBeginTime";
+ protected static final String PROP_CRITICAL = "critical";
+
+ protected boolean mCritical;
+ protected String mBeginTime;
+ protected String mEndTime;
+
+ /**
+ * Adds the Netscape comment in the end-entity certificates or
+ * CA certificates. The policy is set to be non-critical with the
+ * provided OID.
+ */
+ public CertificateRenewalWindowExt() {
+ NAME = "CertificateRenewalWindowExt";
+ DESC = "Sets non-critical Certificate Renewal Window extension in certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mCritical = config.getBoolean(PROP_CRITICAL, false);
+ mBeginTime = config.getString(PROP_BEGIN_TIME, null);
+ mEndTime = config.getString(PROP_END_TIME, null);
+
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <p>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult r = applyCert(req, ci[i]);
+
+ if (r == PolicyResult.REJECTED)
+ return r;
+ }
+ return res;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ } catch (CertificateException e) {
+ }
+
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ try {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (Exception e) {
+ }
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(CertificateRenewalWindowExtension.NAME);
+
+ } catch (IOException e) {
+ // this is the hack: for some reason, the key which is the name
+ // of the policy has been converted into the OID
+ try {
+ extensions.delete("2.16.840.1.113730.1.15");
+ } catch (IOException ee) {
+ }
+ }
+ }
+
+ try {
+ Date now = CMS.getCurrentDate();
+ CertificateRenewalWindowExtension crwExt = null;
+
+ if (mEndTime == null || mEndTime.equals("")) {
+ crwExt = new CertificateRenewalWindowExtension(
+ mCritical,
+ getDateValue(now, mBeginTime),
+ null);
+ } else {
+ crwExt = new CertificateRenewalWindowExtension(
+ mCritical,
+ getDateValue(now, mBeginTime),
+ getDateValue(now, mEndTime));
+ }
+ extensions.set(CertificateRenewalWindowExtension.NAME,
+ crwExt);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1", NAME));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public Date getDateValue(Date relativeFrom, String s) {
+ long time;
+
+ if (s.endsWith("s")) {
+ time = 1000 * Long.parseLong(s.substring(0,
+ s.length() - 1));
+ } else if (s.endsWith("m")) {
+ time = 60 * 1000 * Long.parseLong(s.substring(0,
+ s.length() - 1));
+ } else if (s.endsWith("h")) {
+ time = 60 * 60 * 1000 * Long.parseLong(s.substring(0,
+ s.length() - 1));
+ } else if (s.endsWith("D")) {
+ time = 24 * 60 * 60 * 1000 * Long.parseLong(
+ s.substring(0, s.length() - 1));
+ } else if (s.endsWith("M")) {
+ time = 30 * 60 * 60 * 1000 * Long.parseLong(
+ s.substring(0, s.length() - 1));
+ } else {
+ time = 1000 * Long.parseLong(s);
+ }
+
+ return new Date(relativeFrom.getTime() + time);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;Netscape recommendation: non-critical.",
+ PROP_BEGIN_TIME + ";string;Start Time in seconds (Relative to the time of issuance). Optionally, time unit (s - seconds, m - minutes, h - hours, D - days, M - months) can be specified right after the value. For example, 5 days can be expressed as 5D.",
+ PROP_END_TIME + ";string;End Time in seconds (Optional, Relative to the time of issuance). Optionally, time unit (s - seconds, m - minutes, h - hours, D - days, M - months) can be specified right after the value. For example, 5 days can be expressed as 5D.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-certificaterenewalwindow",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds 'Certificate Renewal Window' extension. See manual"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ if (mBeginTime == null) {
+ params.addElement(PROP_BEGIN_TIME + "=");
+ } else {
+ params.addElement(PROP_BEGIN_TIME + "=" + mBeginTime);
+ }
+ if (mEndTime == null) {
+ params.addElement(PROP_END_TIME + "=");
+ } else {
+ params.addElement(PROP_END_TIME + "=" + mEndTime);
+ }
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_BEGIN_TIME + "=");
+ defParams.addElement(PROP_END_TIME + "=");
+ return defParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java
new file mode 100644
index 000000000..a8d5f8a0c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/CertificateScopeOfUseExt.java
@@ -0,0 +1,320 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.ldap.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Certificate Scope Of Use extension policy. This extension
+ * is defined in draft-thayes-cert-scope-00.txt
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class CertificateScopeOfUseExt extends APolicyRule implements
+ IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL =
+ "critical";
+ protected static final String PROP_ENTRY =
+ "entry";
+ protected static final String PROP_NAME =
+ "name";
+ protected static final String PROP_NAME_TYPE =
+ "name_type";
+ protected static final String PROP_PORT_NUMBER =
+ "port_number";
+
+ public static final int MAX_ENTRY = 5;
+
+ public IConfigStore mConfig = null;
+
+ public CertificateScopeOfUseExt() {
+ NAME = "CertificateScopeOfUseExt";
+ DESC = "Sets scope of use extension for certificates";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector v = new Vector();
+
+ v.addElement(PROP_CRITICAL +
+ ";boolean; This extension may be either critical or non-critical.");
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-certificatescopeofuse");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Certificate Scope of Use Extension.");
+
+ for (int i = 0; i < MAX_ENTRY; i++) {
+ v.addElement(PROP_ENTRY + Integer.toString(i) + "_" + PROP_NAME + ";" + IGeneralNameUtil.GENNAME_VALUE_INFO);
+ v.addElement(PROP_ENTRY + Integer.toString(i) + "_" + PROP_NAME_TYPE + ";" + IGeneralNameUtil.GENNAME_CHOICE_INFO);
+ v.addElement(PROP_ENTRY + Integer.toString(i) + "_" + PROP_PORT_NUMBER + ";string;" + "The port number (optional).");
+ }
+ return com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=AuthInfoAccessExt
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.predicate=
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ }
+
+ /**
+ * Returns a sequence of scope entry.
+ */
+ private Vector getScopeEntries() throws EBaseException {
+ Vector entries = new Vector();
+
+ //
+ // read until there is *NO* ad<NUM>_method
+ //
+ for (int i = 0;; i++) {
+ // get port number (optional)
+ String port = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) + "_" + PROP_PORT_NUMBER, null);
+ BigInt portNumber = null;
+
+ if (port != null && !port.equals("")) {
+ portNumber = new BigInt(Integer.parseInt(port));
+ }
+
+ //
+ // location ::= <TAG> : <VALUE>
+ // TAG ::= uriName | dirName
+ // VALUE ::= [value defined by TAG]
+ //
+ String name_type = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_NAME_TYPE, null);
+ String name = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_NAME, null);
+
+ if (name == null || name.equals(""))
+ break;
+ GeneralName gn = CMS.form_GeneralNameAsConstraints(name_type, name);
+
+ entries.addElement(new CertificateScopeEntry(gn, portNumber));
+ }
+ return entries;
+ }
+
+ /**
+ * If this policy is enabled, add the authority information
+ * access extension to the certificate.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ X509CertInfo certInfo;
+ X509CertInfo[] ci = req.getExtDataInCertInfoArray(
+ IRequest.CERT_INFO);
+
+ if (ci == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int j = 0; j < ci.length; j++) {
+
+ certInfo = ci[j];
+ if (certInfo == null) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_CERT_INFO_ERROR", NAME));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Configuration Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ try {
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // add access descriptions
+ Vector entries = getScopeEntries();
+
+ if (entries.size() == 0) {
+ return res;
+ }
+
+ if (extensions == null) {
+ // create extension if not exist
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ // check to see if AIA is already exist
+ try {
+ extensions.delete(CertificateScopeOfUseExtension.NAME);
+ log(ILogger.LL_INFO, "Previous extension deleted: " + CertificateScopeOfUseExtension.NAME);
+ } catch (IOException ex) {
+ }
+ }
+
+ // Create the extension
+ CertificateScopeOfUseExtension suExt = new
+ CertificateScopeOfUseExtension(mConfig.getBoolean(
+ PROP_CRITICAL, false), entries);
+
+ extensions.set(CertificateScopeOfUseExtension.NAME, suExt);
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE,
+ "Configuration Info Error encountered: " +
+ e.getMessage());
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Configuration Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ return res;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ try {
+ params.addElement(PROP_CRITICAL + "=" +
+ mConfig.getBoolean(PROP_CRITICAL, false));
+ } catch (EBaseException e) {
+ }
+
+ for (int i = 0;; i++) {
+ String name_type = null;
+
+ try {
+ name_type = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) + "_" + PROP_NAME_TYPE,
+ null);
+ } catch (EBaseException e) {
+ }
+ if (name_type == null)
+ break;
+ params.addElement(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_NAME_TYPE + "=" + name_type);
+ String name = null;
+
+ try {
+ name = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) + "_" + PROP_NAME,
+ null);
+ } catch (EBaseException e) {
+ }
+ if (name == null)
+ break;
+ params.addElement(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_NAME + "=" + name);
+ String port = null;
+
+ try {
+ port = mConfig.getString(PROP_ENTRY +
+ Integer.toString(i) + "_" + PROP_PORT_NUMBER,
+ "");
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_ENTRY +
+ Integer.toString(i) +
+ "_" + PROP_PORT_NUMBER + "=" + port);
+ }
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+
+ //
+ // By default, we create MAX_AD access descriptions.
+ // If this is not enough, admin can manually edit
+ // the CMS.cfg
+ //
+ for (int i = 0; i < MAX_ENTRY; i++) {
+ defParams.addElement(PROP_ENTRY + Integer.toString(i) +
+ "_" + PROP_NAME_TYPE + "=");
+ defParams.addElement(PROP_ENTRY + Integer.toString(i) +
+ "_" + PROP_NAME + "=");
+ defParams.addElement(PROP_ENTRY + Integer.toString(i) +
+ "_" + PROP_PORT_NUMBER + "=");
+ }
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java
new file mode 100644
index 000000000..783ab2b6e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/ExtendedKeyUsageExt.java
@@ -0,0 +1,271 @@
+// --- 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.policy.extensions;
+
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import java.security.cert.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This implements the extended key usage extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class ExtendedKeyUsageExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ public static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_PURPOSE_ID = "id";
+ protected static final String PROP_NUM_IDS = "numIds";
+ protected static int MAX_PURPOSE_ID = 10;
+ private boolean mCritical = false;
+ private IConfigStore mConfig = null;
+ private Vector mUsages = null;
+
+ private String[] mParams = null;
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ private ExtendedKeyUsageExtension mExtendedKeyUsage = null;
+
+ /**
+ * Constructs extended Key Usage extension.
+ */
+ public ExtendedKeyUsageExt() {
+ NAME = "ExtendedKeyUsageExt";
+ DESC = "Sets ExtendedKeyUsage extension for certificates";
+ }
+
+ /**
+ * Performs one-time initialization of the policy.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ setExtendedPluginInfo();
+ setupParams();
+ mExtendedKeyUsage = new ExtendedKeyUsageExtension(mCritical, mUsages);
+ }
+
+ /**
+ * Applies the policy to the given request.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // if the extension was not configured correctly, just skip it
+ if (mExtendedKeyUsage == null) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ try {
+ // find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // prepare the extensions data structure
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ try {
+ extensions.delete(ExtendedKeyUsageExtension.NAME);
+ } catch (IOException ex) {
+ // ExtendedKeyUsage extension is not already there
+ }
+ }
+
+ extensions.set(ExtendedKeyUsageExtension.NAME, mExtendedKeyUsage);
+
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR",
+ e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Returns instance specific parameters.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ int numIds = MAX_PURPOSE_ID;
+
+ try {
+ numIds = mConfig.getInteger(PROP_NUM_IDS, MAX_PURPOSE_ID);
+ } catch (EBaseException e) {
+ }
+ params.addElement(PROP_NUM_IDS + "=" + numIds);
+ String usage = null;
+
+ for (int i = 0; i < numIds; i++) {
+ if (mUsages.size() <= i) {
+ params.addElement(PROP_PURPOSE_ID +
+ Integer.toString(i) + "=");
+ } else {
+ usage = ((ObjectIdentifier) mUsages.elementAt(i)).toString();
+ if (usage == null) {
+ params.addElement(PROP_PURPOSE_ID +
+ Integer.toString(i) + "=");
+ } else {
+ params.addElement(PROP_PURPOSE_ID +
+ Integer.toString(i) + "=" + usage);
+ }
+ }
+ }
+ return params;
+ }
+
+ private void setExtendedPluginInfo() {
+ Vector v = new Vector();
+ int mNum = MAX_PURPOSE_ID;
+
+ if (mConfig != null) {
+ try {
+ mConfig.getInteger(PROP_NUM_IDS, MAX_PURPOSE_ID);
+ } catch (EBaseException e) {
+ }
+ }
+ for (int i = 0; i < mNum; i++) {
+ v.addElement(PROP_PURPOSE_ID + Integer.toString(i) + ";string;" +
+ "A unique,valid OID specified in dot-separated numeric component notation. e.g. 2.16.840.1.113730.1.99");
+ }
+
+ v.addElement(PROP_NUM_IDS + ";number;The total number of policy IDs.");
+ v.addElement(PROP_CRITICAL +
+ ";boolean;RFC 2459 recommendation: This extension may, at the option of the certificate issuer, be either critical or non-critical.");
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-extendedkeyusage");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Extended Key Usage Extension. Defined in RFC 2459 " +
+ "(4.2.1.13)");
+
+ mParams = com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ if (mParams == null) {
+ setExtendedPluginInfo();
+ }
+ return mParams;
+ }
+
+ /**
+ * Returns default parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_NUM_IDS + "=" + MAX_PURPOSE_ID);
+ for (int i = 0; i < MAX_PURPOSE_ID; i++) {
+ defParams.addElement(PROP_PURPOSE_ID + Integer.toString(i) + "=");
+ }
+ return defParams;
+ }
+
+ /**
+ * Setups parameters.
+ */
+ private void setupParams() throws EBaseException {
+
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, false);
+ if (mUsages == null) {
+ mUsages = new Vector();
+ }
+
+ int mNum = mConfig.getInteger(PROP_NUM_IDS, MAX_PURPOSE_ID);
+
+ for (int i = 0; i < mNum; i++) {
+ ObjectIdentifier usageOID = null;
+
+ String usage = mConfig.getString(PROP_PURPOSE_ID +
+ Integer.toString(i), null);
+
+ try {
+
+ if (usage == null) break;
+ usage = usage.trim();
+ if (usage.equals("")) break;
+ if (usage.equalsIgnoreCase("ocspsigning")) {
+ usageOID = ObjectIdentifier.getObjectIdentifier(ExtendedKeyUsageExtension.OID_OCSPSigning);
+ } else if (usage.equalsIgnoreCase("codesigning")) {
+ usageOID = ObjectIdentifier.getObjectIdentifier(ExtendedKeyUsageExtension.OID_CODESigning);
+ } else {
+ // it could be an object identifier, test it
+ usageOID = ObjectIdentifier.getObjectIdentifier(usage);
+ }
+ } catch (IOException ex) {
+ throw new EBaseException(this.getClass().getName() + ":" +
+ ex.getMessage());
+ } catch (NumberFormatException ex) {
+ throw new EBaseException(this.getClass().getName() + ":" +
+ "OID '" + usage + "' format error");
+ }
+ mUsages.addElement(usageOID);
+ }
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java b/pki/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java
new file mode 100644
index 000000000..9a07cb020
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/GenericASN1Ext.java
@@ -0,0 +1,471 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.text.ParseException;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.ldap.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Private Integer extension policy.
+ * If this policy is enabled, it adds an Private Integer
+ * extension to the certificate.
+ *
+ * The following listed sample configuration parameters:
+ *
+ * ca.Policy.impl.privateInteger.class=com.netscape.certsrv.policy.genericASNExt
+ * ca.Policy.rule.genericASNExt.enable=true
+ * ca.Policy.rule.genericASNExt.name=myIntegerExtension
+ * ca.Policy.rule.genericASNExt.pattern={{{12}34}5}
+ * ca.Policy.rule.genericASNExt.oid=280.230.123.1234.1
+ * ca.Policy.rule.genericASNExt.critical=false
+ * ca.Policy.rule.genericASNExt.attribute1.type=integer
+ * ca.Policy.rule.genericASNExt.attribute1.source=value
+ * ca.Policy.rule.genericASNExt.attribute1.value=9999
+ * ca.Policy.rule.genericASNExt.attribute2.type=ia5string
+ * ca.Policy.rule.genericASNExt.attribute2.source=value
+ * ca.Policy.rule.genericASNExt.attribute2.value=hello
+ * ca.Policy.rule.genericASNExt.attribute3.type=octetstring
+ * ca.Policy.rule.genericASNExt.attribute3.source=value
+ * ca.Policy.rule.genericASNExt.attribute3.value=hellohello
+ * ca.Policy.rule.genericASNExt.attribute4.type=octetstring
+ * ca.Policy.rule.genericASNExt.attribute4.source=file
+ * ca.Policy.rule.genericASNExt.attribute4.value=c:/tmp/test.txt
+ * ca.Policy.rule.genericASNExt.attribute5.type=
+ * ca.Policy.rule.genericASNExt.attribute5.source=
+ * ca.Policy.rule.genericASNExt.attribute5.value=
+ * ca.Policy.rule.genericASNExt.implName=genericASNExt
+ * ca.Policy.rule.genericASNExt.predicate=
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class GenericASN1Ext extends APolicyRule implements
+ IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final int MAX_ATTR = 10;
+
+ protected static final String PROP_CRITICAL =
+ "critical";
+ protected static final String PROP_NAME =
+ "name";
+ protected static final String PROP_OID =
+ "oid";
+ protected static final String PROP_PATTERN =
+ "pattern";
+ protected static final String PROP_ATTRIBUTE =
+ "attribute";
+ protected static final String PROP_TYPE =
+ "type";
+ protected static final String PROP_SOURCE =
+ "source";
+ protected static final String PROP_VALUE =
+ "value";
+ protected static final String PROP_PREDICATE =
+ "predicate";
+
+ protected static final String PROP_ENABLE =
+ "enable";
+
+ public IConfigStore mConfig = null;
+
+ private String pattern = null;
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String s[] = {
+ "enable" + ";boolean;Enable this policy",
+ "predicate" + ";string;",
+ PROP_CRITICAL + ";boolean;",
+ PROP_NAME + ";string;Name for this extension.",
+ PROP_OID + ";string;OID number for this extension. It should be unique.",
+ PROP_PATTERN + ";string;Pattern for extension; {012}34",
+ // Attribute 0
+ PROP_ATTRIBUTE + "." + "0" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "0" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "0" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 1
+ PROP_ATTRIBUTE + "." + "1" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "1" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "1" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 2
+ PROP_ATTRIBUTE + "." + "2" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "2" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "2" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 3
+ PROP_ATTRIBUTE + "." + "3" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "3" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "3" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 4
+ PROP_ATTRIBUTE + "." + "4" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "4" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "4" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 5
+ PROP_ATTRIBUTE + "." + "5" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "5" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "5" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 6
+ PROP_ATTRIBUTE + "." + "6" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "6" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "6" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 7
+ PROP_ATTRIBUTE + "." + "7" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "7" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "7" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 8
+ PROP_ATTRIBUTE + "." + "8" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "8" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "8" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ // Attribute 9
+ PROP_ATTRIBUTE + "." + "9" + "." + PROP_TYPE + ";choice(Integer,IA5String,OctetString,PrintableString,VisibleString,UTCTime,OID,Boolean);Attribute type for extension",
+ PROP_ATTRIBUTE + "." + "9" + "." + PROP_SOURCE + ";choice(Value,File);Data Source for the extension. You can specify the value here or file name has value.",
+ PROP_ATTRIBUTE + "." + "9" + "." + PROP_VALUE + ";string;If data source is 'value', specity value here. If data source is 'file', specify the file name with full path.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-genericasn1ext",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Private extension based on ASN1. See manual"
+ };
+
+ return s;
+ }
+
+ public GenericASN1Ext() {
+ NAME = "GenericASN1Ext";
+ DESC = "Sets Generic extension for certificates";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=genericASNExt
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.predicate=
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+ if (mConfig == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_INIT_ERROR"));
+ return;
+ }
+
+ boolean enable = mConfig.getBoolean(PROP_ENABLE, false);
+
+ if (enable == false)
+ return;
+
+ String oid = mConfig.getString(PROP_OID, null);
+
+ if ((oid == null) || (oid.length() == 0)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_INIT_ERROR"));
+ return;
+ }
+
+ String name = mConfig.getString(PROP_NAME, null);
+
+ if ((name == null) || (name.length() == 0)) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_INIT_ERROR"));
+ return;
+ }
+
+ try {
+ if (File.separatorChar == '\\') {
+ pattern = mConfig.getString(PROP_PATTERN, null);
+ checkFilename(0);
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, "" + e.toString());
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, "" + e.toString());
+ }
+
+ // Check OID value
+ CMS.checkOID(name, oid);
+ pattern = mConfig.getString(PROP_PATTERN, null);
+ checkOID(0);
+
+ try {
+ ObjectIdentifier tmpid = new ObjectIdentifier(oid);
+
+ if (OIDMap.getName(tmpid) == null)
+ OIDMap.addAttribute("netscape.security.extensions.GenericASN1Extension", oid, name);
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, "" + e.toString());
+ }
+
+ }
+
+ // Check filename
+ private int checkFilename(int index)
+ throws IOException, EBaseException {
+ String source = null;
+
+ while (index < pattern.length()) {
+ char ch = pattern.charAt(index);
+
+ switch (ch) {
+ case '{':
+ index++;
+ index = checkFilename(index);
+ break;
+
+ case '}':
+ return index;
+
+ default:
+ source = mConfig.getString(PROP_ATTRIBUTE + "." + ch + "." + PROP_SOURCE, null);
+ if ((source != null) && (source.equalsIgnoreCase("file"))) {
+ String oValue = mConfig.getString(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE, null);
+ String nValue = oValue.replace('\\', '/');
+
+ mConfig.putString(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE, nValue);
+ FileInputStream fis = new FileInputStream(nValue);
+ fis.close();
+ }
+ }
+ index++;
+ }
+
+ return index;
+ }
+
+ // Check oid
+ private int checkOID(int index)
+ throws EBaseException {
+ String type = null;
+ String oid = null;
+
+ while (index < pattern.length()) {
+ char ch = pattern.charAt(index);
+
+ switch (ch) {
+ case '{':
+ index++;
+ index = checkOID(index);
+ break;
+
+ case '}':
+ return index;
+
+ default:
+ type = mConfig.getString(PROP_ATTRIBUTE + "." + ch + "." + PROP_TYPE, null);
+ if ((type != null) && (type.equalsIgnoreCase("OID"))) {
+ oid = mConfig.getString(PROP_ATTRIBUTE + "." + ch + "." + PROP_VALUE, null);
+ CMS.checkOID(oid, oid);
+ }
+ }
+ index++;
+ }
+
+ return index;
+ }
+
+ /**
+ * If this policy is enabled, add the private Integer
+ * information extension to the certificate.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+ X509CertInfo certInfo;
+ X509CertInfo[] ci = req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int j = 0; j < ci.length; j++) {
+
+ certInfo = ci[j];
+ if (certInfo == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", ""));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME, "Configuration Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ try {
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions) certInfo.get(X509CertInfo.EXTENSIONS);
+
+ if (extensions == null) {
+ // create extension if not exist
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ //
+ // Remove any previousely computed extension
+ //
+ try {
+ extensions.delete(mConfig.getString(PROP_NAME, ""));
+ } catch (Exception e) {/* extension isn't there */
+ }
+ }
+
+ // Create the extension
+ GenericASN1Extension priExt = mkExtension();
+
+ extensions.set(GenericASN1Extension.NAME, priExt);
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Configuration Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (ParseException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_EXTENSION_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Pattern parsing error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_UNKNOWN_EXCEPTION", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Unknown Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+ return res;
+ }
+
+ /**
+ * Construct GenericASN1Extension with value from CMS.cfg
+ */
+ protected GenericASN1Extension mkExtension()
+ throws IOException, EBaseException, ParseException {
+ GenericASN1Extension ext;
+
+ Hashtable h = new Hashtable();
+ // This only show one level, not substores!
+ Enumeration e = mConfig.getPropertyNames();
+
+ while (e.hasMoreElements()) {
+ String n = (String) e.nextElement();
+
+ h.put(n, mConfig.getString(n));
+ }
+ for (int idx = 0; idx < MAX_ATTR; idx++) {
+ String proptype = PROP_ATTRIBUTE + "." + idx + "." + PROP_TYPE;
+ String propsource = PROP_ATTRIBUTE + "." + idx + "." + PROP_SOURCE;
+ String propvalue = PROP_ATTRIBUTE + "." + idx + "." + PROP_VALUE;
+
+ h.put(proptype, mConfig.getString(proptype, null));
+ h.put(propsource, mConfig.getString(propsource, null));
+ h.put(propvalue, mConfig.getString(propvalue, null));
+ }
+ ext = new GenericASN1Extension(h);
+ return ext;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ int idx = 0;
+ Vector params = new Vector();
+
+ try {
+ params.addElement(PROP_CRITICAL + "=" + mConfig.getBoolean(PROP_CRITICAL, false));
+ params.addElement(PROP_NAME + "=" + mConfig.getString(PROP_NAME, null));
+ params.addElement(PROP_OID + "=" + mConfig.getString(PROP_OID, null));
+ params.addElement(PROP_PATTERN + "=" + mConfig.getString(PROP_PATTERN, null));
+
+ for (idx = 0; idx < MAX_ATTR; idx++) {
+ String proptype = PROP_ATTRIBUTE + "." + idx + "." + PROP_TYPE;
+ String propsource = PROP_ATTRIBUTE + "." + idx + "." + PROP_SOURCE;
+ String propvalue = PROP_ATTRIBUTE + "." + idx + "." + PROP_VALUE;
+
+ params.addElement(proptype + "=" + mConfig.getString(proptype, null));
+ params.addElement(propsource + "=" + mConfig.getString(propsource, null));
+ params.addElement(propvalue + "=" + mConfig.getString(propvalue, null));
+ }
+ params.addElement(PROP_PREDICATE + "=" + mConfig.getString(PROP_PREDICATE, null));
+ } catch (EBaseException e) {;
+ }
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ int idx = 0;
+
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_NAME + "=");
+ defParams.addElement(PROP_OID + "=");
+ defParams.addElement(PROP_PATTERN + "=");
+
+ for (idx = 0; idx < MAX_ATTR; idx++) {
+ defParams.addElement(PROP_ATTRIBUTE + "." + idx + "." + PROP_TYPE + "=");
+ defParams.addElement(PROP_ATTRIBUTE + "." + idx + "." + PROP_SOURCE + "=");
+ defParams.addElement(PROP_ATTRIBUTE + "." + idx + "." + PROP_VALUE + "=");
+ }
+
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java
new file mode 100644
index 000000000..240076c95
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/IssuerAltNameExt.java
@@ -0,0 +1,252 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.net.*;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.ldap.*;
+import com.netscape.certsrv.ra.*;
+import com.netscape.certsrv.ca.*;
+import java.util.StringTokenizer;
+import netscape.security.util.DerValue;
+import java.util.Enumeration;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Issuer Alt Name Extension policy.
+ *
+ * This extension is used to associate Internet-style identities
+ * with the Certificate issuer.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class IssuerAltNameExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ public static final String PROP_CRITICAL = "critical";
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ private static Vector defaultParams = new Vector();
+ private static String[] mInfo = null;
+
+ static {
+ defaultParams.addElement(PROP_CRITICAL + "=" + DEFAULT_CRITICALITY);
+ CMS.getGeneralNamesConfigDefaultParams(null, true, defaultParams);
+
+ Vector info = new Vector();
+
+ info.addElement(PROP_CRITICAL + ";boolean;RFC 2459 recommendation: SHOULD NOT be marked critical.");
+ info.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-issueraltname");
+ info.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";This policy inserts the Issuer Alternative Name " +
+ "Extension into the certificate. See RFC 2459 (4.2.1.8). ");
+
+ CMS.getGeneralNamesConfigExtendedPluginInfo(null, true, info);
+
+ mInfo = new String[info.size()];
+ info.copyInto(mInfo);
+ }
+
+ private Vector mParams = new Vector();
+ private IConfigStore mConfig = null;
+ private boolean mCritical = DEFAULT_CRITICALITY;
+ private boolean mEnabled = false;
+ IGeneralNamesConfig mGNs = null;
+ IssuerAlternativeNameExtension mExtension = null;
+
+ /**
+ * Adds the issuer alternate name extension to all certs.
+ */
+ public IssuerAltNameExt() {
+ NAME = "IssuerAltNameExt";
+ DESC = "Associate Internet-style Identities with Issuer";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // get criticality
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEFAULT_CRITICALITY);
+
+ // get enabled.
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+
+ // form general names.
+ mGNs = CMS.createGeneralNamesConfig(null, config, true, mEnabled);
+
+ // form extension
+ try {
+ if (mEnabled &&
+ mGNs.getGeneralNames() != null && !mGNs.getGeneralNames().isEmpty()) {
+ mExtension =
+ new IssuerAlternativeNameExtension(
+ Boolean.valueOf(mCritical), mGNs.getGeneralNames());
+ }
+ } catch (Exception e) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR", e.toString()));
+ }
+
+ // init instance params
+ mParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mGNs.getInstanceParams(mParams);
+
+ return;
+ }
+
+ /**
+ * Adds a extension if none exists.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ if (mEnabled == false || mExtension == null)
+ return res;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ X509CertInfo certInfo = null;
+
+ if (ci == null || (certInfo = ci[0]) == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ // get extension from cert info if any.
+ CertificateExtensions extensions = null;
+
+ try {
+ // get extension if any.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ // no extensions.
+ } catch (CertificateException e) {
+ // no extension.
+ }
+
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ try {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (CertificateException e) {
+ // not possible
+ } catch (Exception e) {
+ }
+ } else {
+
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(IssuerAlternativeNameExtension.NAME);
+
+ } catch (IOException e) {
+ // this is the hack
+ // If name is not found, try deleting using the OID
+
+ try {
+ extensions.delete("2.5.29.18");
+ } catch (IOException ee) {
+ }
+ }
+ }
+
+ try {
+ extensions.set(IssuerAlternativeNameExtension.NAME, mExtension);
+ } catch (Exception e) {
+ if (e instanceof RuntimeException)
+ throw (RuntimeException) e;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("CRL_CREATE_ISSUER_ALT_NAME_EXT", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return Empty Vector since this policy has no configuration parameters.
+ * for this policy instance.
+ */
+ public Vector getInstanceParams() {
+ return mParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return Empty Vector since this policy implementation has no
+ * configuration parameters.
+ */
+ public Vector getDefaultParams() {
+ return defaultParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ return mInfo;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java
new file mode 100644
index 000000000..d824e452e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/KeyUsageExt.java
@@ -0,0 +1,351 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Policy to add Key Usage Extension.
+ * Adds the key usage extension based on what's requested.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class KeyUsageExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ private final static String HTTP_INPUT = "HTTP_INPUT";
+ protected static final boolean[] DEF_BITS =
+ new boolean[KeyUsageExtension.NBITS];
+ protected int mCAPathLen = -1;
+ protected IConfigStore mConfig = null;
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_DIGITAL_SIGNATURE = "digitalSignature";
+ protected static final String PROP_NON_REPUDIATION = "nonRepudiation";
+ protected static final String PROP_KEY_ENCIPHERMENT = "keyEncipherment";
+ protected static final String PROP_DATA_ENCIPHERMENT = "dataEncipherment";
+ protected static final String PROP_KEY_AGREEMENT = "keyAgreement";
+ protected static final String PROP_KEY_CERTSIGN = "keyCertsign";
+ protected static final String PROP_CRL_SIGN = "crlSign";
+ protected static final String PROP_ENCIPHER_ONLY = "encipherOnly";
+ protected static final String PROP_DECIPHER_ONLY = "decipherOnly";
+
+ protected boolean mCritical;
+ protected String mDigitalSignature;
+ protected String mNonRepudiation;
+ protected String mKeyEncipherment;
+ protected String mDataEncipherment;
+ protected String mKeyAgreement;
+ protected String mKeyCertsign;
+ protected String mCrlSign;
+ protected String mEncipherOnly;
+ protected String mDecipherOnly;
+
+ protected KeyUsageExtension mKeyUsage;
+
+ public KeyUsageExt() {
+ NAME = "KeyUsageExtPolicy";
+ DESC = "Sets Key Usage Extension in certificates.";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=KeyUsageExt
+ * ca.Policy.rule.<ruleName>.enable=true
+ * ca.Policy.rule.<ruleName>.
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CANT_FIND_MANAGER"));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Cannot find the Certificate Manager or Registration Manager"));
+ }
+
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, true);
+ mDigitalSignature = mConfig.getString(PROP_DIGITAL_SIGNATURE, HTTP_INPUT);
+ mNonRepudiation = mConfig.getString(PROP_NON_REPUDIATION, HTTP_INPUT);
+ mKeyEncipherment = mConfig.getString(PROP_KEY_ENCIPHERMENT, HTTP_INPUT);
+ mDataEncipherment = mConfig.getString(PROP_DATA_ENCIPHERMENT, HTTP_INPUT);
+ mKeyAgreement = mConfig.getString(PROP_KEY_AGREEMENT, HTTP_INPUT);
+ mKeyCertsign = mConfig.getString(PROP_KEY_CERTSIGN, HTTP_INPUT);
+ mCrlSign = mConfig.getString(PROP_CRL_SIGN, HTTP_INPUT);
+ mEncipherOnly = mConfig.getString(PROP_ENCIPHER_ONLY, HTTP_INPUT);
+ mDecipherOnly = mConfig.getString(PROP_DECIPHER_ONLY, HTTP_INPUT);
+ }
+
+ /**
+ * Adds the key usage extension if not set already.
+ * (CRMF, agent, authentication (currently) or PKCS#10 (future)
+ * or RA could have set the extension.)
+ * If not set, set from http input parameters or use default if
+ * no http input parameters are set.
+ *
+ * Note: this allows any bits requested - does not check if user
+ * authenticated is allowed to have a Key Usage Extension with
+ * those bits. Unless the CA's certificate path length is 0, then
+ * we do not allow CA sign or CRL sign bits in any request.
+ *
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ try {
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ KeyUsageExtension ext = null;
+
+ if (extensions != null) {
+ try {
+ ext = (KeyUsageExtension)
+ extensions.get(KeyUsageExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there.
+ ext = null;
+ }
+ // check if CA does not allow subordinate CA certs.
+ // otherwise accept existing key usage extension.
+ if (ext != null) {
+ if (mCAPathLen == 0) {
+ boolean[] bits = ext.getBits();
+
+ if ((bits.length > KeyUsageExtension.KEY_CERTSIGN_BIT &&
+ bits[KeyUsageExtension.KEY_CERTSIGN_BIT] == true) ||
+ (bits.length > KeyUsageExtension.CRL_SIGN_BIT &&
+ bits[KeyUsageExtension.CRL_SIGN_BIT] == true)) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_NO_SUB_CA_CERTS_ALLOWED"),
+ NAME);
+ return PolicyResult.REJECTED;
+ }
+ }
+ return PolicyResult.ACCEPTED;
+ }
+ } else {
+ // create extensions set if none.
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ }
+
+ boolean[] bits = new boolean[KeyUsageExtension.NBITS];
+
+ bits[KeyUsageExtension.DIGITAL_SIGNATURE_BIT] = getBit("digital_signature",
+ mDigitalSignature, req);
+ bits[KeyUsageExtension.NON_REPUDIATION_BIT] = getBit("non_repudiation",
+ mNonRepudiation, req);
+ bits[KeyUsageExtension.KEY_ENCIPHERMENT_BIT] = getBit("key_encipherment",
+ mKeyEncipherment, req);
+ bits[KeyUsageExtension.DATA_ENCIPHERMENT_BIT] = getBit("data_encipherment",
+ mDataEncipherment, req);
+ bits[KeyUsageExtension.KEY_AGREEMENT_BIT] = getBit("key_agreement",
+ mKeyAgreement, req);
+ bits[KeyUsageExtension.KEY_CERTSIGN_BIT] = getBit("key_certsign",
+ mKeyCertsign, req);
+ bits[KeyUsageExtension.CRL_SIGN_BIT] = getBit("crl_sign", mCrlSign, req);
+ bits[KeyUsageExtension.ENCIPHER_ONLY_BIT] = getBit("encipher_only",
+ mEncipherOnly, req);
+ bits[KeyUsageExtension.DECIPHER_ONLY_BIT] = getBit("decipher_only",
+ mDecipherOnly, req);
+
+ // don't allow no bits set or the extension does not
+ // encode/decode properlly.
+ boolean bitset = false;
+
+ for (int i = 0; i < bits.length; i++) {
+ if (bits[i]) {
+ bitset = true;
+ break;
+ }
+ }
+ if (!bitset) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_NO_KEYUSAGE_EXTENSION_BITS_SET", NAME));
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_KEYUSAGE_EXTENSION_BITS_SET"),
+ NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ // create the extension.
+ try {
+ mKeyUsage = new KeyUsageExtension(mCritical, bits);
+ } catch (IOException e) {
+ }
+ extensions.set(KeyUsageExtension.NAME, mKeyUsage);
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_DIGITAL_SIGNATURE + "=" + mDigitalSignature);
+ params.addElement(PROP_NON_REPUDIATION + "=" + mNonRepudiation);
+ params.addElement(PROP_KEY_ENCIPHERMENT + "=" + mKeyEncipherment);
+ params.addElement(PROP_DATA_ENCIPHERMENT + "=" + mDataEncipherment);
+ params.addElement(PROP_KEY_AGREEMENT + "=" + mKeyAgreement);
+ params.addElement(PROP_KEY_CERTSIGN + "=" + mKeyCertsign);
+ params.addElement(PROP_CRL_SIGN + "=" + mCrlSign);
+ params.addElement(PROP_ENCIPHER_ONLY + "=" + mEncipherOnly);
+ params.addElement(PROP_DECIPHER_ONLY + "=" + mDecipherOnly);
+ return params;
+ }
+
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(PROP_CRITICAL + "=true");
+ mDefParams.addElement(PROP_DIGITAL_SIGNATURE + "=");
+ mDefParams.addElement(PROP_NON_REPUDIATION + "=");
+ mDefParams.addElement(PROP_KEY_ENCIPHERMENT + "=");
+ mDefParams.addElement(PROP_DATA_ENCIPHERMENT + "=");
+ mDefParams.addElement(PROP_KEY_AGREEMENT + "=");
+ mDefParams.addElement(PROP_KEY_CERTSIGN + "=");
+ mDefParams.addElement(PROP_CRL_SIGN + "=");
+ mDefParams.addElement(PROP_ENCIPHER_ONLY + "=");
+ mDefParams.addElement(PROP_DECIPHER_ONLY + "=");
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2459 recommendation: SHOULD be critical",
+ PROP_DIGITAL_SIGNATURE + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_NON_REPUDIATION + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_KEY_ENCIPHERMENT + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_DATA_ENCIPHERMENT + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_KEY_AGREEMENT + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_KEY_CERTSIGN + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_CRL_SIGN + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_ENCIPHER_ONLY + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ PROP_DECIPHER_ONLY + ";choice(true,false,HTTP_INPUT);true means always set this bit, false means don't set this bit, HTTP_INPUT means get this bit from the HTTP input",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-keyusage",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Key Usage Extension; See in RFC 2459 (4.2.1.3)"
+
+ };
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ private boolean getBit(String usage, String choice, IRequest req) {
+ if (choice.equals(HTTP_INPUT)) {
+ choice = req.getExtDataInString(IRequest.HTTP_PARAMS, usage);
+ if (choice == null)
+ choice = "false";
+ }
+ return Boolean.valueOf(choice).booleanValue();
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java
new file mode 100644
index 000000000..05a17cfcd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/NSCCommentExt.java
@@ -0,0 +1,288 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.util.*;
+import netscape.security.x509.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Netscape comment
+ * Adds Netscape comment policy
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class NSCCommentExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ protected static final String PROP_USER_NOTICE_DISPLAY_TEXT = "displayText";
+ protected static final String PROP_COMMENT_FILE = "commentFile";
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_INPUT_TYPE = "inputType";
+ protected static final String TEXT = "Text";
+ protected static final String FILE = "File";
+
+ protected String mUserNoticeDisplayText;
+ protected String mCommentFile;
+ protected String mInputType;
+ protected boolean mCritical;
+ private Vector mParams = new Vector();
+
+ protected String tempCommentFile;
+ protected boolean certApplied = false;
+
+ /**
+ * Adds the Netscape comment in the end-entity certificates or
+ * CA certificates. The policy is set to be non-critical with the
+ * provided OID.
+ */
+ public NSCCommentExt() {
+ NAME = "NSCCommentExt";
+ DESC = "Sets non-critical Netscape Comment extension in certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <p>
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.implName=NSCCommentExtImpl
+ * ca.Policy.rule.<ruleName>.displayText=<n>
+ * ca.Policy.rule.<ruleName>.commentFile=<n>
+ * ca.Policy.rule.<ruleName>.enable=false
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+ FileInputStream fileStream = null;
+
+ try {
+ mCritical = config.getBoolean(PROP_CRITICAL, false);
+ mParams.addElement(PROP_CRITICAL + "=" + mCritical);
+
+ mInputType = config.getString(PROP_INPUT_TYPE, null);
+ mParams.addElement(PROP_INPUT_TYPE + "=" + mInputType);
+
+ mUserNoticeDisplayText = config.getString(PROP_USER_NOTICE_DISPLAY_TEXT, "");
+ mParams.addElement(PROP_USER_NOTICE_DISPLAY_TEXT + "=" + mUserNoticeDisplayText);
+
+ tempCommentFile = config.getString(PROP_COMMENT_FILE, "");
+
+ boolean enable = config.getBoolean(PROP_ENABLE, false);
+
+ if ((enable == true)) {
+
+ if (mInputType.equals("File")) {
+ if (tempCommentFile.equals(""))
+ throw new Exception("No file name provided");
+
+ fileStream = new FileInputStream(tempCommentFile);
+ fileStream.close();
+ }
+ }
+
+ if (tempCommentFile.equals(""))
+ mCommentFile = "";
+ else
+ mCommentFile = tempCommentFile.replace('\\', '/');
+
+ config.putString(PROP_COMMENT_FILE, mCommentFile);
+
+ mParams.addElement(PROP_COMMENT_FILE + "=" + mCommentFile);
+ } catch (FileNotFoundException e) {
+ Object[] params = {getInstanceName(), "File not found : " + tempCommentFile};
+
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG"), params);
+ } catch (Exception e) {
+ Object[] params = {getInstanceName(), e.getMessage()};
+
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG"), params);
+ }
+ }
+
+ /**
+ * Applies the policy on the given Request.
+ * <p>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult r = applyCert(req, ci[i]);
+
+ if (r == PolicyResult.REJECTED)
+ return r;
+ }
+ return res;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ certApplied = false;
+ CertificateExtensions extensions = null;
+
+ try {
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ } catch (CertificateException e) {
+ }
+
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ try {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } catch (Exception e) {
+ }
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(NSCCommentExtension.NAME);
+
+ } catch (IOException e) {
+ // this is the hack: for some reason, the key which is the name
+ // of the policy has been converted into the OID
+ try {
+ extensions.delete("2.16.840.1.113730.1.13");
+ } catch (IOException ee) {
+ }
+ }
+ }
+ if (mInputType.equals("File")) {
+ // if ((mUserNoticeDisplayText.equals("")) && !(mCommentFile.equals(""))) {
+ try {
+ // Read the comments file
+ BufferedReader fis = new BufferedReader(new FileReader(mCommentFile));
+
+ String line = null;
+ StringBuffer buffer = new StringBuffer();
+
+ while ((line = fis.readLine()) != null)
+ buffer.append(line);
+ mUserNoticeDisplayText = new String(buffer);
+ fis.close();
+ } catch (IOException e) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, " Comment Text file not found : " + mCommentFile);
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_COMMENT_FILE_NOT_FOUND", e.toString()));
+ return PolicyResult.REJECTED;
+
+ }
+
+ }
+
+ certApplied = true;
+
+ DisplayText displayText =
+ new DisplayText(DisplayText.tag_IA5String, mUserNoticeDisplayText);
+
+ try {
+ NSCCommentExtension cpExt =
+ new NSCCommentExtension(mCritical, mUserNoticeDisplayText);
+
+ extensions.set(NSCCommentExtension.NAME, cpExt);
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CERTIFICATE_POLICIES_1", NAME));
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_CERTIFICATE_POLICIES_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;Netscape recommendation: non-critical.",
+ PROP_INPUT_TYPE + ";choice(Text,File);Whether the comments " +
+ "would be entered in the displayText field or come from " +
+ "a file.",
+ PROP_USER_NOTICE_DISPLAY_TEXT + ";string;The comment that may be " +
+ "displayed to the user when the certificate is viewed.",
+ PROP_COMMENT_FILE + ";string; If data source is 'File', specify " +
+ "the file name with full path.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-nsccomment",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds 'netscape comment' extension. See manual"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ defParams.addElement(PROP_INPUT_TYPE + "=" + TEXT);
+ defParams.addElement(PROP_USER_NOTICE_DISPLAY_TEXT + "=");
+ defParams.addElement(PROP_COMMENT_FILE + "=");
+ return defParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java
new file mode 100644
index 000000000..5fa6bae9c
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/NSCertTypeExt.java
@@ -0,0 +1,541 @@
+// --- 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.policy.extensions;
+
+
+import java.io.IOException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Locale;
+import java.util.Vector;
+
+import netscape.security.extensions.NSCertTypeExtension;
+import netscape.security.x509.CertificateChain;
+import netscape.security.x509.CertificateExtensions;
+import netscape.security.x509.CertificateVersion;
+import netscape.security.x509.KeyUsageExtension;
+import netscape.security.x509.X509CertInfo;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.AuthToken;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authority.ICertAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.IExtendedPluginInfo;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ca.ICertificateAuthority;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.policy.IEnrollmentPolicy;
+import com.netscape.certsrv.policy.IPolicyProcessor;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * NS Cert Type policy.
+ * Adds the ns cert type extension depending on cert type requested.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class NSCertTypeExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_SET_DEFAULT_BITS = "setDefaultBits";
+ protected static final boolean DEF_SET_DEFAULT_BITS = true;
+ protected static final String DEF_SET_DEFAULT_BITS_VAL =
+ Boolean.valueOf(DEF_SET_DEFAULT_BITS).toString();
+
+ protected static final int DEF_PATHLEN = -1;
+
+ protected static final boolean[] DEF_BITS =
+ new boolean[NSCertTypeExtension.NBITS];
+
+ // XXX for future use. currenlty always allow.
+ protected static final String PROP_AGENT_OVERR = "allowAgentOverride";
+ protected static final String PROP_EE_OVERR = "AllowEEOverride";
+
+ // XXX for future use. currently always critical
+ // (standard says SHOULD be marked critical if included.)
+ protected static final String PROP_CRITICAL = "critical";
+
+ // XXX for future use to allow overrides from forms.
+ // request must be agent approved or authenticated.
+ protected boolean mAllowAgentOverride = false;
+ protected boolean mAllowEEOverride = false;
+
+ // XXX for future use. currently always non-critical
+ protected boolean mCritical = false;
+
+ protected int mCAPathLen = -1;
+
+ protected IConfigStore mConfig = null;
+ protected boolean mSetDefaultBits = false;
+
+ static {
+ // set default bits used when request missing ns cert type info.
+ // default is a client cert
+ DEF_BITS[NSCertTypeExtension.SSL_CLIENT_BIT] = true;
+ DEF_BITS[NSCertTypeExtension.SSL_SERVER_BIT] = false;
+ DEF_BITS[NSCertTypeExtension.EMAIL_BIT] = true;
+ DEF_BITS[NSCertTypeExtension.OBJECT_SIGNING_BIT] = true;
+ DEF_BITS[NSCertTypeExtension.SSL_CA_BIT] = false;
+ DEF_BITS[NSCertTypeExtension.EMAIL_CA_BIT] = false;
+ DEF_BITS[NSCertTypeExtension.OBJECT_SIGNING_CA_BIT] = false;
+ }
+
+ public NSCertTypeExt() {
+ NAME = "NSCertType";
+ DESC = "Sets Netscape Cert Type on all certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=nsCertTypeExt
+ * ra.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // XXX future use.
+ //mAllowAgentOverride = config.getBoolean(PROP_AGENT_OVERR, false);
+ //mAllowEEOverride = config.getBoolean(PROP_EE_OVERR, false);
+ mCritical = config.getBoolean(PROP_CRITICAL, false);
+
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor) owner).getAuthority();
+
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ if (caCert != null)
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+
+ mSetDefaultBits = mConfig.getBoolean(
+ PROP_SET_DEFAULT_BITS, DEF_SET_DEFAULT_BITS);
+ }
+
+ /**
+ * Adds the ns cert type if not set already.
+ * reads ns cert type choices from form. If no choices from form
+ * will defaults to all.
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ CMS.debug("NSCertTypeExt: Impl: " + NAME + ", Instance: " + getInstanceName() + "::apply()");
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ X509CertInfo certInfo = null;
+
+ if (ci == null || (certInfo = ci[0]) == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ try {
+ String certType =
+ req.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ NSCertTypeExtension nsCertTypeExt = null;
+
+ if (extensions != null) {
+ // See if extension is already set and contains correct values.
+ try {
+ nsCertTypeExt = (NSCertTypeExtension)
+ extensions.get(NSCertTypeExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there.
+ nsCertTypeExt = null;
+ }
+ // XXX agent servlet currently sets this. it should be
+ // delayed to here.
+ if (nsCertTypeExt != null &&
+ extensionIsGood(nsCertTypeExt, req)) {
+ CMS.debug(
+ "NSCertTypeExt: already has correct ns cert type ext");
+ return PolicyResult.ACCEPTED;
+ } else if ((nsCertTypeExt != null) &&
+ (certType.equals("ocspResponder"))) {
+ // Fix for #528732 : Always delete
+ // this extension from OCSP signing cert
+ extensions.delete(NSCertTypeExtension.NAME);
+ return PolicyResult.ACCEPTED;
+ }
+ } else {
+ // create extensions set if none.
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ CMS.debug(
+ "NSCertTypeExt: Created extensions for adding ns cert type..");
+ }
+ }
+ // add ns cert type extension if not set or not set correctly.
+ boolean[] bits = null;
+
+ bits = getBitsFromRequest(req, mSetDefaultBits);
+
+ // check if ca doesn't allow any subordinate ca
+ if (mCAPathLen == 0 && bits != null) {
+ if (bits[NSCertTypeExtension.SSL_CA_BIT] ||
+ bits[NSCertTypeExtension.EMAIL_CA_BIT] ||
+ bits[NSCertTypeExtension.OBJECT_SIGNING_CA_BIT]) {
+ setError(req,
+ CMS.getUserMessage("CMS_POLICY_NO_SUB_CA_CERTS_ALLOWED"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ if (nsCertTypeExt != null) {
+ // replace with correct bits to comply to policy.
+ // take all that are true.
+ extensions.delete(NSCertTypeExtension.NAME);
+ }
+
+ int j;
+
+ for (j = 0; bits != null && j < bits.length; j++)
+ if (bits[j]) break;
+ if (bits == null || j == bits.length) {
+ if (!mSetDefaultBits) {
+ CMS.debug(
+ "NSCertTypeExt: no bits requested, not setting default.");
+ return PolicyResult.ACCEPTED;
+ } else
+ bits = DEF_BITS;
+ }
+
+ nsCertTypeExt = new NSCertTypeExtension(mCritical, bits);
+ extensions.set(NSCertTypeExtension.NAME, nsCertTypeExt);
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ /**
+ * check if ns cert type extension is set correctly,
+ * correct bits if not.
+ * if not authorized to set extension, bits will be replaced.
+ */
+ protected boolean extensionIsGood(
+ NSCertTypeExtension nsCertTypeExt, IRequest req)
+ throws IOException, CertificateException {
+ // always return false for now to make sure minimum is set.
+ // agents and ee can add others.
+
+ // must be agent approved or authenticated for allowing extensions
+ // which is always the case if we get to this point.
+ IAuthToken token = req.getExtDataInAuthToken(IRequest.AUTH_TOKEN);
+
+ if (!agentApproved(req) && token == null) {
+ // don't know where this came from.
+ // set all bits to false to reset.
+ CMS.debug(
+ "NSCertTypeExt: unknown origin: setting ns cert type bits to false");
+ boolean[] bits = new boolean[8];
+
+ for (int i = bits.length - 1; i >= 0; i--) {
+ nsCertTypeExt.set(i, false);
+ }
+ return false;
+ } else {
+ // check for min bits, set default if not there.
+ String certType = req.getExtDataInString(IRequest.HTTP_PARAMS,
+ IRequest.CERT_TYPE);
+
+ if ((certType != null) && certType.equals("ocspResponder")) {
+ return false;
+ }
+ if (certType == null || certType.length() == 0) {
+ // if don't know cert type let agent override anything.
+ return true;
+ }
+ if (certType.equals(IRequest.CA_CERT)) {
+ if (!nsCertTypeExt.isSet(NSCertTypeExtension.SSL_CA_BIT) &&
+ !nsCertTypeExt.isSet(NSCertTypeExtension.EMAIL_CA_BIT) &&
+ !nsCertTypeExt.isSet(
+ NSCertTypeExtension.OBJECT_SIGNING_CA_BIT)) {
+ // min not set so set all.
+ CMS.debug(
+ "NSCertTypeExt: is extension good: no ca bits set. set all");
+
+ nsCertTypeExt.set(NSCertTypeExtension.SSL_CA,
+ Boolean.valueOf(true));
+ nsCertTypeExt.set(NSCertTypeExtension.EMAIL_CA,
+ Boolean.valueOf(true));
+ nsCertTypeExt.set(NSCertTypeExtension.OBJECT_SIGNING_CA,
+ Boolean.valueOf(true));
+ }
+ return true;
+ } else if (certType.equals(IRequest.CLIENT_CERT)) {
+ if (!nsCertTypeExt.isSet(NSCertTypeExtension.SSL_CLIENT_BIT) &&
+ !nsCertTypeExt.isSet(NSCertTypeExtension.EMAIL_BIT) &&
+ !nsCertTypeExt.isSet(NSCertTypeExtension.SSL_SERVER_BIT) &&
+ !nsCertTypeExt.isSet(
+ NSCertTypeExtension.OBJECT_SIGNING_BIT)) {
+ // min not set so set all.
+ CMS.debug(
+ "NSCertTypeExt: is extension good: no cl bits set. set all");
+ nsCertTypeExt.set(NSCertTypeExtension.SSL_CLIENT,
+ new Boolean(true));
+ nsCertTypeExt.set(NSCertTypeExtension.EMAIL,
+ new Boolean(true));
+ nsCertTypeExt.set(NSCertTypeExtension.OBJECT_SIGNING,
+ new Boolean(true));
+ }
+ return true;
+ } else if (certType.equals(IRequest.SERVER_CERT)) {
+ // this bit must be true.
+ nsCertTypeExt.set(NSCertTypeExtension.SSL_SERVER_BIT, true);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets ns cert type bits from request.
+ * If none set, use cert type to determine correct bits.
+ * If no cert type, use default.
+ */
+
+ protected boolean[] getBitsFromRequest(IRequest req, boolean setDefault) {
+ boolean[] bits = null;
+
+ CMS.debug("NSCertTypeExt: ns cert type getting ns cert type vars");
+ bits = getNSCertTypeBits(req);
+ if (bits == null && setDefault) {
+ // no ns cert type bits set in request. go with cert type.
+ CMS.debug("NSCertTypeExt: ns cert type getting cert type vars");
+ bits = getCertTypeBits(req);
+
+ if (bits == null && setDefault) {
+ CMS.debug("NSCertTypeExt: ns cert type getting def bits");
+ bits = DEF_BITS;
+ }
+ }
+ return bits;
+ }
+
+ /**
+ * get ns cert type bits from actual sets in the request
+ */
+ protected boolean[] getNSCertTypeBits(IRequest req) {
+ boolean[] bits = new boolean[NSCertTypeExtension.NBITS];
+
+ bits[NSCertTypeExtension.SSL_CLIENT_BIT] =
+ // XXX should change this to is ns cert type ssl_client defn.
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.SSL_CLIENT, false);
+
+ bits[NSCertTypeExtension.SSL_SERVER_BIT] =
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.SSL_SERVER, false);
+
+ bits[NSCertTypeExtension.EMAIL_BIT] =
+ // XXX should change this to is ns cert type ssl_client defn.
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.EMAIL, false);
+
+ bits[NSCertTypeExtension.OBJECT_SIGNING_BIT] =
+ // XXX should change this to is ns cert type ssl_client defn.
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.OBJECT_SIGNING, false);
+
+ bits[NSCertTypeExtension.SSL_CA_BIT] =
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.SSL_CA, false);
+
+ bits[NSCertTypeExtension.EMAIL_CA_BIT] =
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.EMAIL_CA, false);
+
+ bits[NSCertTypeExtension.OBJECT_SIGNING_CA_BIT] =
+ req.getExtDataInBoolean(IRequest.HTTP_PARAMS,
+ NSCertTypeExtension.OBJECT_SIGNING_CA, false);
+
+ // if nothing set, return null.
+ int i;
+
+ for (i = bits.length - 1; i >= 0; i--) {
+ if (bits[i] == true) {
+ CMS.debug("NSCertTypeExt: bit " + i + " is set.");
+ break;
+ }
+ }
+ if (i < 0) {
+ // nothing was set.
+ CMS.debug("NSCertTypeExt: No bits were set.");
+ bits = null;
+ }
+ return bits;
+ }
+
+ /**
+ * get cert type bits according to cert type.
+ */
+ protected boolean[] getCertTypeBits(IRequest req) {
+ String certType =
+ req.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+
+ if (certType == null || certType.length() == 0)
+ return null;
+
+ boolean[] bits = new boolean[KeyUsageExtension.NBITS];
+
+ for (int i = bits.length - 1; i >= 0; i--)
+ bits[i] = false;
+
+ if (certType.equals(IRequest.CLIENT_CERT)) {
+ CMS.debug("NSCertTypeExt: setting bits for client cert");
+ // we can only guess here when it's client.
+ // sets all client bit for default.
+ bits[NSCertTypeExtension.SSL_CLIENT_BIT] = true;
+ bits[NSCertTypeExtension.EMAIL_BIT] = true;
+ //bits[NSCertTypeExtension.OBJECT_SIGNING_BIT] = true;
+ } else if (certType.equals(IRequest.SERVER_CERT)) {
+ CMS.debug("NSCertTypeExt: setting bits for server cert");
+ bits[NSCertTypeExtension.SSL_SERVER_BIT] = true;
+ } else if (certType.equals(IRequest.CA_CERT)) {
+ CMS.debug("NSCertType: setting bits for ca cert");
+ bits[NSCertTypeExtension.SSL_CA_BIT] = true;
+ bits[NSCertTypeExtension.EMAIL_CA_BIT] = true;
+ bits[NSCertTypeExtension.OBJECT_SIGNING_CA_BIT] = true;
+ } else if (certType.equals(IRequest.RA_CERT)) {
+ CMS.debug("NSCertType: setting bits for ra cert");
+ bits[NSCertTypeExtension.SSL_CLIENT_BIT] = true;
+ } else {
+ CMS.debug("NSCertTypeExt: no other cert bits set");
+ // return null to use default.
+ bits = DEF_BITS;
+ }
+ return bits;
+ }
+
+ /**
+ * merge bits with those set from form.
+ * make sure required minimum is set. Agent or auth can set others.
+ * XXX form shouldn't set the extension
+ */
+ public void mergeBits(NSCertTypeExtension nsCertTypeExt, boolean[] bits) {
+ for (int i = bits.length - 1; i >= 0; i--) {
+ if (bits[i] == true) {
+ CMS.debug("NSCertTypeExt: ns cert type merging bit " + i);
+ nsCertTypeExt.set(i, true);
+ }
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_SET_DEFAULT_BITS + "=" + mSetDefaultBits);
+ //new Boolean(mSetDefaultBits).toString());
+ return params;
+ }
+
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(
+ PROP_CRITICAL + "=false");
+ mDefParams.addElement(
+ PROP_SET_DEFAULT_BITS + "=" + DEF_SET_DEFAULT_BITS);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;Netscape recommendation: non-critical.",
+ PROP_SET_DEFAULT_BITS + ";boolean;Specify whether to set the Netscape certificate " +
+ "type extension with default bits ('ssl client' and 'email') in certificates " +
+ "specified by the predicate " +
+ "expression.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-nscerttype",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Netscape Certificate Type extension."
+ };
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java
new file mode 100644
index 000000000..b204e57b2
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/NameConstraintsExt.java
@@ -0,0 +1,468 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Name Constraints Extension Policy
+ * Adds the name constraints extension to a (CA) certificate.
+ * Filtering of CA certificates is done through predicates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class NameConstraintsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_NUM_PERMITTEDSUBTREES = "numPermittedSubtrees";
+ protected static final String PROP_NUM_EXCLUDEDSUBTREES = "numExcludedSubtrees";
+
+ protected static final String PROP_PERMITTEDSUBTREES = "permittedSubtrees";
+ protected static final String PROP_EXCLUDEDSUBTREES = "excludedSubtrees";
+
+ protected static final boolean DEF_CRITICAL = true;
+ protected static final int DEF_NUM_PERMITTEDSUBTREES = 8;
+ protected static final int DEF_NUM_EXCLUDEDSUBTREES = 8;
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mNumPermittedSubtrees = 0;
+ protected int mNumExcludedSubtrees = 0;
+ protected Subtree[] mPermittedSubtrees = null;
+ protected Subtree[] mExcludedSubtrees = null;
+ protected NameConstraintsExtension mNameConstraintsExtension = null;
+
+ protected Vector mInstanceParams = new Vector();
+
+ public NameConstraintsExt() {
+ NAME = "NameConstraintsExt";
+ DESC = "Sets Name Constraints Extension on subordinate CA certificates";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=certType==ca
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // XXX should do do this ?
+ // if CA does not allow subordinate CAs by way of basic constraints,
+ // this policy always rejects
+ /*****
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor)owner).getAuthority();
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ if (caCert != null)
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+ ****/
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+ mNumPermittedSubtrees = mConfig.getInteger(
+ PROP_NUM_PERMITTEDSUBTREES, DEF_NUM_PERMITTEDSUBTREES);
+ mNumExcludedSubtrees = mConfig.getInteger(
+ PROP_NUM_EXCLUDEDSUBTREES, DEF_NUM_EXCLUDEDSUBTREES);
+
+ if (mNumPermittedSubtrees < 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_NUM_PERMITTEDSUBTREES,
+ "value must be greater than or equal to 0"));
+ }
+ if (mNumExcludedSubtrees < 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_NUM_EXCLUDEDSUBTREES,
+ "value must be greater than or equal to 0"));
+ }
+
+ // init permitted subtrees if any.
+ if (mNumPermittedSubtrees > 0) {
+ mPermittedSubtrees =
+ form_subtrees(PROP_PERMITTEDSUBTREES, mNumPermittedSubtrees);
+ CMS.debug("NameConstraintsExt: formed permitted subtrees");
+ }
+
+ // init excluded subtrees if any.
+ if (mNumExcludedSubtrees > 0) {
+ mExcludedSubtrees =
+ form_subtrees(PROP_EXCLUDEDSUBTREES, mNumExcludedSubtrees);
+ CMS.debug("NameConstraintsExt: formed excluded subtrees");
+ }
+
+ // create instance of name constraints extension if enabled.
+ if (mEnabled) {
+ try {
+ Vector permittedSubtrees = new Vector();
+
+ for (int i = 0; i < mNumPermittedSubtrees; i++) {
+ permittedSubtrees.addElement(
+ mPermittedSubtrees[i].mGeneralSubtree);
+ }
+ Vector excludedSubtrees = new Vector();
+
+ for (int j = 0; j < mNumExcludedSubtrees; j++) {
+ excludedSubtrees.addElement(
+ mExcludedSubtrees[j].mGeneralSubtree);
+ }
+ GeneralSubtrees psb = null;
+
+ if (permittedSubtrees.size() > 0) {
+ psb = new GeneralSubtrees(permittedSubtrees);
+ }
+ GeneralSubtrees esb = null;
+
+ if (excludedSubtrees.size() > 0) {
+ esb = new GeneralSubtrees(excludedSubtrees);
+ }
+ mNameConstraintsExtension =
+ new NameConstraintsExtension(mCritical,
+ psb,
+ esb);
+ CMS.debug("NameConstraintsExt: formed Name Constraints Extension " +
+ mNameConstraintsExtension);
+ } catch (IOException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Error initializing Name Constraints Extension: " + e));
+ }
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_NUM_PERMITTEDSUBTREES + "=" + mNumPermittedSubtrees);
+ mInstanceParams.addElement(
+ PROP_NUM_EXCLUDEDSUBTREES + "=" + mNumExcludedSubtrees);
+ if (mNumPermittedSubtrees > 0) {
+ for (int i = 0; i < mPermittedSubtrees.length; i++)
+ mPermittedSubtrees[i].getInstanceParams(mInstanceParams);
+ }
+ if (mNumExcludedSubtrees > 0) {
+ for (int j = 0; j < mExcludedSubtrees.length; j++)
+ mExcludedSubtrees[j].getInstanceParams(mInstanceParams);
+ }
+ }
+
+ Subtree[] form_subtrees(String subtreesName, int numSubtrees)
+ throws EBaseException {
+ Subtree[] subtrees = new Subtree[numSubtrees];
+
+ for (int i = 0; i < numSubtrees; i++) {
+ String subtreeName = subtreesName + i;
+ IConfigStore subtreeConfig = mConfig.getSubStore(subtreeName);
+ Subtree subtree =
+ new Subtree(subtreeName, subtreeConfig, mEnabled);
+
+ subtrees[i] = subtree;
+ }
+ return subtrees;
+ }
+
+ /**
+ * Adds Name Constraints Extension to a (CA) certificate.
+ *
+ * If a Name constraints Extension is already there, accept it if
+ * it's been approved by agent, else replace it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // if extension hasn't been properly configured reject requests until
+ // it has been resolved (or disabled).
+ if (mNameConstraintsExtension == null) {
+ //setError(req, PolicyResources.EXTENSION_NOT_INITED_1, NAME);
+ //return PolicyResult.REJECTED;
+ return PolicyResult.ACCEPTED;
+ }
+
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ // check if name constraints extension already exists.
+ // if not agent approved, replace name constraints extension with ours.
+ // else ignore.
+ try {
+ NameConstraintsExtension nameConstraintsExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ nameConstraintsExt = (NameConstraintsExtension)
+ extensions.get(NameConstraintsExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+
+ if (nameConstraintsExt != null) {
+ if (agentApproved(req)) {
+ CMS.debug(
+ "NameConstraintsExt: request id from agent " + req.getRequestId() +
+ " already has name constraints - accepted");
+ return PolicyResult.ACCEPTED;
+ } else {
+ CMS.debug(
+ "NameConstraintsExt: request id " + req.getRequestId() + " from user " +
+ " already has name constraints - deleted");
+ extensions.delete(NameConstraintsExtension.NAME);
+ }
+ }
+
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ NameConstraintsExtension.NAME, mNameConstraintsExtension);
+ CMS.debug(
+ "NameConstraintsExt: added Name Constraints Extension to request " +
+ req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_NAME_CONST_EXTENSION", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Default config parameters.
+ * To add more permitted or excluded subtrees,
+ * increase the num to greater than 0 and more configuration params
+ * will show up in the console.
+ */
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(
+ PROP_NUM_PERMITTEDSUBTREES + "=" + DEF_NUM_PERMITTEDSUBTREES);
+ mDefParams.addElement(
+ PROP_NUM_EXCLUDEDSUBTREES + "=" + DEF_NUM_EXCLUDEDSUBTREES);
+ for (int k = 0; k < DEF_NUM_PERMITTEDSUBTREES; k++) {
+ Subtree.getDefaultParams(PROP_PERMITTEDSUBTREES + k, mDefParams);
+ }
+ for (int l = 0; l < DEF_NUM_EXCLUDEDSUBTREES; l++) {
+ Subtree.getDefaultParams(PROP_EXCLUDEDSUBTREES + l, mDefParams);
+ }
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector theparams = new Vector();
+
+ theparams.addElement(PROP_CRITICAL + ";boolean;RFC 2459 recommendation: MUST be critical.");
+ theparams.addElement(
+ PROP_NUM_PERMITTEDSUBTREES + ";number;See RFC 2459 sec 4.2.1.11");
+ theparams.addElement(
+ PROP_NUM_EXCLUDEDSUBTREES + ";number;See RFC 2459 sec 4.2.1.11");
+
+ // now do the subtrees.
+ for (int k = 0; k < DEF_NUM_PERMITTEDSUBTREES; k++) {
+ Subtree.getExtendedPluginInfo(PROP_PERMITTEDSUBTREES + k, theparams);
+ }
+ for (int l = 0; l < DEF_NUM_EXCLUDEDSUBTREES; l++) {
+ Subtree.getExtendedPluginInfo(PROP_EXCLUDEDSUBTREES + l, theparams);
+ }
+ theparams.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-nameconstraints");
+ theparams.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Name Constraints Extension. See RFC 2459");
+
+ String[] info = new String[theparams.size()];
+
+ theparams.copyInto(info);
+ return info;
+ }
+}
+
+
+/**
+ * subtree configuration
+ */
+class Subtree {
+
+ protected static final String PROP_BASE = "base";
+ protected static final String PROP_MIN = "min";
+ protected static final String PROP_MAX = "max";
+
+ protected static final int DEF_MIN = 0;
+ protected static final int DEF_MAX = -1; // -1 (less than 0) means not set.
+
+ protected static final String
+ MINMAX_INFO = "number;See RFC 2459 section 4.2.1.11";
+
+ String mName = null;
+ IConfigStore mConfig = null;
+ int mMin = DEF_MIN, mMax = DEF_MAX;
+ IGeneralNameAsConstraintsConfig mBase = null;
+ GeneralSubtree mGeneralSubtree = null;
+
+ String mNameDot = null;
+ String mNameDotMin = null;
+ String mNameDotMax = null;
+
+ public Subtree(
+ String subtreeName, IConfigStore config, boolean policyEnabled)
+ throws EBaseException {
+ mName = subtreeName;
+ mConfig = config;
+
+ if (mName != null) {
+ mNameDot = mName + ".";
+ mNameDotMin = mNameDot + PROP_MIN;
+ mNameDotMax = mNameDot + PROP_MAX;
+ } else {
+ mNameDot = "";
+ mNameDotMin = PROP_MIN;
+ mNameDotMax = PROP_MAX;
+ }
+
+ // necessary to expand/shrink # general names from console.
+ if (mConfig.size() == 0) {
+ mConfig.putInteger(mNameDotMin, mMin);
+ mConfig.putInteger(mNameDotMax, mMax);
+ // GeneralNameConfig will take care of stuff for generalname.
+ }
+
+ // if policy enabled get values to form the general subtree.
+ mMin = mConfig.getInteger(PROP_MIN, DEF_MIN);
+ mMax = mConfig.getInteger(PROP_MAX, DEF_MAX);
+ if (mMax < -1) mMax = -1;
+ mBase = CMS.createGeneralNameAsConstraintsConfig(
+ mNameDot + PROP_BASE, mConfig.getSubStore(PROP_BASE),
+ true, policyEnabled);
+
+ if (policyEnabled) {
+ mGeneralSubtree =
+ new GeneralSubtree(mBase.getGeneralName(), mMin, mMax);
+ }
+ }
+
+ void getInstanceParams(Vector instanceParams) {
+ mBase.getInstanceParams(instanceParams);
+ instanceParams.addElement(mNameDotMin + "=" + mMin);
+ instanceParams.addElement(mNameDotMax + "=" + mMax);
+ }
+
+ static void getDefaultParams(String name, Vector params) {
+ String nameDot = "";
+
+ if (name != null && name.length() >= 0)
+ nameDot = name + ".";
+ CMS.getGeneralNameConfigDefaultParams(nameDot + PROP_BASE, true, params);
+ params.addElement(nameDot + PROP_MIN + "=" + DEF_MIN);
+ params.addElement(nameDot + PROP_MAX + "=" + DEF_MAX);
+ }
+
+ static void getExtendedPluginInfo(String name, Vector info) {
+ String nameDot = "";
+
+ if (name != null && name.length() > 0)
+ nameDot = name + ".";
+ CMS.getGeneralNameConfigExtendedPluginInfo(nameDot + PROP_BASE, true, info);
+ info.addElement(nameDot + PROP_MIN + ";" + MINMAX_INFO);
+ info.addElement(nameDot + PROP_MAX + ";" + MINMAX_INFO);
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java
new file mode 100644
index 000000000..289e2d297
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/OCSPNoCheckExt.java
@@ -0,0 +1,183 @@
+// --- 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.policy.extensions;
+
+
+import com.netscape.certsrv.request.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.extensions.*;
+import netscape.security.util.*;
+import java.security.cert.*;
+import java.io.*;
+import java.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * This implements an OCSP Signing policy, it
+ * adds the OCSP Signing extension to the certificate.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$ $Date$
+ */
+public class OCSPNoCheckExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ public static final String PROP_CRITICAL = "critical";
+ private boolean mCritical = false;
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ private OCSPNoCheckExtension mOCSPNoCheck = null;
+
+ /**
+ * Constructs an OCSP No check extension.
+ */
+ public OCSPNoCheckExt() {
+ NAME = "OCSPNoCheckExt";
+ DESC = "Sets OCSPNoCheck extension for certificates";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2560 recommendation: SHOULD be non-critical.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-ocspnocheck",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds OCSP signing extension to certificate"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Performs one-time initialization of the policy.
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mOCSPNoCheck = new OCSPNoCheckExtension();
+
+ if (mOCSPNoCheck != null) {
+ // configure the extension itself
+ mCritical = config.getBoolean(PROP_CRITICAL,
+ DEFAULT_CRITICALITY);
+ mOCSPNoCheck.setCritical(mCritical);
+ }
+ }
+
+ /**
+ * Applies the policy to the given request.
+ */
+ public PolicyResult apply(IRequest req) {
+
+ // if the extension was not configured correctly, just skip it
+ if (mOCSPNoCheck == null) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ try {
+
+ // find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // prepare the extensions data structure
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ try {
+ extensions.delete(OCSPNoCheckExtension.NAME);
+ } catch (IOException ex) {
+ // OCSPNoCheck extension is not already there
+ // log(ILogger.LL_FAILURE, "No previous extension: "+OCSPNoCheckExtension.NAME+" "+ex.getMessage());
+ }
+ }
+
+ extensions.set(OCSPNoCheckExtension.NAME, mOCSPNoCheck);
+
+ return PolicyResult.ACCEPTED;
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"), NAME,
+ e.getMessage());
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Returns instance parameters.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ return params;
+
+ }
+
+ /**
+ * Returns default parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_CRITICAL + "=false");
+ return defParams;
+
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java
new file mode 100644
index 000000000..4396a09dd
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyConstraintsExt.java
@@ -0,0 +1,282 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Policy Constraints Extension Policy
+ * Adds the policy constraints extension to (CA) certificates.
+ * Filtering of CA certificates is done through predicates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class PolicyConstraintsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String
+ PROP_REQ_EXPLICIT_POLICY = "reqExplicitPolicy";
+ protected static final String
+ PROP_INHIBIT_POLICY_MAPPING = "inhibitPolicyMapping";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final int DEF_REQ_EXPLICIT_POLICY = -1; // not set
+ protected static final int DEF_INHIBIT_POLICY_MAPPING = -1; // not set
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mReqExplicitPolicy = DEF_REQ_EXPLICIT_POLICY;
+ protected int mInhibitPolicyMapping = DEF_INHIBIT_POLICY_MAPPING;
+ protected PolicyConstraintsExtension mPolicyConstraintsExtension = null;
+
+ protected Vector mInstanceParams = new Vector();
+
+ protected static Vector mDefaultParams = new Vector();
+ static {
+ mDefaultParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefaultParams.addElement(
+ PROP_REQ_EXPLICIT_POLICY + "=" + DEF_REQ_EXPLICIT_POLICY);
+ mDefaultParams.addElement(
+ PROP_INHIBIT_POLICY_MAPPING + "=" + DEF_INHIBIT_POLICY_MAPPING);
+ }
+
+ public PolicyConstraintsExt() {
+ NAME = "PolicyConstriantsExt";
+ DESC = "Sets Policy Constraints Extension on subordinate CA certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=certType==ca
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // XXX should do do this ?
+ // if CA does not allow subordinate CAs by way of basic constraints,
+ // this policy always rejects
+ /*****
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((GenericPolicyProcessor)owner).mAuthority;
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ if (caCert != null)
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+ ****/
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mReqExplicitPolicy = mConfig.getInteger(
+ PROP_REQ_EXPLICIT_POLICY, DEF_REQ_EXPLICIT_POLICY);
+ mInhibitPolicyMapping = mConfig.getInteger(
+ PROP_INHIBIT_POLICY_MAPPING, DEF_INHIBIT_POLICY_MAPPING);
+
+ if (mReqExplicitPolicy < -1)
+ mReqExplicitPolicy = -1;
+ if (mInhibitPolicyMapping < -1)
+ mInhibitPolicyMapping = -1;
+
+ // create instance of policy constraings extension
+ try {
+ mPolicyConstraintsExtension =
+ new PolicyConstraintsExtension(mCritical,
+ mReqExplicitPolicy, mInhibitPolicyMapping);
+ CMS.debug(
+ "PolicyConstraintsExt: Created Policy Constraints Extension: " +
+ mPolicyConstraintsExtension);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CANT_INIT_POLICY_CONST_EXT", e.toString()));
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Could not init Policy Constraints Extension. Error: " + e));
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_REQ_EXPLICIT_POLICY + "=" + mReqExplicitPolicy);
+ mInstanceParams.addElement(
+ PROP_INHIBIT_POLICY_MAPPING + "=" + mInhibitPolicyMapping);
+ }
+
+ /**
+ * Adds Policy Constraints Extension to a (CA) certificate.
+ *
+ * If a Policy constraints Extension is already there, accept it if
+ * it's been approved by agent, else replace it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // if extension hasn't been properly configured reject requests until
+ // it has been resolved (or disabled).
+ if (mPolicyConstraintsExtension == null) {
+ return PolicyResult.ACCEPTED;
+ }
+
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ // check if name constraints extension already exists.
+ // if not agent approved, replace name constraints extension with ours.
+ // else ignore.
+ try {
+ PolicyConstraintsExtension policyConstraintsExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ policyConstraintsExt = (PolicyConstraintsExtension)
+ extensions.get(PolicyConstraintsExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+
+ if (policyConstraintsExt != null) {
+ if (agentApproved(req)) {
+ return PolicyResult.ACCEPTED;
+ } else {
+ extensions.delete(PolicyConstraintsExtension.NAME);
+ }
+ }
+
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ "PolicyConstriantsExt", mPolicyConstraintsExtension);
+ CMS.debug("PolicyConstraintsExt: added our policy constraints extension");
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CANT_PROCESS_POLICY_CONST_EXT", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefaultParams;
+ }
+
+ /**
+ * gets plugin info for pretty console edit displays.
+ */
+ public String[] getExtendedPluginInfo(Locale locale) {
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_REQ_EXPLICIT_POLICY + "=" + mReqExplicitPolicy);
+ mInstanceParams.addElement(
+ PROP_INHIBIT_POLICY_MAPPING + "=" + mInhibitPolicyMapping);
+
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2459 recommendation: may be critical or non-critical.",
+ PROP_REQ_EXPLICIT_POLICY + ";integer;Number of addional certificates that may appear in the path before an explicit policy is required. If less than 0 this field is unset in the extension.",
+ PROP_INHIBIT_POLICY_MAPPING + ";integer;Number of addional certificates that may appear in the path before policy mapping is no longer permitted. If less than 0 this field is unset in the extension.",
+ IExtendedPluginInfo.HELP_TOKEN + ";configuration-policyrules-policyconstraints"
+ };
+
+ return params;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java
new file mode 100644
index 000000000..aafecb17a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/PolicyMappingsExt.java
@@ -0,0 +1,417 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Policy Mappings Extension Policy
+ * Adds the Policy Mappings extension to a (CA) certificate.
+ * Filtering of CA certificates is done through predicates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class PolicyMappingsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_NUM_POLICYMAPPINGS = "numPolicyMappings";
+
+ protected static final String PROP_POLICYMAP = "policyMap";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final int DEF_NUM_POLICYMAPPINGS = 1;
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mNumPolicyMappings = DEF_NUM_POLICYMAPPINGS;
+ protected PolicyMap[] mPolicyMaps = null;
+ protected PolicyMappingsExtension mPolicyMappingsExtension = null;
+
+ protected Vector mInstanceParams = new Vector();
+
+ public PolicyMappingsExt() {
+ NAME = "PolicyMappingsExt";
+ DESC = "Sets Policy Mappings Extension on subordinate CA certificates";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=certType==ca
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // XXX should do do this ?
+ // if CA does not allow subordinate CAs by way of basic constraints,
+ // this policy always rejects
+ /*****
+ ICertAuthority certAuthority = (ICertAuthority)
+ ((IPolicyProcessor)owner).getAuthority();
+ if (certAuthority instanceof ICertificateAuthority) {
+ CertificateChain caChain = certAuthority.getCACertChain();
+ X509Certificate caCert = null;
+ // Note that in RA the chain could be null if CA was not up when
+ // RA was started. In that case just set the length to -1 and let
+ // CA reject if it does not allow any subordinate CA certs.
+ if (caChain != null) {
+ caCert = caChain.getFirstCertificate();
+ if (caCert != null)
+ mCAPathLen = caCert.getBasicConstraints();
+ }
+ }
+ ****/
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mNumPolicyMappings = mConfig.getInteger(
+ PROP_NUM_POLICYMAPPINGS, DEF_NUM_POLICYMAPPINGS);
+ if (mNumPolicyMappings < 1) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_INVALID_ATTR_VALUE_2", NAME, ""));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_NUM_POLICYMAPPINGS,
+ "value must be greater than or equal to 1"));
+ }
+
+ // init Policy Mappings, check values if enabled.
+ mPolicyMaps = new PolicyMap[mNumPolicyMappings];
+ for (int i = 0; i < mNumPolicyMappings; i++) {
+ String subtreeName = PROP_POLICYMAP + i;
+
+ try {
+ mPolicyMaps[i] = new PolicyMap(subtreeName, mConfig, mEnabled);
+ } catch (EBaseException e) {
+ log(ILogger.LL_FAILURE, NAME + ": " +
+ CMS.getLogMessage("POLICY_ERROR_CREATE_MAP", e.toString()));
+ throw e;
+ }
+ }
+
+ // create instance of policy mappings extension if enabled.
+ if (mEnabled) {
+ try {
+ Vector certPolicyMaps = new Vector();
+
+ for (int j = 0; j < mNumPolicyMappings; j++) {
+ certPolicyMaps.addElement(
+ mPolicyMaps[j].mCertificatePolicyMap);
+ }
+ mPolicyMappingsExtension =
+ new PolicyMappingsExtension(mCritical, certPolicyMaps);
+ } catch (IOException e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Error initializing " + NAME + " Error: " + e));
+ }
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ PROP_NUM_POLICYMAPPINGS + "=" + mNumPolicyMappings);
+ for (int i = 0; i < mNumPolicyMappings; i++) {
+ mPolicyMaps[i].getInstanceParams(mInstanceParams);
+ }
+ }
+
+ /**
+ * Adds policy mappings Extension to a (CA) certificate.
+ *
+ * If a policy mappings Extension is already there, accept it if
+ * it's been approved by agent, else replace it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // if extension hasn't been properly configured reject requests until
+ // it has been resolved (or disabled).
+ if (mPolicyMappingsExtension == null) {
+ //setError(req, PolicyResources.EXTENSION_NOT_INITED_1, NAME);
+ //return PolicyResult.REJECTED;
+ return PolicyResult.ACCEPTED;
+ }
+
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ // check if policy mappings extension already exists.
+ // if not agent approved, replace policy mappings extension with ours.
+ // else ignore.
+ try {
+ PolicyMappingsExtension policyMappingsExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ policyMappingsExt = (PolicyMappingsExtension)
+ extensions.get(PolicyMappingsExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+
+ if (policyMappingsExt != null) {
+ if (agentApproved(req)) {
+ return PolicyResult.ACCEPTED;
+ } else {
+ extensions.delete(PolicyMappingsExtension.NAME);
+ }
+ }
+
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ PolicyMappingsExtension.NAME, mPolicyMappingsExtension);
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_PROCESS_POLICYMAP_EXT", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.toString()));
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Default config parameters.
+ * To add more permitted or excluded subtrees,
+ * increase the num to greater than 0 and more configuration params
+ * will show up in the console.
+ */
+ private static Vector mDefParams = new Vector();
+ static {
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(
+ PROP_NUM_POLICYMAPPINGS + "=" + DEF_NUM_POLICYMAPPINGS);
+ String policyMap0Dot = PROP_POLICYMAP + "0.";
+
+ mDefParams.addElement(
+ policyMap0Dot + PolicyMap.PROP_ISSUER_DOMAIN_POLICY + "=" + "");
+ mDefParams.addElement(
+ policyMap0Dot + PolicyMap.PROP_SUBJECT_DOMAIN_POLICY + "=" + "");
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ Vector theparams = new Vector();
+
+ theparams.addElement(PROP_CRITICAL + ";boolean;RFC 2459 recommendation: MUST be non-critical.");
+ theparams.addElement(PROP_NUM_POLICYMAPPINGS + ";number; Number of policy mappings. The value must be greater than or equal to 1");
+
+ String policyInfo =
+ ";string;An object identifier in the form n.n.n.n";
+
+ for (int k = 0; k < 5; k++) {
+ String policyMapkDot = PROP_POLICYMAP + k + ".";
+
+ theparams.addElement(policyMapkDot +
+ PolicyMap.PROP_ISSUER_DOMAIN_POLICY + policyInfo);
+ theparams.addElement(policyMapkDot +
+ PolicyMap.PROP_SUBJECT_DOMAIN_POLICY + policyInfo);
+ }
+
+ theparams.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-policymappings");
+ theparams.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Policy Mappings Extension. See RFC 2459 (4.2.1.6)");
+
+ String[] params = new String[theparams.size()];
+
+ theparams.copyInto(params);
+ return params;
+ }
+}
+
+
+class PolicyMap {
+
+ protected static String PROP_ISSUER_DOMAIN_POLICY = "issuerDomainPolicy";
+ protected static String PROP_SUBJECT_DOMAIN_POLICY = "subjectDomainPolicy";
+
+ protected String mName = null;
+ protected String mNameDot = null;
+ protected IConfigStore mConfig = null;
+ protected String mIssuerDomainPolicy = null;
+ protected String mSubjectDomainPolicy = null;
+ protected CertificatePolicyMap mCertificatePolicyMap = null;
+
+ /**
+ * forms policy map parameters.
+ * @param name name of this policy map, for example policyMap0
+ * @param config parent's config from where we find this configuration.
+ * @param enabled whether policy was enabled.
+ */
+ protected PolicyMap(String name, IConfigStore config, boolean enabled)
+ throws EBaseException {
+ mName = name;
+ mConfig = config.getSubStore(mName);
+ mNameDot = mName + ".";
+
+ if( mConfig == null ) {
+ CMS.debug( "PolicyMappingsExt::PolicyMap - mConfig is null!" );
+ return;
+ }
+
+ // if there's no configuration for this map put it there.
+ if (mConfig.size() == 0) {
+ config.putString(mNameDot + PROP_ISSUER_DOMAIN_POLICY, "");
+ config.putString(mNameDot + PROP_SUBJECT_DOMAIN_POLICY, "");
+ mConfig = config.getSubStore(mName);
+ if (mConfig == null || mConfig.size() == 0) {
+ CMS.debug( "PolicyMappingsExt::PolicyMap - mConfig " +
+ "is null or empty!" );
+ return;
+ }
+ }
+
+ // get policy ids from configuration.
+ mIssuerDomainPolicy =
+ mConfig.getString(PROP_ISSUER_DOMAIN_POLICY, null);
+ mSubjectDomainPolicy =
+ mConfig.getString(PROP_SUBJECT_DOMAIN_POLICY, null);
+
+ // adjust for "" and console returning "null"
+ if (mIssuerDomainPolicy != null &&
+ (mIssuerDomainPolicy.length() == 0 ||
+ mIssuerDomainPolicy.equals("null"))) {
+ mIssuerDomainPolicy = null;
+ }
+ if (mSubjectDomainPolicy != null &&
+ (mSubjectDomainPolicy.length() == 0 ||
+ mSubjectDomainPolicy.equals("null"))) {
+ mSubjectDomainPolicy = null;
+ }
+
+ // policy ids cannot be null if policy is enabled.
+ String msg = "value cannot be null.";
+
+ if (mIssuerDomainPolicy == null && enabled)
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mNameDot + PROP_ISSUER_DOMAIN_POLICY, msg));
+ if (mSubjectDomainPolicy == null && enabled)
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mNameDot + PROP_SUBJECT_DOMAIN_POLICY, msg));
+
+ // if a policy id is not null check that it is a valid OID.
+ ObjectIdentifier issuerPolicyId = null;
+ ObjectIdentifier subjectPolicyId = null;
+
+ if (mIssuerDomainPolicy != null)
+ issuerPolicyId = CMS.checkOID(
+ mNameDot + PROP_ISSUER_DOMAIN_POLICY, mIssuerDomainPolicy);
+ if (mSubjectDomainPolicy != null)
+ subjectPolicyId = CMS.checkOID(
+ mNameDot + PROP_SUBJECT_DOMAIN_POLICY, mSubjectDomainPolicy);
+
+ // if enabled, form CertificatePolicyMap to be encoded in extension.
+ // policy ids should be all set.
+ if (enabled) {
+ mCertificatePolicyMap = new CertificatePolicyMap(
+ new CertificatePolicyId(issuerPolicyId),
+ new CertificatePolicyId(subjectPolicyId));
+ }
+ }
+
+ protected void getInstanceParams(Vector instanceParams) {
+ instanceParams.addElement(
+ mNameDot + PROP_ISSUER_DOMAIN_POLICY + "=" + (mIssuerDomainPolicy == null ? "" :
+ mIssuerDomainPolicy));
+ instanceParams.addElement(
+ mNameDot + PROP_SUBJECT_DOMAIN_POLICY + "=" + (mSubjectDomainPolicy == null ? "" :
+ mSubjectDomainPolicy));
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java
new file mode 100644
index 000000000..60da8f9a3
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/PresenceExt.java
@@ -0,0 +1,164 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.authority.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.ca.*;
+import netscape.ldap.*;
+import netscape.security.extensions.*;
+import com.netscape.cms.policy.APolicyRule;
+
+/**
+ * Checks extension presence.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class PresenceExt extends APolicyRule {
+ private static Vector mDefParams = new Vector();
+ private IConfigStore mConfig = null;
+ private String mOID = null;
+ private boolean mCritical;
+ private int mVersion = 0;
+ private String mStreetAddress;
+ private String mTelephoneNumber;
+ private String mRFC822Name;
+ private String mID;
+ private String mHostName;
+ private int mPortNumber = 0;
+ private int mMaxUsers = 0;
+ private int mServiceLevel = 0;
+
+ public static final String PROP_IS_CRITICAL = "critical";
+ public static final String PROP_OID = "oid";
+ public static final String PROP_VERSION = "version";
+ public static final String PROP_STREET_ADDRESS = "streetAddress";
+ public static final String PROP_TELEPHONE_NUMBER = "telephoneNumber";
+ public static final String PROP_RFC822_NAME = "rfc822Name";
+ public static final String PROP_ID = "id";
+ public static final String PROP_HOSTNAME = "hostName";
+ public static final String PROP_PORT_NUMBER = "portNumber";
+ public static final String PROP_MAX_USERS = "maxUsers";
+ public static final String PROP_SERVICE_LEVEL = "serviceLevel";
+
+ static {
+ mDefParams.addElement(PROP_IS_CRITICAL + "=false");
+ }
+
+ public PresenceExt() {
+ NAME = "PresenceExtPolicy";
+ DESC = "Sets Presence Server Extension in certificates.";
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mCritical = config.getBoolean(PROP_IS_CRITICAL, false);
+ mOID = config.getString(PROP_OID, "");
+ mVersion = config.getInteger(PROP_VERSION, 0);
+ mStreetAddress = config.getString(PROP_STREET_ADDRESS, "");
+ mTelephoneNumber = config.getString(PROP_TELEPHONE_NUMBER, "");
+ mRFC822Name = config.getString(PROP_RFC822_NAME, "");
+ mID = config.getString(PROP_ID, "");
+ mHostName = config.getString(PROP_HOSTNAME, "");
+ mPortNumber = config.getInteger(PROP_PORT_NUMBER, 0);
+ mMaxUsers = config.getInteger(PROP_MAX_USERS, 0);
+ mServiceLevel = config.getInteger(PROP_SERVICE_LEVEL, 0);
+ }
+
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ /*
+ PresenceServerExtension ext = new PresenceServerExtension(mCritical,
+ mOID, mVersion, mStreetAddress,
+ mTelephoneNumber, mRFC822Name, mID,
+ mHostName, mPortNumber, mMaxUsers, mServiceLevel);
+ */
+
+ return res;
+ }
+
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_IS_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_OID + "=" + mOID);
+ params.addElement(PROP_VERSION + "=" + mVersion);
+ params.addElement(PROP_STREET_ADDRESS + "=" + mStreetAddress);
+ params.addElement(PROP_TELEPHONE_NUMBER + "=" + mTelephoneNumber);
+ params.addElement(PROP_RFC822_NAME + "=" + mRFC822Name);
+ params.addElement(PROP_ID + "=" + mID);
+ params.addElement(PROP_HOSTNAME + "=" + mHostName);
+ params.addElement(PROP_PORT_NUMBER + "=" + mPortNumber);
+ params.addElement(PROP_MAX_USERS + "=" + mMaxUsers);
+ params.addElement(PROP_SERVICE_LEVEL + "=" + mServiceLevel);
+ return params;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_IS_CRITICAL + ";boolean;Criticality",
+ PROP_OID + ";string; Object identifier of this extension",
+ PROP_VERSION + ";string; version",
+ PROP_STREET_ADDRESS + ";string; street address",
+ PROP_TELEPHONE_NUMBER + ";string; telephone number",
+ PROP_RFC822_NAME + ";string; rfc822 name",
+ PROP_ID + ";string; identifier",
+ PROP_HOSTNAME + ";string; host name",
+ PROP_PORT_NUMBER + ";string; port number",
+ PROP_MAX_USERS + ";string; max users",
+ PROP_SERVICE_LEVEL + ";string; service level",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-presenceext",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Presence Server Extension;"
+
+ };
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java
new file mode 100644
index 000000000..468abdf7b
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/PrivateKeyUsagePeriodExt.java
@@ -0,0 +1,250 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * PrivateKeyUsagePeriod Identifier Extension policy.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class PrivateKeyUsagePeriodExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+
+ private final static String PROP_NOT_BEFORE = "notBefore";
+ private final static String PROP_NOT_AFTER = "notAfter";
+ protected static final String PROP_IS_CRITICAL = "critical";
+
+ // 6 months roughly
+ private final static long defDuration = 60L * 60 * 24 * 180 * 1000;
+
+ private static final String DATE_PATTERN = "MM/dd/yyyy";
+ static SimpleDateFormat formatter = new SimpleDateFormat(DATE_PATTERN);
+ private static Date now = CMS.getCurrentDate();
+ private static Date six_months = new Date(now.getTime() + defDuration);
+
+ public static final String DEFAULT_NOT_BEFORE = formatter.format(now);
+ public static final String DEFAULT_NOT_AFTER = formatter.format(six_months);
+
+ // PKIX specifies the that the extension SHOULD NOT be critical
+ public static final boolean DEFAULT_CRITICALITY = false;
+
+ protected String mNotBefore;
+ protected String mNotAfter;
+ protected boolean mCritical;
+
+ private static Vector defaultParams;
+
+ static {
+
+ formatter.setLenient(false);
+
+ defaultParams = new Vector();
+ defaultParams.addElement(PROP_IS_CRITICAL + "=" + DEFAULT_CRITICALITY);
+ defaultParams.addElement(PROP_NOT_BEFORE + "=" + DEFAULT_NOT_BEFORE);
+ defaultParams.addElement(PROP_NOT_AFTER + "=" + DEFAULT_NOT_AFTER);
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_IS_CRITICAL + ";boolean;RFC 2459 recommendation: The profile " +
+ "recommends against the use of this extension. CAs " +
+ "conforming to the profile MUST NOT generate certs with " +
+ "critical private key usage period extensions.",
+ PROP_NOT_BEFORE + ";string; Date before which the Private Key is invalid.",
+ PROP_NOT_AFTER + ";string; Date after which the Private Key is invalid.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-privatekeyusageperiod",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds (deprecated) Private Key Usage Period Extension. " +
+ "Defined in RFC 2459 (4.2.1.4)"
+ };
+
+ return params;
+ }
+
+ /**
+ * Adds the private key usage extension to all certs.
+ */
+ public PrivateKeyUsagePeriodExt() {
+ NAME = "PrivateKeyUsagePeriodExt";
+ DESC = "Sets Private Key Usage Extension for a certificate";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * ra.Policy.rule.<ruleName>.implName=PrivateKeyUsageExtension
+ * ra.Policy.rule.<ruleName>.enable=true
+ * ra.Policy.rule.<ruleName>.notBefore=30
+ * ra.Policy.rule.<ruleName>.notAfter=180
+ * ra.Policy.rule.<ruleName>.critical=false
+ * ra.Policy.rule.<ruleName>.predicate=ou==Sales
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+
+ try {
+ // Get params.
+ mNotBefore = config.getString(PROP_NOT_BEFORE, null);
+ mNotAfter = config.getString(PROP_NOT_AFTER, null);
+ mCritical = config.getBoolean(PROP_IS_CRITICAL, false);
+
+ // Check the parameter formats
+ String notBefore;
+ String notAfter;
+
+ notBefore = formatter.format(formatter.parse(mNotBefore.trim()));
+ notAfter = formatter.format(formatter.parse(mNotAfter.trim()));
+ } catch (Exception e) {
+ // e.printStackTrace();
+ Object[] params = {getInstanceName(), e};
+
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_INVALID_POLICY_CONFIG"), params);
+ }
+
+ }
+
+ /**
+ * Adds a private key usage extension if none exists.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ // get private key usage extension from cert info if any.
+ CertificateExtensions extensions = null;
+ PrivateKeyUsageExtension ext = null;
+
+ try {
+ // get subject key id extension if any.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ } catch (IOException e) {
+ // no extensions or subject key identifier extension.
+ } catch (CertificateException e) {
+ // no extensions or subject key identifier extension.
+ }
+
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ } else {
+ // remove any previously computed version of the extension
+ try {
+ extensions.delete(PrivateKeyUsageExtension.NAME);
+
+ } catch (IOException e) {
+ }
+
+ }
+
+ try {
+ ext = new PrivateKeyUsageExtension(
+ formatter.parse(mNotBefore),
+ formatter.parse(mNotAfter));
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions.set(PrivateKeyUsageExtension.NAME, ext);
+ } catch (Exception e) {
+ if (e instanceof RuntimeException)
+ throw (RuntimeException) e;
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_CREATE_PRIVATE_KEY_EXT", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR"), NAME);
+ return PolicyResult.REJECTED;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return Empty Vector since this policy has no configuration parameters.
+ * for this policy instance.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ params.addElement(PROP_IS_CRITICAL + "=" + mCritical);
+ params.addElement(PROP_NOT_BEFORE + "=" + mNotBefore);
+ params.addElement(PROP_NOT_AFTER + "=" + mNotAfter);
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return Empty Vector since this policy implementation has no
+ * configuration parameters.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ defParams.addElement(PROP_IS_CRITICAL + "=" + DEFAULT_CRITICALITY);
+ defParams.addElement(PROP_NOT_BEFORE + "=" + DEFAULT_NOT_BEFORE);
+ defParams.addElement(PROP_NOT_AFTER + "=" + DEFAULT_NOT_AFTER);
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java
new file mode 100644
index 000000000..b8dba995e
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/RemoveBasicConstraintsExt.java
@@ -0,0 +1,141 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Remove Basic Constraints policy.
+ * Adds the Basic constraints extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class RemoveBasicConstraintsExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ public RemoveBasicConstraintsExt() {
+ NAME = "RemoveBasicConstraintsExt";
+ DESC = "Remove Basic Constraints extension";
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ }
+
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // get cert info.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ X509CertInfo certInfo = null;
+
+ if (ci == null || (certInfo = ci[0]) == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certResult = applyCert(req, certInfo);
+
+ if (certResult == PolicyResult.REJECTED)
+ return certResult;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(
+ IRequest req, X509CertInfo certInfo) {
+ // get basic constraints extension from cert info if any.
+ CertificateExtensions extensions = null;
+
+ try {
+ // get basic constraints extension if any.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ if (extensions != null) {
+ try {
+ extensions.delete(BasicConstraintsExtension.NAME);
+ CMS.debug("PolicyRule RemoveBasicConstraintsExt: removed the extension from request " + req.getRequestId().toString());
+ } catch (IOException e) {
+ }
+ }
+ } catch (IOException e) {
+ // no extensions or basic constraints extension.
+ } catch (CertificateException e) {
+ // no extensions or basic constraints extension.
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ return defParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-removebasicconstraints",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Removes the Basic Constraints extension."
+ };
+
+ return params;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java
new file mode 100644
index 000000000..32e2c48fb
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjAltNameExt.java
@@ -0,0 +1,350 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ *
+ * THIS POLICY HAS BEEN DEPRECATED SINCE CMS 4.2.
+ * New Policy is com.netscape.certsrv.policy.SubjectAltNameExt.
+ * <p>
+ *
+ * Subject Alternative Name extension policy in CMS 4.1.
+ *
+ * Adds the subject alternative name extension depending on the
+ * certificate type requested.
+ *
+ * Two forms are supported. 1) For S/MIME certificates, email
+ * addresses are copied from data stored in the request by the
+ * authentication component. Both 'e' and 'altEmail' are supported
+ * so that both the primary address and alternative forms may be
+ * certified. Only the primary goes in the subjectName position (which
+ * should be phased out).
+ *
+ * e
+ * mailAlternateAddress
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubjAltNameExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ // for future use. currently always allow.
+ protected static final String PROP_AGENT_OVERR = "allowAgentOverride";
+ protected static final String PROP_EE_OVERR = "AllowEEOverride";
+ protected static final String PROP_ENABLE_MANUAL_VALUES =
+ "enableManualValues";
+
+ // for future use. currently always non-critical
+ // (standard says SHOULD be marked critical if included.)
+ protected static final String PROP_CRITICAL = "critical";
+
+ // for future use to allow overrides from forms.
+ // request must be agent approved or authenticated.
+ protected boolean mAllowAgentOverride = false;
+ protected boolean mAllowEEOverride = false;
+ protected boolean mEnableManualValues = false;
+
+ // for future use. currently always critical
+ // (standard says SHOULD be marked critical if included.)
+ protected boolean mCritical = false;
+
+ public SubjAltNameExt() {
+ NAME = "SubjAltNameExt";
+ DESC = "Sets alternative subject names for certificates";
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2459 recommendation: If the certificate subject field contains an empty sequence, the subjectAltName extension MUST be marked critical.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subjaltname",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";This policy inserts the Subject Alternative Name " +
+ "Extension into the certificate. See RFC 2459 (4.2.1.7). " +
+ "* Note: you probably want to use this policy in " +
+ "conjunction with an authentication manager which sets " +
+ "the 'mail' or 'mailalternateaddress' values in the authToken. " +
+ "See the 'ldapStringAttrs' parameter in the Directory-based " +
+ "authentication plugin"
+ };
+
+ return params;
+
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=SubjAltNameExt
+ * ra.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ // future use.
+ mAllowAgentOverride = config.getBoolean(PROP_AGENT_OVERR, false);
+ mAllowEEOverride = config.getBoolean(PROP_EE_OVERR, false);
+ mCritical = config.getBoolean(PROP_CRITICAL, false);
+ // mEnableManualValues = config.getBoolean(PROP_ENABLE_MANUAL_VALUES, false);
+ }
+
+ /**
+ * Adds the subject alternative names extension if not set already.
+ *
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // Find the X509CertInfo object in the request
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return res;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ //
+ // General error handling block
+ //
+ apply:
+ try {
+
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ if (extensions != null) {
+ //
+ // Remove any previously computed version of the extension
+ //
+ try {
+ extensions.delete(SubjectAlternativeNameExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there
+ }
+ }
+
+ //
+ // Determine the type of the request. For future expansion
+ // this test should dispatch to a specialized object to
+ // handle each particular type. For now just return for
+ // non-client certs, and implement client certs directly here.
+ //
+ String certType =
+ req.getExtDataInString(IRequest.HTTP_PARAMS, IRequest.CERT_TYPE);
+
+ if (certType == null ||
+ !certType.equals(IRequest.CLIENT_CERT) ||
+ !req.getExtDataInBoolean(IRequest.SMIME, false)) {
+ break apply;
+ }
+
+ // Create a list of email addresses that should be added
+ // to the certificate
+
+ IAuthToken tok = findAuthToken(req, null);
+
+ if (tok == null) break apply;
+
+ Vector emails = getEmailList(tok);
+
+ if (emails == null) break apply;
+
+ // Create the extension
+ SubjectAlternativeNameExtension subjAltNameExt = mkExt(emails);
+
+ if (extensions == null)
+ extensions = createCertificateExtensions(certInfo);
+
+ extensions.set(SubjectAlternativeNameExtension.NAME,
+ subjAltNameExt);
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.toString()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ return res;
+ }
+
+ /**
+ * Find a particular authentication token by manager name.
+ * If the token is not present return null
+ */
+ protected IAuthToken
+ findAuthToken(IRequest req, String authMgrName) {
+
+ return req.getExtDataInAuthToken(IRequest.AUTH_TOKEN);
+ }
+
+ /**
+ * Generate a String Vector containing all the email addresses
+ * found in this Authentication token
+ */
+ protected Vector /* of String */
+ getEmailList(IAuthToken tok) {
+
+ Vector v = new Vector();
+
+ addValues(tok, "mail", v);
+ addValues(tok, "mailalternateaddress", v);
+
+ if (v.size() == 0) return null;
+
+ return v;
+ }
+
+ /**
+ * Add attribute values from an LDAP attribute to a vector
+ */
+ protected void
+ addValues(IAuthToken tok, String attrName, Vector v) {
+ String attr[] = tok.getInStringArray(attrName);
+
+ if (attr == null) return;
+
+ for (int i = 0; i < attr.length; i++) {
+ v.addElement(attr[i]);
+ }
+ }
+
+ /**
+ * Make a Subject name extension given a list of email addresses
+ */
+ protected SubjectAlternativeNameExtension
+ mkExt(Vector emails)
+ throws IOException {
+ SubjectAlternativeNameExtension sa;
+ GeneralNames gns = new GeneralNames();
+
+ for (int i = 0; i < emails.size(); i++) {
+ String email = (String) emails.elementAt(i);
+
+ gns.addElement(new RFC822Name(email));
+ }
+
+ sa = new SubjectAlternativeNameExtension(gns);
+
+ return sa;
+ }
+
+ /**
+ * Create a new SET of extensions in the certificate info
+ * object.
+ *
+ * This should be a method in the X509CertInfo object
+ */
+ protected CertificateExtensions
+ createCertificateExtensions(X509CertInfo certInfo)
+ throws IOException, CertificateException {
+ CertificateExtensions extensions;
+
+ // Force version to V3
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+
+ return extensions;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ Vector params = new Vector();
+
+ //params.addElement("PROP_AGENT_OVERR = " + mAllowAgentOverride);
+ //params.addElement("PROP_EE_OVERR = " + mAllowEEOverride);
+ params.addElement(PROP_CRITICAL + "=" + mCritical);
+ // params.addElement(PROP_ENABLE_MANUAL_VALUES + " = " +
+ // mEnableManualValues);
+ return params;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ Vector defParams = new Vector();
+
+ //defParams.addElement("PROP_AGENT_OVERR = " + DEF_AGENT_OVERR);
+ //defParams.addElement("PROP_EE_OVERR = " + DEF_EE_OVERR);
+ defParams.addElement(PROP_CRITICAL + "=false");
+ // defParams.addElement(PROP_ENABLE_MANUAL_VALUES + "= false");
+
+ return defParams;
+ }
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java
new file mode 100644
index 000000000..eb7dba173
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectAltNameExt.java
@@ -0,0 +1,322 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.apps.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import netscape.security.x509.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Subject Alternative Name extension policy.
+ *
+ * Adds the subject alternative name extension as configured.
+ *
+ * Two forms are supported. 1) For S/MIME certificates, email
+ * addresses are copied from data stored in the request by the
+ * authentication component. Both 'e' and 'altEmail' are supported
+ * so that both the primary address and alternative forms may be
+ * certified. Only the primary goes in the subjectName position (which
+ * should be phased out).
+ *
+ * e
+ * mailAlternateAddress
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubjectAltNameExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ // (standard says SHOULD be marked critical if included.)
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final boolean DEF_CRITICAL = false;
+
+ protected IConfigStore mConfig = null;
+ protected boolean mEnabled = false;
+ protected boolean mCritical = DEF_CRITICAL;
+ protected int mNumGNs = 0;
+ protected ISubjAltNameConfig[] mGNs = null;
+
+ Vector mInstanceParams = new Vector();
+
+ // init default params and extended plugin info.
+ private static Vector mDefParams = new Vector();
+ static {
+ // default params.
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(
+ IGeneralNameUtil.PROP_NUM_GENERALNAMES + "=" +
+ IGeneralNameUtil.DEF_NUM_GENERALNAMES);
+ for (int i = 0; i < IGeneralNameUtil.DEF_NUM_GENERALNAMES; i++) {
+ CMS.getSubjAltNameConfigDefaultParams(
+ IGeneralNameUtil.PROP_GENERALNAME + i, mDefParams);
+ }
+ }
+
+ private String[] mExtendedPluginInfo = null;
+
+ public SubjectAltNameExt() {
+ NAME = "SubjectAltNameExt";
+ DESC = "Sets alternative subject names for certificates";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ra.Policy.rule.<ruleName>.implName=SubjectAltNameExt
+ * ra.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ // get criticality
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ // get enabled
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+
+ // get general names configuration.
+ mNumGNs = mConfig.getInteger(IGeneralNameUtil.PROP_NUM_GENERALNAMES);
+ if (mNumGNs <= 0) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_MUST_BE_POSITIVE_NUMBER",
+ IGeneralNameUtil.PROP_NUM_GENERALNAMES));
+ }
+ mGNs = new ISubjAltNameConfig[mNumGNs];
+ for (int i = 0; i < mNumGNs; i++) {
+ String name = IGeneralNameUtil.PROP_GENERALNAME + i;
+ IConfigStore substore = mConfig.getSubStore(name);
+
+ mGNs[i] = CMS.createSubjAltNameConfig(name, substore, mEnabled);
+ }
+
+ // init instance params.
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(
+ IGeneralNameUtil.PROP_NUM_GENERALNAMES + "=" + mNumGNs);
+ for (int j = 0; j < mGNs.length; j++) {
+ mGNs[j].getInstanceParams(mInstanceParams);
+ }
+ }
+
+ /**
+ * Adds the subject alternative names extension if not set already.
+ *
+ * <P>
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ // Find the X509CertInfo object in the request
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return res;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+
+ try {
+ // Find the extensions in the certInfo
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ // Remove any previously computed version of the extension
+ // unless it is from RA. If from RA, accept what RA put in
+ // request and don't add our own.
+ if (extensions != null) {
+ String sourceId = req.getSourceId();
+
+ if (sourceId != null && sourceId.length() > 0)
+ return res; // accepted
+ try {
+ extensions.delete(SubjectAlternativeNameExtension.NAME);
+ } catch (IOException e) {
+ // extension isn't there
+ }
+ }
+
+ // form list of general names for the extension.
+ GeneralNames gns = new GeneralNames();
+
+ for (int i = 0; i < mNumGNs; i++) {
+ Object value = null;
+
+ value = req.getExtDataInString(mGNs[i].getPfx(), mGNs[i].getAttr());
+ if (value == null) {
+ continue;
+ }
+ Vector gn = mGNs[i].formGeneralNames(value);
+
+ if (gn.size() == 0)
+ continue;
+ for (Enumeration n = gn.elements(); n.hasMoreElements();) {
+ gns.addElement((GeneralName) n.nextElement());
+ }
+ }
+
+ // nothing was found in request to put into extension
+ if (gns.size() == 0)
+ return res; // accepted
+
+ String subject = certInfo.get(X509CertInfo.SUBJECT).toString();
+
+ boolean curCritical = mCritical;
+
+ if (subject.equals("")) {
+ curCritical = true;
+ }
+
+ // make the extension
+ SubjectAlternativeNameExtension
+ sa = new SubjectAlternativeNameExtension(curCritical, gns);
+
+ // add it to certInfo.
+ if (extensions == null)
+ extensions = createCertificateExtensions(certInfo);
+
+ extensions.set(SubjectAlternativeNameExtension.NAME, sa);
+
+ return res; // accepted.
+
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (Exception e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("BASE_INTERNAL_ERROR_1", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Internal Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+ }
+
+ /**
+ * Create a new SET of extensions in the certificate info
+ * object.
+ *
+ * This should be a method in the X509CertInfo object
+ */
+ protected CertificateExtensions
+ createCertificateExtensions(X509CertInfo certInfo)
+ throws IOException, CertificateException {
+ CertificateExtensions extensions;
+
+ // Force version to V3
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+
+ return extensions;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+
+ // extended plugin info.
+ Vector info = new Vector();
+
+ info.addElement(PROP_CRITICAL + ";boolean;RFC2459 recommendation: If the certificate subject field contains an empty sequence, the extension MUST be marked critical.");
+ info.addElement(IGeneralNameUtil.PROP_NUM_GENERALNAMES_INFO);
+ for (int i = 0; i < IGeneralNameUtil.DEF_NUM_GENERALNAMES; i++) {
+ CMS.getSubjAltNameConfigExtendedPluginInfo(
+ IGeneralNameUtil.PROP_GENERALNAME + i, info);
+ }
+ info.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subjaltname");
+ info.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";This policy inserts the Subject Alternative Name " +
+ "Extension into the certificate. See RFC 2459 (4.2.1.7). " +
+ "* Note: you probably want to use this policy in " +
+ "conjunction with an authentication manager which sets " +
+ "the 'mail' or 'mailalternateaddress' values in the authToken. " +
+ "See the 'ldapStringAttrs' parameter in the Directory-based " +
+ "authentication plugin");
+ mExtendedPluginInfo = new String[info.size()];
+ info.copyInto(mExtendedPluginInfo);
+ return mExtendedPluginInfo;
+ }
+
+}
+
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java
new file mode 100644
index 000000000..be065245a
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectDirectoryAttributesExt.java
@@ -0,0 +1,434 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.authentication.*;
+import com.netscape.certsrv.common.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.extensions.*;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import netscape.ldap.*;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Policy to add the subject directory attributes extension.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubjectDirectoryAttributesExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_ATTRIBUTE = "attribute";
+ protected static final String PROP_NUM_ATTRIBUTES = "numAttributes";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final int DEF_NUM_ATTRIBUTES = 3;
+ protected static final int MAX_NUM_ATTRIBUTES = 10;
+
+ protected boolean mCritical;
+ protected int mNumAttributes;
+ protected AttributeConfig[] mAttributes = null;
+
+ protected IConfigStore mConfig;
+ protected SubjectDirAttributesExtension mExt = null;
+
+ protected Vector mParams = new Vector();
+ private String[] mEPI = null; // extended plugin info
+ protected static Vector mDefParams = new Vector();
+
+ static {
+ setDefaultParams();
+ }
+
+ public SubjectDirectoryAttributesExt() {
+ NAME = "SubjectDirectoryAttributesExtPolicy";
+ DESC = "Sets Subject Directory Attributes Extension in certificates.";
+ setExtendedPluginInfo();
+ }
+
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ boolean enabled = config.getBoolean("enabled", false);
+
+ mConfig = config;
+
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, false);
+ mNumAttributes = mConfig.getInteger(PROP_NUM_ATTRIBUTES, DEF_NUM_ATTRIBUTES);
+ if (mNumAttributes < 1) {
+ EBaseException ex = new EBaseException(
+ CMS.getUserMessage("CMS_BASE_MUST_BE_POSITIVE_NUMBER", PROP_NUM_ATTRIBUTES));
+
+ log(ILogger.LL_FAILURE, NAME + " Error: " + ex.toString());
+ throw ex;
+ }
+ mAttributes = new AttributeConfig[mNumAttributes];
+ for (int i = 0; i < mNumAttributes; i++) {
+ String name = PROP_ATTRIBUTE + i;
+ IConfigStore c = mConfig.getSubStore(name);
+
+ mAttributes[i] = new AttributeConfig(name, c, enabled);
+ }
+ if (enabled) {
+ try {
+ mExt = formExt(null);
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, NAME + " Error: " + e.getMessage());
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INTERNAL_ERROR",
+ "Error forming Subject Directory Attributes Extension. " +
+ "See log file for details."));
+ }
+ }
+ setInstanceParams();
+ }
+
+ public PolicyResult apply(IRequest req) {
+ PolicyResult res = PolicyResult.ACCEPTED;
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED; // unrecoverable error.
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult r = applyCert(req, ci[i]);
+
+ if (r == PolicyResult.REJECTED)
+ return r;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+ CertificateExtensions extensions = null;
+ SubjectDirAttributesExtension subjDirExt = null;
+
+ try {
+ // get extension and remove if exists.
+ extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+ if (extensions == null) {
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ } else {
+ try {
+ extensions.delete(SubjectDirAttributesExtension.NAME);
+ } catch (IOException ee) {
+ // if name is not found, try deleting the extension using the OID
+ try {
+ extensions.delete("2.5.29.9");
+ } catch (IOException eee) {
+ }
+ }
+ }
+
+ // form extension and set.
+ if (mExt != null) {
+ extensions.set(SubjectDirAttributesExtension.NAME, mExt);
+ } else {
+ SubjectDirAttributesExtension ext = formExt(req);
+
+ if (ext != null)
+ extensions.set(SubjectDirAttributesExtension.NAME, formExt(req));
+ }
+ return PolicyResult.ACCEPTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED; // unrecoverable error.
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("BASE_IO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "IOException Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ private Vector formValues(String val) {
+ StringTokenizer tokenizer = new StringTokenizer(val, "+");
+ Vector v = new Vector();
+
+ while (tokenizer.hasMoreElements()) {
+ String s = (String) tokenizer.nextElement();
+
+ v.addElement(s);
+ }
+ return v;
+ }
+
+ public Vector getInstanceParams() {
+ return mParams; // inited in init()
+ }
+
+ public Vector getDefaultParams() {
+ return mDefParams;
+ }
+
+ public String[] getExtendedPluginInfo(Locale locale) {
+ return mEPI; // inited in the constructor.
+ }
+
+ private void setInstanceParams() {
+ mParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mParams.addElement(PROP_NUM_ATTRIBUTES + "=" + mNumAttributes);
+ for (int i = 0; i < mNumAttributes; i++) {
+ mAttributes[i].getInstanceParams(mParams);
+ }
+ // clean up others if exists. expensive.
+ for (int j = mNumAttributes; j < MAX_NUM_ATTRIBUTES; j++) {
+ mConfig.removeSubStore(PROP_ATTRIBUTE + j);
+ }
+ }
+
+ private static void setDefaultParams() {
+ mDefParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefParams.addElement(PROP_NUM_ATTRIBUTES + "=" + DEF_NUM_ATTRIBUTES);
+ for (int i = 0; i < DEF_NUM_ATTRIBUTES; i++) {
+ AttributeConfig.getDefaultParams(PROP_ATTRIBUTE + i, mDefParams);
+ }
+ }
+
+ private void setExtendedPluginInfo() {
+ Vector v = new Vector();
+
+ v.addElement(PROP_CRITICAL + ";boolean;" +
+ "RFC 2459 recommendation: MUST be non-critical.");
+ v.addElement(PROP_NUM_ATTRIBUTES + ";number;" +
+ "Number of Attributes in the extension.");
+
+ for (int i = 0; i < MAX_NUM_ATTRIBUTES; i++) {
+ AttributeConfig.getExtendedPluginInfo(PROP_ATTRIBUTE + i, v);
+ }
+
+ v.addElement(IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subjectdirectoryattributes");
+ v.addElement(IExtendedPluginInfo.HELP_TEXT +
+ ";Adds Subject Directory Attributes extension. See RFC 2459 (4.2.1.9). It's not recommended as an essential part of the profile, but may be used in local environments.");
+
+ mEPI = com.netscape.cmsutil.util.Utils.getStringArrayFromVector(v);
+ }
+
+ private SubjectDirAttributesExtension formExt(IRequest req)
+ throws IOException {
+ Vector attrs = new Vector();
+
+ // if we're called from init and one attribute is from request attribute
+ // the ext can't be formed yet.
+ if (req == null) {
+ for (int i = 0; i < mNumAttributes; i++) {
+ if (mAttributes[i].mWhereToGetValue ==
+ AttributeConfig.USE_REQUEST_ATTR)
+ return null;
+ }
+ }
+ // either we're called from apply or all values are fixed.
+ for (int i = 0; i < mNumAttributes; i++) {
+ if (mAttributes[i].mAttribute != null) {
+ attrs.addElement(mAttributes[i].mAttribute);
+ } else {
+ // skip attribute if request attribute doesn't exist.
+ Attribute a = mAttributes[i].formAttr(req);
+
+ if (a == null)
+ continue;
+ attrs.addElement(a);
+ }
+ }
+ if (attrs.size() == 0)
+ return null;
+ Attribute[] attrList = new Attribute[attrs.size()];
+
+ attrs.copyInto(attrList);
+ SubjectDirAttributesExtension ext =
+ new SubjectDirAttributesExtension(attrList);
+
+ return ext;
+ }
+}
+
+
+class AttributeConfig {
+
+ protected static final String PROP_ATTRIBUTE_NAME = "attributeName";
+ protected static final String PROP_WTG_VALUE = "whereToGetValue";
+ protected static final String PROP_VALUE = "value";
+
+ protected static final String USE_REQUEST_ATTR = "Request Attribute";
+ protected static final String USE_FIXED = "Fixed Value";
+
+ protected String mAttributeName = null;
+ protected String mWhereToGetValue = null;
+ protected String mValue = null;
+
+ protected String mPrefix = null;
+ protected String mReqAttr = null;
+ protected ObjectIdentifier mAttributeOID = null;
+
+ protected String mName = null;
+ protected IConfigStore mConfig = null;
+ protected Attribute mAttribute = null;
+
+ protected static final String ATTRIBUTE_NAME_INFO = "Attribute name.";
+ protected static final String WTG_VALUE_INFO =
+ PROP_WTG_VALUE + ";choice(" + USE_REQUEST_ATTR + "," + USE_FIXED + ");" +
+ "Get value from a request attribute or use a fixed value specified below.";
+ protected static final String VALUE_INFO =
+ PROP_VALUE + ";string;" +
+ "Request attribute name or a fixed value to put into the extension.";
+
+ public AttributeConfig(String name, IConfigStore config, boolean enabled)
+ throws EBaseException {
+ X500NameAttrMap map = X500NameAttrMap.getDefault();
+
+ mName = name;
+ mConfig = config;
+ if (enabled) {
+ mAttributeName = mConfig.getString(PROP_ATTRIBUTE_NAME);
+ mWhereToGetValue = mConfig.getString(PROP_WTG_VALUE);
+ mValue = mConfig.getString(PROP_VALUE);
+ } else {
+ mAttributeName = mConfig.getString(PROP_ATTRIBUTE_NAME, "");
+ mWhereToGetValue = mConfig.getString(PROP_WTG_VALUE, USE_REQUEST_ATTR);
+ mValue = mConfig.getString(PROP_VALUE, "");
+ }
+
+ if (mAttributeName.length() > 0) {
+ mAttributeOID = map.getOid(mAttributeName);
+ if (mAttributeOID == null)
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", mAttributeName));
+ }
+
+ if (mWhereToGetValue.equalsIgnoreCase(USE_REQUEST_ATTR)) {
+ mWhereToGetValue = USE_REQUEST_ATTR;
+ if (enabled && mValue.length() == 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_GET_PROPERTY_FAILED", PROP_VALUE));
+ }
+ int dot = mValue.indexOf('.');
+
+ if (dot != -1) {
+ mPrefix = mValue.substring(0, dot);
+ mReqAttr = mValue.substring(dot + 1);
+ if (mPrefix == null || mPrefix.length() == 0 ||
+ mReqAttr == null || mReqAttr.length() == 0) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTRIBUTE", mValue));
+ }
+ } else {
+ mPrefix = null;
+ mReqAttr = mValue;
+ }
+ } else if (mWhereToGetValue.equalsIgnoreCase(USE_FIXED)) {
+ mWhereToGetValue = USE_FIXED;
+ if (mAttributeOID != null) {
+ try {
+ checkValue(mAttributeOID, mValue);
+ mAttribute = new Attribute(mAttributeOID, mValue);
+ } catch (Exception e) {
+ throw new EBaseException(
+ CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mAttributeName, e.getMessage()));
+ }
+ }
+ } else if (enabled || mWhereToGetValue.length() > 0) {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_VALUE_FOR_TYPE", PROP_WTG_VALUE,
+ "Must be either '" + USE_REQUEST_ATTR + "' or '" + USE_FIXED + "'."));
+ }
+ }
+
+ public static void getDefaultParams(String name, Vector v) {
+ String nameDot = name + ".";
+
+ v.addElement(nameDot + PROP_ATTRIBUTE_NAME + "=");
+ v.addElement(nameDot + PROP_WTG_VALUE + "=" + USE_REQUEST_ATTR);
+ v.addElement(nameDot + PROP_VALUE + "=");
+ }
+
+ public static void getExtendedPluginInfo(String name, Vector v) {
+ String nameDot = name + ".";
+ String attrChoices = getAllNames();
+
+ v.addElement(nameDot + PROP_ATTRIBUTE_NAME + ";choice(" + attrChoices + ");" +
+ ATTRIBUTE_NAME_INFO);
+ v.addElement(nameDot + WTG_VALUE_INFO);
+ v.addElement(nameDot + VALUE_INFO);
+ }
+
+ public void getInstanceParams(Vector v) {
+ String nameDot = mName + ".";
+
+ v.addElement(nameDot + PROP_ATTRIBUTE_NAME + "=" + mAttributeName);
+ v.addElement(nameDot + PROP_WTG_VALUE + "=" + mWhereToGetValue);
+ v.addElement(nameDot + PROP_VALUE + "=" + mValue);
+ }
+
+ public Attribute formAttr(IRequest req)
+ throws IOException {
+ String val = req.getExtDataInString(mPrefix, mReqAttr);
+
+ if (val == null || val.length() == 0) {
+ return null;
+ }
+ checkValue(mAttributeOID, val);
+ return new Attribute(mAttributeOID, val);
+ }
+
+ static private String getAllNames() {
+ Enumeration n = X500NameAttrMap.getDefault().getAllNames();
+ StringBuffer sb = new StringBuffer();
+ sb.append((String) n.nextElement());
+
+ while (n.hasMoreElements()) {
+ sb.append(",");
+ sb.append((String) n.nextElement());
+ }
+ return sb.toString();
+ }
+
+ private static void checkValue(ObjectIdentifier oid, String val)
+ throws IOException {
+ AVAValueConverter c = X500NameAttrMap.getDefault().getValueConverter(oid);
+ DerValue derval;
+
+ derval = c.getValue(val); // errs encountered will get thrown.
+ return;
+ }
+
+}
diff --git a/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java
new file mode 100644
index 000000000..a8069be29
--- /dev/null
+++ b/pki/base/common/src/com/netscape/cms/policy/extensions/SubjectKeyIdentifierExt.java
@@ -0,0 +1,368 @@
+// --- 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.policy.extensions;
+
+
+import java.util.*;
+import java.io.*;
+import java.security.cert.*;
+import com.netscape.certsrv.request.IRequest;
+import com.netscape.certsrv.request.PolicyResult;
+import com.netscape.certsrv.policy.*;
+import com.netscape.certsrv.base.*;
+import com.netscape.certsrv.ca.*;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.apps.*;
+import netscape.security.x509.*;
+import netscape.security.util.*;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.InvalidKeyException;
+import com.netscape.cms.policy.APolicyRule;
+
+
+/**
+ * Subject Public Key Extension Policy
+ * Adds the subject public key id extension to certificates.
+ * <P>
+ * <PRE>
+ * NOTE: The Policy Framework has been replaced by the Profile Framework.
+ * </PRE>
+ * <P>
+ *
+ * @deprecated
+ * @version $Revision$, $Date$
+ */
+public class SubjectKeyIdentifierExt extends APolicyRule
+ implements IEnrollmentPolicy, IExtendedPluginInfo {
+ protected static final String PROP_CRITICAL = "critical";
+ protected static final String PROP_KEYID_TYPE = "keyIdentifierType";
+ protected static final String PROP_REQATTR_NAME = "requestAttrName";
+
+ protected static final String KEYID_TYPE_SHA1 = "SHA1";
+ protected static final String KEYID_TYPE_TYPEFIELD = "TypeField";
+ protected static final String KEYID_TYPE_SPKISHA1 = "SpkiSHA1";
+ protected static final String KEYID_TYPE_REQATTR = "RequestAttribute";
+
+ protected static final boolean DEF_CRITICAL = false;
+ protected static final String DEF_KEYID_TYPE = KEYID_TYPE_SHA1;
+ protected static final String DEF_REQATTR_NAME = "KeyIdentifier";
+
+ protected boolean mEnabled = false;
+ protected IConfigStore mConfig = null;
+
+ protected boolean mCritical = DEF_CRITICAL;
+ protected String mKeyIdType = DEF_KEYID_TYPE;;
+ protected String mReqAttrName = DEF_REQATTR_NAME;
+
+ protected Vector mInstanceParams = new Vector();
+
+ protected static Vector mDefaultParams = new Vector();
+ static {
+ // form static default params.
+ mDefaultParams.addElement(PROP_CRITICAL + "=" + DEF_CRITICAL);
+ mDefaultParams.addElement(PROP_KEYID_TYPE + "=" + DEF_KEYID_TYPE);
+
+ /*
+ mDefaultParams.addElement(PROP_REQATTR_NAME+"="+DEF_REQATTR_NAME);
+ */
+ }
+
+ public SubjectKeyIdentifierExt() {
+ NAME = "SubjectKeyIdentifierExt";
+ DESC = "Adds Subject Key Idenifier Extension to certs";
+ }
+
+ /**
+ * Initializes this policy rule.
+ * <P>
+ *
+ * The entries may be of the form:
+ *
+ * ca.Policy.rule.<ruleName>.predicate=
+ * ca.Policy.rule.<ruleName>.implName=
+ * ca.Policy.rule.<ruleName>.enable=true
+ *
+ * @param config The config store reference
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ mConfig = config;
+
+ mEnabled = mConfig.getBoolean(
+ IPolicyProcessor.PROP_ENABLE, false);
+ mCritical = mConfig.getBoolean(PROP_CRITICAL, DEF_CRITICAL);
+
+ mKeyIdType = mConfig.getString(PROP_KEYID_TYPE, DEF_KEYID_TYPE);
+
+ /*
+ mReqAttrName = mConfig.getString(PROP_REQATTR_NAME, DEF_REQATTR_NAME);
+ */
+
+ // parse key id type
+ if (mKeyIdType.equalsIgnoreCase(KEYID_TYPE_SHA1))
+ mKeyIdType = KEYID_TYPE_SHA1;
+ else if (mKeyIdType.equalsIgnoreCase(KEYID_TYPE_TYPEFIELD))
+ mKeyIdType = KEYID_TYPE_TYPEFIELD;
+
+ /*
+ else if (mKeyIdType.equalsIgnoreCase(KEYID_TYPE_REQATTR)
+ mKeyIdType = KEYID_TYPE_REQATTR;
+ */
+ else if (mKeyIdType.equalsIgnoreCase(KEYID_TYPE_SPKISHA1))
+ mKeyIdType = KEYID_TYPE_SPKISHA1;
+ else {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("KRA_UNKNOWN_KEY_ID_TYPE", mKeyIdType));
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ PROP_KEYID_TYPE,
+ "value must be one of " +
+ KEYID_TYPE_SHA1 + ", " +
+ KEYID_TYPE_TYPEFIELD + ", " +
+ KEYID_TYPE_SPKISHA1));
+ }
+
+ // form instance params
+ mInstanceParams.addElement(PROP_CRITICAL + "=" + mCritical);
+ mInstanceParams.addElement(PROP_KEYID_TYPE + "=" + mKeyIdType);
+
+ /*
+ mInstanceParams.addElement(PROP_REQATTR_NAME+"="+mReqAttrName);
+ */
+ }
+
+ /**
+ * Adds Subject Key identifier Extension to a certificate.
+ * If the extension is already there, accept it.
+ *
+ * @param req The request on which to apply policy.
+ * @return The policy result object.
+ */
+ public PolicyResult apply(IRequest req) {
+ // get certInfo from request.
+ X509CertInfo[] ci =
+ req.getExtDataInCertInfoArray(IRequest.CERT_INFO);
+
+ if (ci == null || ci[0] == null) {
+ setError(req, CMS.getUserMessage("CMS_POLICY_NO_CERT_INFO"), NAME);
+ return PolicyResult.REJECTED;
+ }
+
+ for (int i = 0; i < ci.length; i++) {
+ PolicyResult certRes = applyCert(req, ci[i]);
+
+ if (certRes == PolicyResult.REJECTED)
+ return certRes;
+ }
+ return PolicyResult.ACCEPTED;
+ }
+
+ public PolicyResult applyCert(IRequest req, X509CertInfo certInfo) {
+
+ try {
+ // if subject key id extension already exists, leave it if approved.
+ SubjectKeyIdentifierExtension subjectKeyIdExt = null;
+ CertificateExtensions extensions = (CertificateExtensions)
+ certInfo.get(X509CertInfo.EXTENSIONS);
+
+ try {
+ if (extensions != null) {
+ subjectKeyIdExt = (SubjectKeyIdentifierExtension)
+ extensions.get(SubjectKeyIdentifierExtension.NAME);
+ }
+ } catch (IOException e) {
+ // extension isn't there.
+ }
+ if (subjectKeyIdExt != null) {
+ if (agentApproved(req)) {
+ CMS.debug(
+ "SubjectKeyIdentifierExt: agent approved request id " + req.getRequestId() +
+ " already has subject key id extension with value " +
+ subjectKeyIdExt);
+ return PolicyResult.ACCEPTED;
+ } else {
+ CMS.debug(
+ "SubjectKeyIdentifierExt: request id from user " + req.getRequestId() +
+ " had subject key identifier - deleted to be replaced");
+ extensions.delete(SubjectKeyIdentifierExtension.NAME);
+ }
+ }
+
+ // create subject key id extension.
+ KeyIdentifier keyId = null;
+
+ try {
+ keyId = formKeyIdentifier(certInfo, req);
+ } catch (EBaseException e) {
+ setPolicyException(req, e);
+ return PolicyResult.REJECTED;
+ }
+ subjectKeyIdExt =
+ new SubjectKeyIdentifierExtension(
+ mCritical, keyId.getIdentifier());
+
+ // add subject key id extension.
+ if (extensions == null) {
+ certInfo.set(X509CertInfo.VERSION,
+ new CertificateVersion(CertificateVersion.V3));
+ extensions = new CertificateExtensions();
+ certInfo.set(X509CertInfo.EXTENSIONS, extensions);
+ }
+ extensions.set(
+ SubjectKeyIdentifierExtension.NAME, subjectKeyIdExt);
+ CMS.debug(
+ "SubjectKeyIdentifierExt: added subject key id ext to request " + req.getRequestId());
+ return PolicyResult.ACCEPTED;
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_UNEXPECTED_POLICY_ERROR,NAME", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, e.getMessage());
+ return PolicyResult.REJECTED;
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("CA_CERT_INFO_ERROR", e.getMessage()));
+ setError(req, CMS.getUserMessage("CMS_POLICY_UNEXPECTED_POLICY_ERROR"),
+ NAME, "Certificate Info Error");
+ return PolicyResult.REJECTED;
+ }
+ }
+
+ /**
+ * Form the Key Identifier in the Subject Key Identifier extension.
+ * <p>
+ * @param certInfo Certificate Info
+ * @param req request
+ * @return A Key Identifier.
+ */
+ protected KeyIdentifier formKeyIdentifier(
+ X509CertInfo certInfo, IRequest req) throws EBaseException {
+ KeyIdentifier keyId = null;
+
+ if (mKeyIdType == KEYID_TYPE_SHA1) {
+ keyId = formSHA1KeyId(certInfo);
+ } else if (mKeyIdType == KEYID_TYPE_TYPEFIELD) {
+ keyId = formTypeFieldKeyId(certInfo);
+ } /*
+ else if (mKeyIdType == KEYID_TYPE_REQATTR) {
+ keyId = formReqAttrKeyId(certInfo, req);
+ }
+ */ else if (mKeyIdType == KEYID_TYPE_SPKISHA1) {
+ keyId = formSpkiSHA1KeyId(certInfo);
+ } else {
+ throw new EBaseException(CMS.getUserMessage("CMS_BASE_INVALID_ATTR_VALUE",
+ mKeyIdType, "Unknown Key Identifier type."));
+ }
+ return keyId;
+ }
+
+ /**
+ * Form key identifier from a type field value of 0100 followed by
+ * the least significate 60 bits of the sha-1 hash of the subject
+ * public key BIT STRING in accordance with RFC 2459.
+ * <p>
+ * @param certInfo - certificate info
+ * @return A Key Identifier with value formulatd as described.
+ */
+
+ protected KeyIdentifier formTypeFieldKeyId(X509CertInfo certInfo)
+ throws EBaseException {
+ KeyIdentifier keyId = null;
+ X509Key key = null;
+
+ try {
+ CertificateX509Key certKey =
+ (CertificateX509Key) certInfo.get(X509CertInfo.KEY);
+
+ if (certKey == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", NAME));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ key = (X509Key) certKey.get(CertificateX509Key.KEY);
+ if (key == null) {
+ log(ILogger.LL_FAILURE, CMS.getLogMessage("POLICY_MISSING_KEY_1", NAME));
+ throw new EPolicyException(CMS.getUserMessage("CMS_POLICY_MISSING_KEY", NAME));
+ }
+ } catch (IOException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_GET_KEY_FROM_CERT", e.toString()));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ } catch (CertificateException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_GET_KEY_FROM_CERT", e.toString()));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ }
+ try {
+ byte[] octetString = new byte[8];
+ MessageDigest md = MessageDigest.getInstance("SHA-1");
+
+ md.update(key.getKey());
+ byte[] hash = md.digest();
+
+ System.arraycopy(hash, hash.length - 8, octetString, 0, 8);
+ octetString[0] &= (0x08f & octetString[0]);
+ keyId = new KeyIdentifier(octetString);
+ } catch (NoSuchAlgorithmException e) {
+ log(ILogger.LL_FAILURE,
+ CMS.getLogMessage("POLICY_ERROR_SUBJECT_KEY_ID_1", NAME));
+ throw new EPolicyException(
+ CMS.getUserMessage("CMS_POLICY_SUBJECT_KEY_ID_ERROR", NAME));
+ }
+ return keyId;
+ }
+
+ /**
+ * Return configured parameters for a policy rule instance.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getInstanceParams() {
+ return mInstanceParams;
+ }
+
+ /**
+ * Return default parameters for a policy implementation.
+ *
+ * @return nvPairs A Vector of name/value pairs.
+ */
+ public Vector getDefaultParams() {
+ return mDefaultParams;
+ }
+
+ /**
+ * Gets extended plugin info for pretty Console displays.
+ */
+ public String[] getExtendedPluginInfo(Locale locale) {
+ String[] params = {
+ PROP_CRITICAL + ";boolean;RFC 2459 recommendation: MUST NOT be marked critical.",
+ PROP_KEYID_TYPE + ";" +
+ "choice(" + KEYID_TYPE_SHA1 + "," +
+ KEYID_TYPE_TYPEFIELD + "," +
+ KEYID_TYPE_SPKISHA1 + ");" +
+ "Method to derive the Key Identifier.",
+ IExtendedPluginInfo.HELP_TOKEN +
+ ";configuration-policyrules-subjectkeyidentifier",
+ IExtendedPluginInfo.HELP_TEXT +
+ ";Adds the Subject Key Identifier extension. See RFC 2459 (4.2.1.2)"
+ };
+
+ return params;
+ }
+}
+