Skip to content

8301793: AlgorithmId should not encode a missing parameters field as NULL unless hardcoded #3615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 57 additions & 66 deletions src/java.base/share/classes/sun/security/x509/AlgorithmId.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -662,22 +645,30 @@ private static ConcurrentHashMap<String, String> 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);
}
115 changes: 115 additions & 0 deletions test/jdk/sun/security/x509/AlgorithmId/NullParams.java
Original file line number Diff line number Diff line change
@@ -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");
}
}