diff options
| author | alee <alee@c9f7a03b-bd48-0410-a16d-cbbf54688b0b> | 2008-08-14 14:50:44 +0000 |
|---|---|---|
| committer | alee <alee@c9f7a03b-bd48-0410-a16d-cbbf54688b0b> | 2008-08-14 14:50:44 +0000 |
| commit | 4bb94b38ec0ddf48b2f9c12bebe65c1b2116da0d (patch) | |
| tree | f08493804c4e52a9a8063f4de33c3d4436852f83 | |
| parent | ce49e144fb0368cb842d58e5c2c959ca7ee34626 (diff) | |
Fix for Bug 458499: UniqueSubjectName plugin for plugins does not account for revoked certs
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/trunk@109 c9f7a03b-bd48-0410-a16d-cbbf54688b0b
3 files changed, 119 insertions, 4 deletions
diff --git a/pki/base/common/src/UserMessages_en.properties b/pki/base/common/src/UserMessages_en.properties index 26edcd0d8..1ea7ebd88 100644 --- a/pki/base/common/src/UserMessages_en.properties +++ b/pki/base/common/src/UserMessages_en.properties @@ -740,6 +740,7 @@ CMS_PROFILE_DUPLICATE_KEY=Public key duplication detected CMS_PROFILE_ENCODING_ERROR=Error in BER encoding CMS_PROFILE_REVOKE_DUPKEY_CERT=Revoke certificate with duplicate key CMS_PROFILE_CONFIG_ALLOW_SAME_KEY_RENEWAL=Allow renewal of certification with same keys +CMS_PROFILE_CONFIG_KEY_USAGE_EXTENSION_CHECKING=Allow duplicate subject names with different key usage for agent approved requests CMS_PROFILE_INTERNAL_ERROR=Profile internal error: {0} CMS_PROFILE_DENY_OPERATION=Not authorized to do this operation. CMS_PROFILE_DELETE_ENABLEPROFILE=Cannot delete enabled profile: {0} diff --git a/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java b/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java index abdc0b177..0250530ad 100644 --- a/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java +++ b/pki/base/common/src/com/netscape/cms/profile/constraint/UniqueSubjectNameConstraint.java @@ -41,7 +41,12 @@ import netscape.security.x509.*; */ public class UniqueSubjectNameConstraint extends EnrollConstraint { + public static final String CONFIG_KEY_USAGE_EXTENSION_CHECKING = + "enableKeyUsageExtensionChecking"; + private boolean mKeyUsageExtensionChecking = true; + public UniqueSubjectNameConstraint() { + addConfigName(CONFIG_KEY_USAGE_EXTENSION_CHECKING); } public void init(IProfile profile, IConfigStore config) @@ -50,6 +55,10 @@ public class UniqueSubjectNameConstraint extends EnrollConstraint { } public IDescriptor getConfigDescriptor(Locale locale, String name) { + if (name.equals(CONFIG_KEY_USAGE_EXTENSION_CHECKING)) { + return new Descriptor(IDescriptor.BOOLEAN, null, "true", + CMS.getUserMessage(locale, "CMS_PROFILE_CONFIG_KEY_USAGE_EXTENSION_CHECKING")); + } return null; } @@ -57,16 +66,79 @@ public class UniqueSubjectNameConstraint extends EnrollConstraint { return null; } + /** + * 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; + } + + /** * Validates the request. The request is not modified * during the validation. + * + * Rules are as follows: + * If the subject name is not unique, then the request will be rejected unless: + * 1. the certificate is expired or expired_revoked + * 2. the certificate is revoked and the revocation reason is not "on hold" + * 3. the keyUsageExtension bits are different and enableKeyUsageExtensionChecking=true (default) */ public void validate(IRequest request, X509CertInfo info) throws ERejectException { CMS.debug("UniqueSubjectNameConstraint: validate start"); CertificateSubjectName sn = null; IAuthority authority = (IAuthority)CMS.getSubsystem("ca"); - + + mKeyUsageExtensionChecking = getConfigBoolean(CONFIG_KEY_USAGE_EXTENSION_CHECKING); ICertificateRepository certdb = null; if (authority != null && authority instanceof ICertificateAuthority) { ICertificateAuthority ca = (ICertificateAuthority)authority; @@ -95,18 +167,58 @@ public class UniqueSubjectNameConstraint extends EnrollConstraint { } catch (EBaseException e) { CMS.debug("UniqueSubjectNameConstraint exception: "+e.toString()); } - if (sameSubjRecords != null && sameSubjRecords.hasMoreElements()) { + while (sameSubjRecords != null && sameSubjRecords.hasMoreElements()) { + ICertRecord rec = (ICertRecord) sameSubjRecords.nextElement(); + String status = rec.getStatus(); + + IRevocationInfo revocationInfo = rec.getRevocationInfo(); + RevocationReason reason = null; + + if (revocationInfo != null) { + CRLExtensions crlExts = revocationInfo.getCRLEntryExtensions(); + + if (crlExts != null) { + Enumeration enumx = crlExts.getElements(); + + while (enumx.hasMoreElements()) { + Extension ext = (Extension) enumx.nextElement(); + + if (ext instanceof CRLReasonExtension) { + reason = ((CRLReasonExtension) ext).getReason(); + } + } + } + } + + if (status.equals(ICertRecord.STATUS_EXPIRED) || status.equals(ICertRecord.STATUS_REVOKED_EXPIRED)) { + continue; + } + + if (status.equals(ICertRecord.STATUS_REVOKED) && reason != null && + (! reason.equals(RevocationReason.CERTIFICATE_HOLD))) { + continue; + } + + if (mKeyUsageExtensionChecking && !sameKeyUsageExtension(rec, info)) { + continue; + } + throw new ERejectException( CMS.getUserMessage(getLocale(request), "CMS_PROFILE_SUBJECT_NAME_NOT_UNIQUE", certsubjectname)); } } + CMS.debug("UniqueSubjectNameConstraint: validate end"); } public String getText(Locale locale) { + String params[] = { + getConfig(CONFIG_KEY_USAGE_EXTENSION_CHECKING) + }; return CMS.getUserMessage(locale, - "CMS_PROFILE_CONSTRAINT_UNIQUE_SUBJECT_NAME_TEXT"); + "CMS_PROFILE_CONSTRAINT_UNIQUE_SUBJECT_NAME_TEXT", + params); } public boolean isApplicable(IPolicyDefault def) { diff --git a/pki/linux/common/pki-common.spec b/pki/linux/common/pki-common.spec index df7dec0c9..676084971 100644 --- a/pki/linux/common/pki-common.spec +++ b/pki/linux/common/pki-common.spec @@ -33,7 +33,7 @@ ## Package Header Definitions %define base_name %{base_prefix}-%{base_component} %define base_version 1.0.0 -%define base_release 16 +%define base_release 17 %define base_group System Environment/Base %define base_vendor Red Hat, Inc. %define base_license GPLv2 with exceptions @@ -298,6 +298,8 @@ chmod 00755 %{_datadir}/%{base_prefix}/setup/postinstall ############################################################################### %changelog +* Wed Aug 13 2008 Ade Lee <alee@redhat.com> 1.0.0-17 +- Fix for Bug 458499: UniqueSubjectName plugin for plugins does not account for revoked certs * Fri Aug 8 2008 Andrew Wnuk <awnuk@redhat.com> 1.0.0-16 - Fix for Bug 453834. * Thu Aug 7 2008 Jack Magne <jmagne@redhat.com> 1.0.0-15 |
