mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8296442: EncryptedPrivateKeyInfo can be created with an uninitialized AlgorithmParameters
Reviewed-by: xuelei, kdriver, mullan
This commit is contained in:
parent
37848a9ca2
commit
68d3ed5cee
6 changed files with 128 additions and 72 deletions
|
@ -57,17 +57,20 @@ import sun.security.util.DerOutputStream;
|
||||||
|
|
||||||
public class EncryptedPrivateKeyInfo {
|
public class EncryptedPrivateKeyInfo {
|
||||||
|
|
||||||
// the "encryptionAlgorithm" field
|
// The "encryptionAlgorithm" is stored in either the algid or
|
||||||
|
// the params field. Precisely, if this object is created by
|
||||||
|
// {@link #EncryptedPrivateKeyInfo(AlgorithmParameters, byte[])}
|
||||||
|
// with an uninitialized AlgorithmParameters, the AlgorithmParameters
|
||||||
|
// object is stored in the params field and algid is set to null.
|
||||||
|
// In all other cases, algid is non null and params is null.
|
||||||
private final AlgorithmId algid;
|
private final AlgorithmId algid;
|
||||||
|
private final AlgorithmParameters params;
|
||||||
// the algorithm name of the encrypted private key
|
|
||||||
private String keyAlg;
|
|
||||||
|
|
||||||
// the "encryptedData" field
|
// the "encryptedData" field
|
||||||
private final byte[] encryptedData;
|
private final byte[] encryptedData;
|
||||||
|
|
||||||
// the ASN.1 encoded contents of this class
|
// the ASN.1 encoded contents of this class
|
||||||
private byte[] encoded;
|
private final byte[] encoded;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs (i.e., parses) an {@code EncryptedPrivateKeyInfo} from
|
* Constructs (i.e., parses) an {@code EncryptedPrivateKeyInfo} from
|
||||||
|
@ -100,6 +103,7 @@ public class EncryptedPrivateKeyInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.algid = AlgorithmId.parse(seq[0]);
|
this.algid = AlgorithmId.parse(seq[0]);
|
||||||
|
this.params = null;
|
||||||
if (seq[0].data.available() != 0) {
|
if (seq[0].data.available() != 0) {
|
||||||
throw new IOException("encryptionAlgorithm field overrun");
|
throw new IOException("encryptionAlgorithm field overrun");
|
||||||
}
|
}
|
||||||
|
@ -141,6 +145,7 @@ public class EncryptedPrivateKeyInfo {
|
||||||
throw new NullPointerException("the algName parameter " +
|
throw new NullPointerException("the algName parameter " +
|
||||||
"must be non-null");
|
"must be non-null");
|
||||||
this.algid = AlgorithmId.get(algName);
|
this.algid = AlgorithmId.get(algName);
|
||||||
|
this.params = null;
|
||||||
|
|
||||||
if (encryptedData == null) {
|
if (encryptedData == null) {
|
||||||
throw new NullPointerException("the encryptedData " +
|
throw new NullPointerException("the encryptedData " +
|
||||||
|
@ -181,7 +186,22 @@ public class EncryptedPrivateKeyInfo {
|
||||||
if (algParams == null) {
|
if (algParams == null) {
|
||||||
throw new NullPointerException("algParams must be non-null");
|
throw new NullPointerException("algParams must be non-null");
|
||||||
}
|
}
|
||||||
this.algid = AlgorithmId.get(algParams);
|
AlgorithmId tmp;
|
||||||
|
try {
|
||||||
|
tmp = AlgorithmId.get(algParams);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// This exception is thrown when algParams.getEncoded() fails.
|
||||||
|
// While the spec of this constructor requires that
|
||||||
|
// "getEncoded should return...", in reality people might
|
||||||
|
// create with an uninitialized algParams first and only
|
||||||
|
// initialize it before calling getEncoded(). Thus we support
|
||||||
|
// this case as well.
|
||||||
|
tmp = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// one and only one is non null
|
||||||
|
this.algid = tmp;
|
||||||
|
this.params = this.algid != null ? null : algParams;
|
||||||
|
|
||||||
if (encryptedData == null) {
|
if (encryptedData == null) {
|
||||||
throw new NullPointerException("encryptedData must be non-null");
|
throw new NullPointerException("encryptedData must be non-null");
|
||||||
|
@ -197,7 +217,6 @@ public class EncryptedPrivateKeyInfo {
|
||||||
this.encoded = null;
|
this.encoded = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the encryption algorithm.
|
* Returns the encryption algorithm.
|
||||||
* <p>Note: Standard name is returned instead of the specified one
|
* <p>Note: Standard name is returned instead of the specified one
|
||||||
|
@ -209,7 +228,7 @@ public class EncryptedPrivateKeyInfo {
|
||||||
* @return the encryption algorithm name.
|
* @return the encryption algorithm name.
|
||||||
*/
|
*/
|
||||||
public String getAlgName() {
|
public String getAlgName() {
|
||||||
return this.algid.getName();
|
return algid == null ? params.getAlgorithm() : algid.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -217,7 +236,7 @@ public class EncryptedPrivateKeyInfo {
|
||||||
* @return the algorithm parameters.
|
* @return the algorithm parameters.
|
||||||
*/
|
*/
|
||||||
public AlgorithmParameters getAlgParameters() {
|
public AlgorithmParameters getAlgParameters() {
|
||||||
return this.algid.getParameters();
|
return algid == null ? params : algid.getParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -252,14 +271,13 @@ public class EncryptedPrivateKeyInfo {
|
||||||
byte[] encoded;
|
byte[] encoded;
|
||||||
try {
|
try {
|
||||||
encoded = cipher.doFinal(encryptedData);
|
encoded = cipher.doFinal(encryptedData);
|
||||||
checkPKCS8Encoding(encoded);
|
return pkcs8EncodingToSpec(encoded);
|
||||||
} catch (GeneralSecurityException |
|
} catch (GeneralSecurityException |
|
||||||
IOException |
|
IOException |
|
||||||
IllegalStateException ex) {
|
IllegalStateException ex) {
|
||||||
throw new InvalidKeySpecException(
|
throw new InvalidKeySpecException(
|
||||||
"Cannot retrieve the PKCS8EncodedKeySpec", ex);
|
"Cannot retrieve the PKCS8EncodedKeySpec", ex);
|
||||||
}
|
}
|
||||||
return new PKCS8EncodedKeySpec(encoded, keyAlg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PKCS8EncodedKeySpec getKeySpecImpl(Key decryptKey,
|
private PKCS8EncodedKeySpec getKeySpecImpl(Key decryptKey,
|
||||||
|
@ -270,13 +288,13 @@ public class EncryptedPrivateKeyInfo {
|
||||||
try {
|
try {
|
||||||
if (provider == null) {
|
if (provider == null) {
|
||||||
// use the most preferred one
|
// use the most preferred one
|
||||||
c = Cipher.getInstance(algid.getName());
|
c = Cipher.getInstance(getAlgName());
|
||||||
} else {
|
} else {
|
||||||
c = Cipher.getInstance(algid.getName(), provider);
|
c = Cipher.getInstance(getAlgName(), provider);
|
||||||
}
|
}
|
||||||
c.init(Cipher.DECRYPT_MODE, decryptKey, algid.getParameters());
|
c.init(Cipher.DECRYPT_MODE, decryptKey, getAlgParameters());
|
||||||
encoded = c.doFinal(encryptedData);
|
encoded = c.doFinal(encryptedData);
|
||||||
checkPKCS8Encoding(encoded);
|
return pkcs8EncodingToSpec(encoded);
|
||||||
} catch (NoSuchAlgorithmException nsae) {
|
} catch (NoSuchAlgorithmException nsae) {
|
||||||
// rethrow
|
// rethrow
|
||||||
throw nsae;
|
throw nsae;
|
||||||
|
@ -284,7 +302,6 @@ public class EncryptedPrivateKeyInfo {
|
||||||
throw new InvalidKeyException(
|
throw new InvalidKeyException(
|
||||||
"Cannot retrieve the PKCS8EncodedKeySpec", ex);
|
"Cannot retrieve the PKCS8EncodedKeySpec", ex);
|
||||||
}
|
}
|
||||||
return new PKCS8EncodedKeySpec(encoded, keyAlg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -388,14 +405,23 @@ public class EncryptedPrivateKeyInfo {
|
||||||
DerOutputStream tmp = new DerOutputStream();
|
DerOutputStream tmp = new DerOutputStream();
|
||||||
|
|
||||||
// encode encryption algorithm
|
// encode encryption algorithm
|
||||||
|
if (algid != null) {
|
||||||
algid.encode(tmp);
|
algid.encode(tmp);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// Let's hope params has been initialized by now.
|
||||||
|
AlgorithmId.get(params).encode(tmp);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException("not initialized", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// encode encrypted data
|
// encode encrypted data
|
||||||
tmp.putOctetString(encryptedData);
|
tmp.putOctetString(encryptedData);
|
||||||
|
|
||||||
// wrap everything into a SEQUENCE
|
// wrap everything into a SEQUENCE
|
||||||
out.write(DerValue.tag_Sequence, tmp);
|
out.write(DerValue.tag_Sequence, tmp);
|
||||||
this.encoded = out.toByteArray();
|
return out.toByteArray();
|
||||||
}
|
}
|
||||||
return this.encoded.clone();
|
return this.encoded.clone();
|
||||||
}
|
}
|
||||||
|
@ -409,7 +435,7 @@ public class EncryptedPrivateKeyInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("fallthrough")
|
@SuppressWarnings("fallthrough")
|
||||||
private void checkPKCS8Encoding(byte[] encodedKey)
|
private static PKCS8EncodedKeySpec pkcs8EncodingToSpec(byte[] encodedKey)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
DerInputStream in = new DerInputStream(encodedKey);
|
DerInputStream in = new DerInputStream(encodedKey);
|
||||||
DerValue[] values = in.getSequence(3);
|
DerValue[] values = in.getSequence(3);
|
||||||
|
@ -420,9 +446,9 @@ public class EncryptedPrivateKeyInfo {
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case 3:
|
case 3:
|
||||||
checkTag(values[0], DerValue.tag_Integer, "version");
|
checkTag(values[0], DerValue.tag_Integer, "version");
|
||||||
keyAlg = AlgorithmId.parse(values[1]).getName();
|
String keyAlg = AlgorithmId.parse(values[1]).getName();
|
||||||
checkTag(values[2], DerValue.tag_OctetString, "privateKey");
|
checkTag(values[2], DerValue.tag_OctetString, "privateKey");
|
||||||
break;
|
return new PKCS8EncodedKeySpec(encodedKey, keyAlg);
|
||||||
default:
|
default:
|
||||||
throw new IOException("invalid key encoding");
|
throw new IOException("invalid key encoding");
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,36 +116,6 @@ class MacData {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MacData(AlgorithmParameters algParams, byte[] digest,
|
|
||||||
byte[] salt, int iterations) throws NoSuchAlgorithmException
|
|
||||||
{
|
|
||||||
if (algParams == null)
|
|
||||||
throw new NullPointerException("the algParams parameter " +
|
|
||||||
"must be non-null");
|
|
||||||
|
|
||||||
AlgorithmId algid = AlgorithmId.get(algParams);
|
|
||||||
this.digestAlgorithmName = algid.getName();
|
|
||||||
this.digestAlgorithmParams = algid.getParameters();
|
|
||||||
|
|
||||||
if (digest == null) {
|
|
||||||
throw new NullPointerException("the digest " +
|
|
||||||
"parameter must be non-null");
|
|
||||||
} else if (digest.length == 0) {
|
|
||||||
throw new IllegalArgumentException("the digest " +
|
|
||||||
"parameter must not be empty");
|
|
||||||
} else {
|
|
||||||
this.digest = digest.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.macSalt = salt;
|
|
||||||
this.iterations = iterations;
|
|
||||||
|
|
||||||
// delay the generation of ASN.1 encoding until
|
|
||||||
// getEncoded() is called
|
|
||||||
this.encoded = null;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
String getDigestAlgName() {
|
String getDigestAlgName() {
|
||||||
return digestAlgorithmName;
|
return digestAlgorithmName;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,6 +100,8 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||||
*
|
*
|
||||||
* @param oid the identifier for the algorithm.
|
* @param oid the identifier for the algorithm.
|
||||||
* @param algparams the associated algorithm parameters, can be null.
|
* @param algparams the associated algorithm parameters, can be null.
|
||||||
|
* @exception IllegalStateException if algparams is not initialized
|
||||||
|
* or cannot be encoded
|
||||||
*/
|
*/
|
||||||
public AlgorithmId(ObjectIdentifier oid, AlgorithmParameters algparams) {
|
public AlgorithmId(ObjectIdentifier oid, AlgorithmParameters algparams) {
|
||||||
algid = oid;
|
algid = oid;
|
||||||
|
@ -108,9 +110,9 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||||
try {
|
try {
|
||||||
encodedParams = algParams.getEncoded();
|
encodedParams = algParams.getEncoded();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
// Ignore this at the moment. This exception can occur
|
throw new IllegalStateException(
|
||||||
// if AlgorithmParameters was not initialized yet. Will
|
"AlgorithmParameters not initialized or cannot be decoded",
|
||||||
// try to re-getEncoded() again later.
|
ioe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,17 +159,11 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||||
* @exception IOException on encoding error.
|
* @exception IOException on encoding error.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void encode (DerOutputStream out) throws IOException {
|
public void encode(DerOutputStream out) throws IOException {
|
||||||
DerOutputStream bytes = new DerOutputStream();
|
DerOutputStream bytes = new DerOutputStream();
|
||||||
|
|
||||||
bytes.putOID(algid);
|
bytes.putOID(algid);
|
||||||
|
|
||||||
// Re-getEncoded() from algParams if it was not initialized
|
|
||||||
if (algParams != null && encodedParams == null) {
|
|
||||||
encodedParams = algParams.getEncoded();
|
|
||||||
// If still not initialized. Let the IOE be thrown.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (encodedParams == null) {
|
if (encodedParams == null) {
|
||||||
// Changes backed out for compatibility with Solaris
|
// Changes backed out for compatibility with Solaris
|
||||||
|
|
||||||
|
@ -488,6 +484,8 @@ public class AlgorithmId implements Serializable, DerEncoder {
|
||||||
*
|
*
|
||||||
* @param algparams the associated algorithm parameters.
|
* @param algparams the associated algorithm parameters.
|
||||||
* @exception NoSuchAlgorithmException on error.
|
* @exception NoSuchAlgorithmException on error.
|
||||||
|
* @exception IllegalStateException if algparams is not initialized
|
||||||
|
* or cannot be encoded
|
||||||
*/
|
*/
|
||||||
public static AlgorithmId get(AlgorithmParameters algparams)
|
public static AlgorithmId get(AlgorithmParameters algparams)
|
||||||
throws NoSuchAlgorithmException {
|
throws NoSuchAlgorithmException {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,16 +23,11 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 4941596
|
* @bug 4941596 8296442
|
||||||
* @summary Test the EncryptedPrivateKeyInfo.getAlgName(...) methods.
|
* @summary Test the EncryptedPrivateKeyInfo.getAlgName(...) methods.
|
||||||
* @author Valerie Peng
|
* @author Valerie Peng
|
||||||
*/
|
*/
|
||||||
import java.util.*;
|
|
||||||
import java.nio.*;
|
|
||||||
import java.io.*;
|
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.security.spec.*;
|
|
||||||
import javax.crypto.*;
|
import javax.crypto.*;
|
||||||
import javax.crypto.spec.*;
|
import javax.crypto.spec.*;
|
||||||
|
|
||||||
|
@ -61,8 +56,18 @@ public class GetAlgName {
|
||||||
AlgorithmParameters ap = c.getParameters();
|
AlgorithmParameters ap = c.getParameters();
|
||||||
epki = new EncryptedPrivateKeyInfo(ap, BYTES);
|
epki = new EncryptedPrivateKeyInfo(ap, BYTES);
|
||||||
if (!epki.getAlgName().equalsIgnoreCase(algo)) {
|
if (!epki.getAlgName().equalsIgnoreCase(algo)) {
|
||||||
System.out.println("...expect: " + algo);
|
System.out.println("...expected: " + algo);
|
||||||
System.out.println("...got: " + epki.getAlgName());
|
System.out.println(" ...got: " + epki.getAlgName());
|
||||||
|
status = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure EncryptedPrivateKeyInfo can be created with an
|
||||||
|
// uninitialized AlgorithmParameters.
|
||||||
|
AlgorithmParameters ap2 = AlgorithmParameters.getInstance(ap.getAlgorithm());
|
||||||
|
epki = new EncryptedPrivateKeyInfo(ap2, BYTES);
|
||||||
|
if (!epki.getAlgName().equalsIgnoreCase(algo)) {
|
||||||
|
System.out.println("...expected: " + algo);
|
||||||
|
System.out.println(" ...got: " + epki.getAlgName());
|
||||||
status = false;
|
status = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 8261779
|
* @bug 8261779 8296442
|
||||||
* @summary Check that EncryptedPrivateKeyInfo.getEncoded() calls
|
* @summary Check that EncryptedPrivateKeyInfo.getEncoded() calls
|
||||||
* AlgorithmParameters.getEncoded() when first called
|
* AlgorithmParameters.getEncoded() when first called
|
||||||
*/
|
*/
|
||||||
|
@ -56,6 +56,14 @@ public class GetEncoded {
|
||||||
AlgorithmParameters ap1 = AlgorithmParameters.getInstance("EC");
|
AlgorithmParameters ap1 = AlgorithmParameters.getInstance("EC");
|
||||||
EncryptedPrivateKeyInfo epki1 =
|
EncryptedPrivateKeyInfo epki1 =
|
||||||
new EncryptedPrivateKeyInfo(ap1, new byte[] {1, 2, 3, 4});
|
new EncryptedPrivateKeyInfo(ap1, new byte[] {1, 2, 3, 4});
|
||||||
|
|
||||||
|
try {
|
||||||
|
epki1.getEncoded();
|
||||||
|
throw new Exception("Should have thrown IOException");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// test passed, expected exception
|
||||||
|
}
|
||||||
|
|
||||||
ap1.init(new ECGenParameterSpec("secp256r1"));
|
ap1.init(new ECGenParameterSpec("secp256r1"));
|
||||||
|
|
||||||
EncryptedPrivateKeyInfo epki2 =
|
EncryptedPrivateKeyInfo epki2 =
|
||||||
|
|
49
test/jdk/sun/security/x509/AlgorithmId/Uninitialized.java
Normal file
49
test/jdk/sun/security/x509/AlgorithmId/Uninitialized.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, 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 8296442
|
||||||
|
* @summary EncryptedPrivateKeyInfo can be created with an uninitialized AlgorithmParameters
|
||||||
|
* @modules java.base/sun.security.x509
|
||||||
|
*/
|
||||||
|
|
||||||
|
import sun.security.x509.AlgorithmId;
|
||||||
|
|
||||||
|
import java.security.AlgorithmParameters;
|
||||||
|
|
||||||
|
public class Uninitialized {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
AlgorithmParameters ap = AlgorithmParameters.getInstance("EC");
|
||||||
|
boolean success;
|
||||||
|
try {
|
||||||
|
AlgorithmId.get(ap);
|
||||||
|
success = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
if (success) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue