From f00d72510775ab18d0ec47d704fb36ae9eeccf5f Mon Sep 17 00:00:00 2001 From: Bob Du Date: Tue, 7 Feb 2023 14:32:16 -0500 Subject: [PATCH] tokenLabel support and EC fixes for Z platform - tokenLabel keyword support - APAR IJ09107 - Point does not match field size Exception for EC curve Signed-off-by: Bob Du --- .../classes/sun/security/pkcs11/Config.java | 25 +++++++++-- .../sun/security/pkcs11/P11Signature.java | 32 ++++++++++++- .../sun/security/pkcs11/SunPKCS11.java | 45 +++++++++++++++++-- 3 files changed, 93 insertions(+), 9 deletions(-) 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 70e69d9b877..5d796a9396c 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; @@ -500,9 +513,15 @@ 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)) { + tokenLabel = parseStringEntry("tokenLabel"); + } 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 e262d95c67f..0f65d3feb86 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 { @@ -468,6 +483,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); @@ -830,7 +853,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); @@ -848,7 +871,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 d4605fd1855..d18ad43313e 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 @@ -79,6 +79,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 @@ -171,6 +179,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(); @@ -377,12 +386,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)