mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-11 13:05:45 +00:00
8383608: Make BinaryEncodable non-exhaustive
Reviewed-by: mullan
This commit is contained in:
parent
132072077a
commit
dc4bb5acbe
@ -32,15 +32,35 @@ import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import jdk.internal.javac.PreviewFeature;
|
||||
import sun.security.internal.InternalBinaryEncodable;
|
||||
|
||||
|
||||
/**
|
||||
* This interface is implemented by security API classes that contain
|
||||
* binary-encodable cryptographic material.
|
||||
* This interface identifies the cryptographic objects that can be converted
|
||||
* to and from binary data, and thereby encoded and decoded as PEM text.
|
||||
*
|
||||
* <p> This sealed interface may evolve. When using {@code switch}, always include a
|
||||
* {@code default} case rather than relying on the classes specified in the
|
||||
* {@code permits} clause to remain fixed. An exhaustive {@code switch} may
|
||||
* result in a {@link MatchException}.
|
||||
* <p> The APIs for cryptographic objects such as public keys, private keys,
|
||||
* certificates, and certificate revocation lists all provide the means to
|
||||
* convert their instances to and from standardized binary representations.
|
||||
* Other kinds of cryptographic objects, such as certificate requests, have
|
||||
* no corresponding API but can still be expressed as standardized binary
|
||||
* representations. The {@code BinaryEncodable} interface allows the
|
||||
* {@link PEMEncoder} and {@link PEMDecoder} classes to operate uniformly on
|
||||
* binary representations of key or certificate material.
|
||||
*
|
||||
* <p> The permitted subtype {@code PEM} is notable for supporting the encoding
|
||||
* and decoding of PEM text that represents cryptographic objects for which no
|
||||
* API exists. In future releases, other permitted subtypes may be added to
|
||||
* support the encoding and decoding of such cryptographic objects.
|
||||
*
|
||||
* <p> The list of permitted subtypes shown after {@code permits} is not
|
||||
* exhaustive. This means if application code switches over a
|
||||
* {@code BinaryEncodable} value, the {@code switch} cannot be made exhaustive
|
||||
* simply by providing a {@code case} label for every permitted subtype shown
|
||||
* in the list; there also must be a {@code default} or
|
||||
* {@code case BinaryEncodable} label to handle additional subtypes. This
|
||||
* allows the list of permitted subtypes to change over time without causing
|
||||
* pre-existing switches to fail because of an unrecognized subtype.
|
||||
*
|
||||
* @see AsymmetricKey
|
||||
* @see KeyPair
|
||||
@ -57,5 +77,5 @@ import jdk.internal.javac.PreviewFeature;
|
||||
@PreviewFeature(feature = PreviewFeature.Feature.PEM_API)
|
||||
public sealed interface BinaryEncodable permits AsymmetricKey, KeyPair,
|
||||
PKCS8EncodedKeySpec, X509EncodedKeySpec, EncryptedPrivateKeyInfo,
|
||||
X509Certificate, X509CRL, PEM {
|
||||
X509Certificate, X509CRL, PEM, InternalBinaryEncodable {
|
||||
}
|
||||
|
||||
@ -48,10 +48,10 @@ import java.util.Objects;
|
||||
* PEM is a textual encoding used to store and transfer cryptographic
|
||||
* objects, such as asymmetric keys, certificates, and certificate revocation
|
||||
* lists (CRLs). It is defined in RFC 1421 and RFC 7468. PEM consists of
|
||||
* Base64-encoded content enclosed by a type-identifying header
|
||||
* and footer.
|
||||
* Base64-encoded content enclosed by a header and footer that identify the
|
||||
* type of the content.
|
||||
*
|
||||
* <p>The {@link #decode(String)} and {@link #decode(InputStream)} methods
|
||||
* <p> The {@link #decode(String)} and {@link #decode(InputStream)} methods
|
||||
* return an instance of a class that matches the PEM type and implements
|
||||
* {@link BinaryEncodable}, as follows:
|
||||
* <ul>
|
||||
@ -70,11 +70,18 @@ import java.util.Objects;
|
||||
* </ul>
|
||||
*
|
||||
* <p> If the PEM type has no corresponding class, {@code decode(String)} and
|
||||
* {@code decode(InputStream)} will return a {@code PEM} object.
|
||||
* {@code decode(InputStream)} return a {@code PEM} object.
|
||||
*
|
||||
* <p> If application code switches over the {@code BinaryEncodable} result of
|
||||
* {@link #decode(String)} or {@link #decode(InputStream)}, the {@code switch} cannot
|
||||
* be made exhaustive simply by providing a {@code case} label for every permitted
|
||||
* subtype listed for {@code BinaryEncodable}; there also must be a {@code default}
|
||||
* or {@code case BinaryEncodable} label to handle additional subtypes that
|
||||
* might be added in the future.
|
||||
*
|
||||
* <p> The {@link #decode(String, Class)} and {@link #decode(InputStream, Class)}
|
||||
* methods accept a class parameter specifying the desired {@code BinaryEncodable}
|
||||
* type. These methods avoid the need for casting and are useful when multiple
|
||||
* methods accept a parameter specifying the desired {@code BinaryEncodable}
|
||||
* result. These methods avoid the need for casting and are useful when multiple
|
||||
* representations are possible. For example, if the PEM contains both public and
|
||||
* private keys, specifying {@code PrivateKey.class} returns only the private key.
|
||||
* If {@code X509EncodedKeySpec.class} is provided, the public key encoding is
|
||||
@ -109,11 +116,6 @@ import java.util.Objects;
|
||||
* for decryption, an {@link EncryptedPrivateKeyInfo} is returned.
|
||||
* A {@code PEMDecoder} configured for decryption can also decode unencrypted PEM.
|
||||
*
|
||||
* <p> The {@code BinaryEncodable} interface may evolve. When using a decode method
|
||||
* with {@code switch}, always include a {@code default} case rather than
|
||||
* relying on the classes specified in the permits clause to remain fixed.
|
||||
* An exhaustive {@code switch} may result in a {@link MatchException}.
|
||||
*
|
||||
* <p> This class is immutable and thread-safe.
|
||||
*
|
||||
* <p> Example: decode a private key:
|
||||
@ -136,6 +138,7 @@ import java.util.Objects;
|
||||
* @see PEMEncoder
|
||||
* @see PEM
|
||||
* @see EncryptedPrivateKeyInfo
|
||||
* @see BinaryEncodable
|
||||
*
|
||||
* @spec https://www.rfc-editor.org/info/rfc1421
|
||||
* RFC 1421: Privacy Enhancement for Internet Electronic Mail
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package sun.security.internal;
|
||||
|
||||
import java.security.BinaryEncodable;
|
||||
|
||||
/**
|
||||
* This class is a non-public subtype of BinaryEncodable. This type
|
||||
* allows the BinaryEncodable list of permitted subtypes to change
|
||||
* over time without causing pre-existing switches to fail because of an
|
||||
* unrecognized subtype.
|
||||
*/
|
||||
|
||||
public final class InternalBinaryEncodable implements BinaryEncodable {
|
||||
private InternalBinaryEncodable() {}
|
||||
}
|
||||
67
test/jdk/sun/security/internal/CheckIBE.java
Normal file
67
test/jdk/sun/security/internal/CheckIBE.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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 8383608
|
||||
* @summary check that InternalBinaryEncodable exists
|
||||
* @enablePreview
|
||||
* @modules java.base/sun.security.internal
|
||||
* @run main CheckIBE
|
||||
*/
|
||||
|
||||
import javax.crypto.EncryptedPrivateKeyInfo;
|
||||
import java.security.AsymmetricKey;
|
||||
import java.security.BinaryEncodable;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PEM;
|
||||
import java.security.cert.X509CRL;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import sun.security.internal.InternalBinaryEncodable;
|
||||
|
||||
/*
|
||||
* This test verifies that BinaryEncodable has the expected set of permitted
|
||||
* subtypes, including InternalBinaryEncodable. If this switch stops compiling,
|
||||
* update the cases to match the BinaryEncodable permits list.
|
||||
*/
|
||||
|
||||
public class CheckIBE {
|
||||
public static void main(String[] args) {
|
||||
BinaryEncodable be = new PEM("TEST", "TEST");
|
||||
|
||||
switch (be) {
|
||||
case AsymmetricKey ignored -> {}
|
||||
case KeyPair ignored -> {}
|
||||
case PKCS8EncodedKeySpec ignored -> {}
|
||||
case X509EncodedKeySpec ignored -> {}
|
||||
case EncryptedPrivateKeyInfo ignored -> {}
|
||||
case X509Certificate ignored -> {}
|
||||
case X509CRL ignored -> {}
|
||||
case PEM ignored -> {}
|
||||
case InternalBinaryEncodable ignored -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
test/jdk/sun/security/internal/ExhaustiveBE.java
Normal file
65
test/jdk/sun/security/internal/ExhaustiveBE.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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 8383608
|
||||
* @summary verify switches over BinaryEncodable are not exhaustive
|
||||
* @enablePreview
|
||||
* @compile/fail ExhaustiveBE.java
|
||||
*/
|
||||
|
||||
import javax.crypto.EncryptedPrivateKeyInfo;
|
||||
import java.security.AsymmetricKey;
|
||||
import java.security.BinaryEncodable;
|
||||
import java.security.KeyPair;
|
||||
import java.security.PEM;
|
||||
import java.security.cert.X509CRL;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
/*
|
||||
* This test verifies that application code cannot exhaustively switch over
|
||||
* BinaryEncodable by naming only the public permitted subtypes. Compilation
|
||||
* must fail because application code needs a default case, or a
|
||||
* BinaryEncodable case, to cover the internal permitted subtype
|
||||
* InternalBinaryEncodable.
|
||||
*/
|
||||
|
||||
public class ExhaustiveBE {
|
||||
public static void main(String[] args) {
|
||||
BinaryEncodable be = new PEM("TEST", "TEST");
|
||||
|
||||
switch (be) {
|
||||
case AsymmetricKey ignored -> {}
|
||||
case KeyPair ignored -> {}
|
||||
case PKCS8EncodedKeySpec ignored -> {}
|
||||
case X509EncodedKeySpec ignored -> {}
|
||||
case EncryptedPrivateKeyInfo ignored -> {}
|
||||
case X509Certificate ignored -> {}
|
||||
case X509CRL ignored -> {}
|
||||
case PEM ignored -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user