JDK-8250970 : Deprecate "denigrated" java.security.cert APIs that represent DNs as Principal or String objects
  • Type: CSR
  • Component: security-libs
  • Sub-Component: java.security
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 16
  • Submitted: 2020-08-03
  • Updated: 2020-08-24
  • Resolved: 2020-08-24
Related Reports
CSR :  
Description
Summary
-------

Deprecate "denigrated" java.security.cert APIs that represent DNs as Principal or String objects.

Problem
-------

8 java.security.cert API methods use the term "denigrated" to discourage developers from using methods that take/return Distinguished Names as Principal or String objects. All of them contain warnings as to why the methods are not recommended and point to other methods that should be used instead that take/return an X500Principal. The "denigrated" term is not a common or accepted term used in Java APIs, and in each of these cases, deprecating the methods is the better approach as it will provide compile-time warnings to developers to help them avoid or transition away from these APIs.

There is no plan to remove these APIs at this time. Although they are discouraged, they are not hazardous and have been in the platform for a long time, so removing them would be a much higher compatibility risk.

Solution
--------

Deprecate and remove the "denigrated" term from the the following APIs:

`java.security.cert.X509Certificate.getIssuerDN()`
`java.security.cert.X509Certificate.getSubjectDN()`
`java.security.cert.X509CRL.getIssuerDN()`
`java.security.cert.X509CertSelector.setIssuer(String)`
`java.security.cert.X509CertSelector.setSubject(String)`
`java.security.cert.X509CertSelector.getIssuerAsString()`
`java.security.cert.X509CertSelector.getSubjectAsString()`
`java.security.cert.X509CRLSelector.addIssuerName(String)`

Specification
-------------
```
--- old/src/java.base/share/classes/java/security/cert/X509Certificate.java	2020-08-03 14:21:43.000000000 -0400
+++ new/src/java.base/share/classes/java/security/cert/X509Certificate.java	2020-08-03 14:21:42.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -197,12 +197,6 @@
     public abstract BigInteger getSerialNumber();
 
     /**
-     * <strong>Denigrated</strong>, replaced by {@linkplain
-     * #getIssuerX500Principal()}. This method returns the {@code issuer}
-     * as an implementation specific Principal object, which should not be
-     * relied upon by portable code.
-     *
-     * <p>
      * Gets the {@code issuer} (issuer distinguished name) value from
      * the certificate. The issuer name identifies the entity that signed (and
      * issued) the certificate.
@@ -234,7 +228,13 @@
      * {@code TeletexString} or {@code UniversalString}.
      *
      * @return a Principal whose name is the issuer distinguished name.
+     *
+     * @deprecated Use {@link #getIssuerX500Principal} instead. This method
+     * returns the {@code issuer} as an implementation specific
+     * {@code Principal} object, which should not be relied upon by portable
+     * code.
      */
+    @Deprecated(since="16")
     public abstract Principal getIssuerDN();
 
     /**
@@ -255,12 +255,6 @@
     }
 
     /**
-     * <strong>Denigrated</strong>, replaced by {@linkplain
-     * #getSubjectX500Principal()}. This method returns the {@code subject}
-     * as an implementation specific Principal object, which should not be
-     * relied upon by portable code.
-     *
-     * <p>
      * Gets the {@code subject} (subject distinguished name) value
      * from the certificate.  If the {@code subject} value is empty,
      * then the {@code getName()} method of the returned
@@ -275,7 +269,13 @@
      * and other relevant definitions.
      *
      * @return a Principal whose name is the subject name.
+     *
+     * @deprecated Use {@link #getSubjectX500Principal} instead. This method
+     * returns the {@code subject} as an implementation specific
+     * {@code Principal} object, which should not be relied upon by portable
+     * code.
      */
+    @Deprecated(since="16")
     public abstract Principal getSubjectDN();
 
     /**
```
```
--- old/src/java.base/share/classes/java/security/cert/X509CRL.java	2020-08-03 14:21:39.000000000 -0400
+++ new/src/java.base/share/classes/java/security/cert/X509CRL.java	2020-08-03 14:21:39.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -279,12 +279,6 @@
     public abstract int getVersion();
 
     /**
-     * <strong>Denigrated</strong>, replaced by {@linkplain
-     * #getIssuerX500Principal()}. This method returns the {@code issuer}
-     * as an implementation specific Principal object, which should not be
-     * relied upon by portable code.
-     *
-     * <p>
      * Gets the {@code issuer} (issuer distinguished name) value from
      * the CRL. The issuer name identifies the entity that signed (and
      * issued) the CRL.
@@ -316,7 +310,13 @@
      * {@code TeletexString} or {@code UniversalString}.
      *
      * @return a Principal whose name is the issuer distinguished name.
+     *
+     * @deprecated Use {@link #getIssuerX500Principal} instead. This method
+     * returns the {@code issuer} as an implementation specific
+     * {@code Principal} object, which should not be relied upon by portable
+     * code.
      */
+    @Deprecated(since="16")
     public abstract Principal getIssuerDN();
 
     /**
```
```
--- old/src/java.base/share/classes/java/security/cert/X509CertSelector.java	2020-08-03 14:21:42.000000000 -0400
+++ new/src/java.base/share/classes/java/security/cert/X509CertSelector.java	2020-08-03 14:21:41.000000000 -0400
@@ -46,13 +46,14 @@
  * getBasicConstraints} method). Therefore, the {@link #match match}
  * method would return {@code true} for any {@code X509Certificate}.
  * Typically, several criteria are enabled (by calling
- * {@link #setIssuer setIssuer} or
+ * {@link #setIssuer(X500Principal) setIssuer} or
  * {@link #setKeyUsage setKeyUsage}, for instance) and then the
  * {@code X509CertSelector} is passed to
  * {@link CertStore#getCertificates CertStore.getCertificates} or some similar
  * method.
  * <p>
- * Several criteria can be enabled (by calling {@link #setIssuer setIssuer}
+ * Several criteria can be enabled (by calling
+ * {@link #setIssuer(X500Principal) setIssuer}
  * and {@link #setSerialNumber setSerialNumber},
  * for example) such that the {@code match} method
  * usually uniquely matches a single {@code X509Certificate}. We say
@@ -184,13 +185,6 @@
     }
 
     /**
-     * <strong>Denigrated</strong>, use {@linkplain #setIssuer(X500Principal)}
-     * or {@linkplain #setIssuer(byte[])} instead. This method should not be
-     * relied on as it can fail to match some certificates because of a loss of
-     * encoding information in the
-     * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a> String form
-     * of some distinguished names.
-     * <p>
      * Sets the issuer criterion. The specified distinguished name
      * must match the issuer distinguished name in the
      * {@code X509Certificate}. If {@code null}, any issuer
@@ -202,7 +196,15 @@
      * @param issuerDN a distinguished name in RFC 2253 format
      *                 (or {@code null})
      * @throws IOException if a parsing error occurs (incorrect form for DN)
+     *
+     * @deprecated Use {@link #setIssuer(X500Principal)} or
+     * {@link #setIssuer(byte[])} instead. This method should not be relied on
+     * as it can fail to match some certificates because of a loss of encoding
+     * information in the
+     * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a> String form
+     * of some distinguished names.
      */
+    @Deprecated(since="16")
     public void setIssuer(String issuerDN) throws IOException {
         if (issuerDN == null) {
             issuer = null;
@@ -276,12 +278,6 @@
     }
 
     /**
-     * <strong>Denigrated</strong>, use {@linkplain #setSubject(X500Principal)}
-     * or {@linkplain #setSubject(byte[])} instead. This method should not be
-     * relied on as it can fail to match some certificates because of a loss of
-     * encoding information in the RFC 2253 String form of some distinguished
-     * names.
-     * <p>
      * Sets the subject criterion. The specified distinguished name
      * must match the subject distinguished name in the
      * {@code X509Certificate}. If {@code null}, any subject
@@ -293,7 +289,14 @@
      * @param subjectDN a distinguished name in RFC 2253 format
      *                  (or {@code null})
      * @throws IOException if a parsing error occurs (incorrect form for DN)
+     *
+     * @deprecated Use {@link #setSubject(X500Principal)} or
+     * {@link #setSubject(byte[])} instead. This method should not be relied
+     * on as it can fail to match some certificates because of a loss of
+     * encoding information in the RFC 2253 String form of some distinguished
+     * names.
      */
+    @Deprecated(since="16")
     public void setSubject(String subjectDN) throws IOException {
         if (subjectDN == null) {
             subject = null;
@@ -311,7 +314,7 @@
      * If {@code subjectDN} is not {@code null}, it should contain a
      * single DER encoded distinguished name, as defined in X.501. For the ASN.1
      * notation for this structure, see
-     * {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}.
+     * {@link #setIssuer(byte[]) setIssuer(byte[] issuerDN)}.
      *
      * @param subjectDN a byte array containing the distinguished name in
      *                  ASN.1 DER format (or {@code null})
@@ -1299,12 +1302,6 @@
     }
 
     /**
-     * <strong>Denigrated</strong>, use {@linkplain #getIssuer()} or
-     * {@linkplain #getIssuerAsBytes()} instead. This method should not be
-     * relied on as it can fail to match some certificates because of a loss of
-     * encoding information in the RFC 2253 String form of some distinguished
-     * names.
-     * <p>
      * Returns the issuer criterion as a {@code String}. This
      * distinguished name must match the issuer distinguished name in the
      * {@code X509Certificate}. If {@code null}, the issuer criterion
@@ -1315,7 +1312,13 @@
      *
      * @return the required issuer distinguished name in RFC 2253 format
      *         (or {@code null})
+     *
+     * @deprecated Use {@link #getIssuer()} or {@link #getIssuerAsBytes()}
+     * instead. This method should not be relied on as it can fail to match
+     * some certificates because of a loss of encoding information in the
+     * RFC 2253 String form of some distinguished names.
      */
+    @Deprecated(since="16")
     public String getIssuerAsString() {
         return (issuer == null ? null : issuer.getName());
     }
@@ -1330,7 +1333,7 @@
      * array containing a single DER encoded distinguished name, as defined in
      * X.501. The ASN.1 notation for this structure is supplied in the
      * documentation for
-     * {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}.
+     * {@link #setIssuer(byte[]) setIssuer(byte[] issuerDN)}.
      * <p>
      * Note that the byte array returned is cloned to protect against
      * subsequent modifications.
@@ -1358,12 +1361,6 @@
     }
 
     /**
-     * <strong>Denigrated</strong>, use {@linkplain #getSubject()} or
-     * {@linkplain #getSubjectAsBytes()} instead. This method should not be
-     * relied on as it can fail to match some certificates because of a loss of
-     * encoding information in the RFC 2253 String form of some distinguished
-     * names.
-     * <p>
      * Returns the subject criterion as a {@code String}. This
      * distinguished name must match the subject distinguished name in the
      * {@code X509Certificate}. If {@code null}, the subject criterion
@@ -1374,7 +1371,13 @@
      *
      * @return the required subject distinguished name in RFC 2253 format
      *         (or {@code null})
+     *
+     * @deprecated Use {@link #getSubject()} or {@link #getSubjectAsBytes()}
+     * instead. This method should not be relied on as it can fail to match
+     * some certificates because of a loss of encoding information in the
+     * RFC 2253 String form of some distinguished names.
      */
+    @Deprecated(since="16")
     public String getSubjectAsString() {
         return (subject == null ? null : subject.getName());
     }
@@ -1389,7 +1392,7 @@
      * array containing a single DER encoded distinguished name, as defined in
      * X.501. The ASN.1 notation for this structure is supplied in the
      * documentation for
-     * {@link #setSubject(byte [] subjectDN) setSubject(byte [] subjectDN)}.
+     * {@link #setSubject(byte[]) setSubject(byte[] subjectDN)}.
      * <p>
      * Note that the byte array returned is cloned to protect against
      * subsequent modifications.
@@ -1985,7 +1988,7 @@
         if (debug != null) {
             debug.println("X509CertSelector.match(SN: "
                 + (xcert.getSerialNumber()).toString(16) + "\n  Issuer: "
-                + xcert.getIssuerDN() + "\n  Subject: " + xcert.getSubjectDN()
+                + xcert.getIssuerX500Principal() + "\n  Subject: " + xcert.getSubjectX500Principal()
                 + ")");
         }
```
```
--- old/src/java.base/share/classes/java/security/cert/X509CRLSelector.java	2020-08-03 14:21:40.000000000 -0400
+++ new/src/java.base/share/classes/java/security/cert/X509CRLSelector.java	2020-08-03 14:21:40.000000000 -0400
@@ -225,13 +225,6 @@
     }
 
     /**
-     * <strong>Denigrated</strong>, use
-     * {@linkplain #addIssuer(X500Principal)} or
-     * {@linkplain #addIssuerName(byte[])} instead. This method should not be
-     * relied on as it can fail to match some CRLs because of a loss of
-     * encoding information in the RFC 2253 String form of some distinguished
-     * names.
-     * <p>
      * Adds a name to the issuerNames criterion. The issuer distinguished
      * name in the {@code X509CRL} must match at least one of the specified
      * distinguished names.
@@ -243,7 +236,14 @@
      *
      * @param name the name in RFC 2253 form
      * @throws IOException if a parsing error occurs
+     *
+     * @deprecated Use {@link #addIssuer(X500Principal)} or
+     * {@link #addIssuerName(byte[])} instead. This method should not be
+     * relied on as it can fail to match some CRLs because of a loss of
+     * encoding information in the RFC 2253 String form of some distinguished
+     * names.
      */
+    @Deprecated(since="16")
     public void addIssuerName(String name) throws IOException {
         addIssuerNameInternal(name, new X500Name(name).asX500Principal());
     }
```

Comments
Moving to Approved.
24-08-2020