diff --git a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java index db35da16f90..bb93ee5040e 100644 --- a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java +++ b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java @@ -176,54 +176,37 @@ public void derEncode (DerOutputStream out) throws IOException { } if (encodedParams == null) { - // Changes backed out for compatibility with Solaris - - // Several AlgorithmId should omit the whole parameter part when - // it's NULL. They are --- - // RFC 3370 2.1: Implementations SHOULD generate SHA-1 - // AlgorithmIdentifiers with absent parameters. - // RFC 3447 C1: When id-sha1, id-sha224, id-sha256, id-sha384 and - // id-sha512 are used in an AlgorithmIdentifier the parameters - // (which are optional) SHOULD be omitted. - // RFC 3279 2.3.2: The id-dsa algorithm syntax includes optional - // domain parameters... When omitted, the parameters component - // MUST be omitted entirely - // RFC 3370 3.1: When the id-dsa-with-sha1 algorithm identifier - // is used, the AlgorithmIdentifier parameters field MUST be absent. - /*if ( - algid.equals((Object)SHA_oid) || - algid.equals((Object)SHA224_oid) || - algid.equals((Object)SHA256_oid) || - algid.equals((Object)SHA384_oid) || - algid.equals((Object)SHA512_oid) || - algid.equals((Object)SHA512_224_oid) || - algid.equals((Object)SHA512_256_oid) || - algid.equals((Object)SHA3_224_oid) || - algid.equals((Object)SHA3_256_oid) || - algid.equals((Object)SHA3_384_oid) || - algid.equals((Object)SHA3_512_oid) || - algid.equals((Object)DSA_oid) || - algid.equals((Object)sha1WithDSA_oid)) { - ; // no parameter part encoded - } else { - bytes.putNull(); - }*/ - if (algid.equals(RSASSA_PSS_oid) || algid.equals(ed448_oid) - || algid.equals(ed25519_oid) - || algid.equals(x448_oid) - || algid.equals(x25519_oid) - || algid.equals(SHA224withECDSA_oid) - || algid.equals(SHA256withECDSA_oid) - || algid.equals(SHA384withECDSA_oid) - || algid.equals(SHA512withECDSA_oid)) { - // RFC 4055 3.3: when an RSASSA-PSS key does not require - // parameter validation, field is absent. - // RFC 8410 3: for id-X25519, id-X448, id-Ed25519, and - // id-Ed448, the parameters must be absent. - // RFC 5758 3.2: the encoding must omit the parameters field - // for ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384 - // and ecdsa-with-SHA512. - } else { + // MessageDigest algorithms usually have a NULL parameters even + // if most RFCs suggested absent. + // RSA key and signature algorithms requires the NULL parameters + // to be present, see A.1 and A.2.4 of RFC 8017. + if (algid.equals(RSAEncryption_oid) + || algid.equals(MD2_oid) + || algid.equals(MD5_oid) + || algid.equals(SHA_oid) + || algid.equals(SHA224_oid) + || algid.equals(SHA256_oid) + || algid.equals(SHA384_oid) + || algid.equals(SHA512_oid) + || algid.equals(SHA512_224_oid) + || algid.equals(SHA512_256_oid) + || algid.equals(SHA3_224_oid) + || algid.equals(SHA3_256_oid) + || algid.equals(SHA3_384_oid) + || algid.equals(SHA3_512_oid) + || algid.equals(SHA1withRSA_oid) + || algid.equals(SHA224withRSA_oid) + || algid.equals(SHA256withRSA_oid) + || algid.equals(SHA384withRSA_oid) + || algid.equals(SHA512withRSA_oid) + || algid.equals(SHA512$224withRSA_oid) + || algid.equals(SHA512$256withRSA_oid) + || algid.equals(MD2withRSA_oid) + || algid.equals(MD5withRSA_oid) + || algid.equals(SHA3_224withRSA_oid) + || algid.equals(SHA3_256withRSA_oid) + || algid.equals(SHA3_384withRSA_oid) + || algid.equals(SHA3_512withRSA_oid)) { bytes.putNull(); } } else { @@ -662,22 +645,30 @@ private static ConcurrentHashMap collectOIDAliases() { public static final ObjectIdentifier MGF1_oid = ObjectIdentifier.of(KnownOIDs.MGF1); - public static final ObjectIdentifier ed25519_oid = - ObjectIdentifier.of(KnownOIDs.Ed25519); - public static final ObjectIdentifier ed448_oid = - ObjectIdentifier.of(KnownOIDs.Ed448); - - public static final ObjectIdentifier x25519_oid = - ObjectIdentifier.of(KnownOIDs.X25519); - public static final ObjectIdentifier x448_oid = - ObjectIdentifier.of(KnownOIDs.X448); - - public static final ObjectIdentifier SHA224withECDSA_oid = - ObjectIdentifier.of(KnownOIDs.SHA224withECDSA); - public static final ObjectIdentifier SHA256withECDSA_oid = - ObjectIdentifier.of(KnownOIDs.SHA256withECDSA); - public static final ObjectIdentifier SHA384withECDSA_oid = - ObjectIdentifier.of(KnownOIDs.SHA384withECDSA); - public static final ObjectIdentifier SHA512withECDSA_oid = - ObjectIdentifier.of(KnownOIDs.SHA512withECDSA); + public static final ObjectIdentifier SHA1withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA1withRSA); + public static final ObjectIdentifier SHA224withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA224withRSA); + public static final ObjectIdentifier SHA256withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA256withRSA); + public static final ObjectIdentifier SHA384withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA384withRSA); + public static final ObjectIdentifier SHA512withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA512withRSA); + public static final ObjectIdentifier SHA512$224withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA512$224withRSA); + public static final ObjectIdentifier SHA512$256withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA512$256withRSA); + public static final ObjectIdentifier MD2withRSA_oid = + ObjectIdentifier.of(KnownOIDs.MD2withRSA); + public static final ObjectIdentifier MD5withRSA_oid = + ObjectIdentifier.of(KnownOIDs.MD5withRSA); + public static final ObjectIdentifier SHA3_224withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA3_224withRSA); + public static final ObjectIdentifier SHA3_256withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA3_256withRSA); + public static final ObjectIdentifier SHA3_384withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA3_384withRSA); + public static final ObjectIdentifier SHA3_512withRSA_oid = + ObjectIdentifier.of(KnownOIDs.SHA3_512withRSA); } diff --git a/test/jdk/sun/security/x509/AlgorithmId/NullParams.java b/test/jdk/sun/security/x509/AlgorithmId/NullParams.java new file mode 100644 index 00000000000..733ab9fa522 --- /dev/null +++ b/test/jdk/sun/security/x509/AlgorithmId/NullParams.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2023, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8301793 + * @summary AlgorithmId should not encode a missing parameters field as NULL unless hardcoded + * @modules java.base/sun.security.x509 + * java.base/sun.security.util + */ + +import sun.security.util.DerInputStream; +import sun.security.util.DerValue; +import sun.security.x509.AlgorithmId; + +public class NullParams { + + static boolean failed = false; + + public static void main(String[] args) throws Exception { + + // Full new list: must have NULL + test("MD2", true); + test("MD5", true); + test("SHA-1", true); + test("SHA-224", true); + test("SHA-256", true); + test("SHA-384", true); + test("SHA-512", true); + test("SHA-512/224", true); + test("SHA-512/256", true); + test("SHA3-224", true); + test("SHA3-256", true); + test("SHA3-384", true); + test("SHA3-512", true); + test("RSA", true); + test("MD2withRSA", true); + test("MD5withRSA", true); + test("SHA1withRSA", true); + test("SHA224withRSA", true); + test("SHA256withRSA", true); + test("SHA384withRSA", true); + test("SHA512/224withRSA", true); + test("SHA512/256withRSA", true); + test("SHA512withRSA", true); + test("SHA3-224withRSA", true); + test("SHA3-256withRSA", true); + test("SHA3-384withRSA", true); + test("SHA3-512withRSA", true); + + // Full old list: must be absent + test("SHA1withECDSA", false); + test("SHA224withECDSA", false); + test("SHA256withECDSA", false); + test("SHA384withECDSA", false); + test("SHA512withECDSA", false); + test("Ed25519", false); + test("Ed448", false); + test("X25519", false); + test("X448", false); + test("RSASSA-PSS", false); + + // Others + test("DSA", false); + test("SHA1withDSA", false); + test("HmacSHA1", false); + + if (failed) { + throw new RuntimeException("At least one failed"); + } + } + + static void test(String name, boolean hasNull) throws Exception { + System.out.printf("%20s ", name); + AlgorithmId aid = AlgorithmId.get(name); + byte[] encoding = aid.encode(); + DerValue v = new DerValue(encoding); + DerInputStream data = v.data(); + data.getOID(); + if (hasNull) { + if (data.available() == 0) { + System.out.println("NULL missing"); + failed = true; + return; + } + } else { + if (data.available() != 0) { + System.out.println("Has unexpected NULL"); + failed = true; + return; + } + } + System.out.println("OK"); + } +}