diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java index 4dee4336a8c..1cfdccb49e4 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java @@ -23,6 +23,12 @@ * questions. */ +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2023, 2023 All Rights Reserved + * =========================================================================== + */ + package sun.security.pkcs11; import java.io.*; @@ -103,6 +109,9 @@ public List run() { // name of the PKCS#11 library private String library; + // name of the PKCS#11 token to use + private String tokenLabel; + // description to pass to the provider class private String description; @@ -227,6 +236,10 @@ String getLibrary() { return library; } + String getTokenLabel() { + return tokenLabel; + } + String getDescription() { if (description != null) { return description; @@ -499,9 +512,16 @@ private void parse() throws IOException { case "nssOptimizeSpace"-> nssOptimizeSpace = parseBooleanEntry(st.sval); default-> - throw new ConfigurationException - ("Unknown keyword '" + st.sval + "', line " + - st.lineno()); + { + if ("tokenLabel".equalsIgnoreCase(st.sval)) { + st.sval = "tokenLabel"; + tokenLabel = parseStringEntry(st.sval); + } else { + throw new ConfigurationException + ("Unknown keyword '" + st.sval + "', line " + + st.lineno()); + } + } } parsedKeywords.add(st.sval); } diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java index b561011ab9e..4e305363924 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java @@ -23,6 +23,12 @@ * questions. */ +/* + * =========================================================================== + * (c) Copyright IBM Corp. 2023, 2023 All Rights Reserved + * =========================================================================== + */ + package sun.security.pkcs11; import java.io.IOException; @@ -162,6 +168,15 @@ final class P11Signature extends SignatureSpi { // than 1024 bits", but this is a little arbitrary private static final int RAW_ECDSA_MAX = 128; + // Check if running on z platform. + private static final boolean isZ; + static { + String arch = System.getProperty("os.arch"); + isZ = "s390".equalsIgnoreCase(arch) || "s390x".equalsIgnoreCase(arch); + } + + // Elliptic Curve key size in bits. + private int ecKeySize; P11Signature(Token token, String algorithm, long mechanism) throws NoSuchAlgorithmException, PKCS11Exception { @@ -473,6 +488,14 @@ protected void engineInitVerify(PublicKey publicKey) if (publicKey == null) { throw new InvalidKeyException("Key must not be null"); } + + // Check if the public key is EC public key to keep its key size. + if (publicKey instanceof ECPublicKey ecPublicKey) { + ecKeySize = ecPublicKey.getParams().getCurve().getField().getFieldSize(); + } else { + ecKeySize = 0; // Otherwise reset the ecKeySize parameter. + } + // Need to check key length whenever a new key is set if (publicKey != p11Key) { checkKeySize(keyAlgorithm, publicKey); @@ -843,7 +866,7 @@ private static byte[] asn1ToDSA(byte[] sig, int sigLen) } } - private static byte[] asn1ToECDSA(byte[] sig) throws SignatureException { + private byte[] asn1ToECDSA(byte[] sig) throws SignatureException { try { // Enforce strict DER checking for signatures DerInputStream in = new DerInputStream(sig, 0, sig.length, false); @@ -861,7 +884,12 @@ private static byte[] asn1ToECDSA(byte[] sig) throws SignatureException { // trim leading zeroes byte[] br = KeyUtil.trimZeroes(r.toByteArray()); byte[] bs = KeyUtil.trimZeroes(s.toByteArray()); - int k = Math.max(br.length, bs.length); + int k; + if (isZ && (ecKeySize > 0)) { + k = (ecKeySize + 7) / 8; + } else { + k = Math.max(br.length, bs.length); + } // r and s each occupy half the array byte[] res = new byte[k << 1]; System.arraycopy(br, 0, res, k - br.length, br.length); diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java index b884108ae06..b813d60b705 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -78,6 +78,14 @@ public final class SunPKCS11 extends AuthProvider { private static final long serialVersionUID = -1354835039035306505L; static final Debug debug = Debug.getInstance("sunpkcs11"); + + // Check if running on z platform. + private static final boolean isZ; + static { + String arch = System.getProperty("os.arch"); + isZ = "s390".equalsIgnoreCase(arch) || "s390x".equalsIgnoreCase(arch); + } + // the PKCS11 object through which we make the native calls @SuppressWarnings("serial") // Type of field is not Serializable; // see writeReplace @@ -172,6 +180,7 @@ private static T checkNull(T obj) { } String library = config.getLibrary(); + String tokenLabel = config.getTokenLabel(); String functionList = config.getFunctionList(); long slotID = config.getSlotID(); int slotListIndex = config.getSlotListIndex(); @@ -378,12 +387,40 @@ private static T checkNull(T obj) { System.out.println(p11Info); } - if ((slotID < 0) || showInfo) { + if ((slotID < 0) || showInfo || (tokenLabel != null)) { long[] slots = p11.C_GetSlotList(false); if (showInfo) { - System.out.println("All slots: " + toString(slots)); - slots = p11.C_GetSlotList(true); - System.out.println("Slots with tokens: " + toString(slots)); + if (isZ) { + System.out.println("Slots[slotID, tokenName]:"); + for (int i = 0; i < slots.length; i++) { + System.out.println("[" + i + ", " + new String(p11.C_GetTokenInfo(slots[i]).label).trim() + "]"); + } + } else { + System.out.println("All slots: " + toString(slots)); + slots = p11.C_GetSlotList(true); + System.out.println("Slots with tokens: " + toString(slots)); + } + } + /* TokenLabel is only supported on Z architecture platforms. It is null otherwise. */ + if (tokenLabel != null) { + boolean found = false; + for (int i = 0; i < slots.length; i++) { + try { + String label = new String(p11.C_GetTokenInfo(slots[i]).label).trim(); + if (tokenLabel.equalsIgnoreCase(label)) { + slotID = -1; + slotListIndex = i; + found = true; + break; + } + } catch (PKCS11Exception ex) { + // ignore + } + } + if (!found) { + throw new IOException("Invalid Token Label : " + + tokenLabel); + } } if (slotID < 0) { if ((slotListIndex < 0)