Skip to content
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

8255409: Support the new C_GetInterfaceList, C_GetInterface, and C_SessionCancel APIs in PKCS#11 v3.0 #6655

Closed
wants to merge 5 commits into from
Closed
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
147 changes: 81 additions & 66 deletions src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ private static void debug(Object o) {
// name of the C function that returns the PKCS#11 functionlist
// This option primarily exists for the deprecated
// Secmod.Module.getProvider() method.
private String functionList = "C_GetFunctionList";
private String functionList = null;

// whether to use NSS secmod mode. Implicitly set if nssLibraryDirectory,
// nssSecmodDirectory, or nssModule is specified.
Expand Down Expand Up @@ -311,6 +311,12 @@ boolean getAllowSingleThreadedModules() {
}

String getFunctionList() {
if (functionList == null) {
// defaults to "C_GetFunctionList" for NSS secmod
if (nssUseSecmod || nssUseSecmodTrust) {
return "C_GetFunctionList";
}
}
return functionList;
}

Expand Down Expand Up @@ -408,67 +414,73 @@ private void parse() throws IOException {
if (token != TT_WORD) {
throw excToken("Unexpected token:");
}
String word = st.sval;
if (word.equals("name")) {
name = parseStringEntry(word);
} else if (word.equals("library")) {
library = parseLibrary(word);
} else if (word.equals("description")) {
parseDescription(word);
} else if (word.equals("slot")) {
parseSlotID(word);
} else if (word.equals("slotListIndex")) {
parseSlotListIndex(word);
} else if (word.equals("enabledMechanisms")) {
parseEnabledMechanisms(word);
} else if (word.equals("disabledMechanisms")) {
parseDisabledMechanisms(word);
} else if (word.equals("attributes")) {
parseAttributes(word);
} else if (word.equals("handleStartupErrors")) {
parseHandleStartupErrors(word);
} else if (word.endsWith("insertionCheckInterval")) {
insertionCheckInterval = parseIntegerEntry(word);
switch (st.sval) {
case "name"->
name = parseStringEntry(st.sval);
case "library"->
library = parseLibrary(st.sval);
case "description"->
parseDescription(st.sval);
case "slot"->
parseSlotID(st.sval);
case "slotListIndex"->
parseSlotListIndex(st.sval);
case "enabledMechanisms"->
parseEnabledMechanisms(st.sval);
case "disabledMechanisms"->
parseDisabledMechanisms(st.sval);
case "attributes"->
parseAttributes(st.sval);
case "handleStartupErrors"->
parseHandleStartupErrors(st.sval);
case "insertionCheckInterval"-> {
insertionCheckInterval = parseIntegerEntry(st.sval);
if (insertionCheckInterval < 100) {
throw excLine(word + " must be at least 100 ms");
throw excLine(st.sval + " must be at least 100 ms");
}
} else if (word.equals("cleaner.shortInterval")) {
resourceCleanerShortInterval = parseIntegerEntry(word);
}
case "cleaner.shortInterval"-> {
resourceCleanerShortInterval = parseIntegerEntry(st.sval);
if (resourceCleanerShortInterval < 1_000) {
throw excLine(word + " must be at least 1000 ms");
throw excLine(st.sval + " must be at least 1000 ms");
}
} else if (word.equals("cleaner.longInterval")) {
resourceCleanerLongInterval = parseIntegerEntry(word);
}
case "cleaner.longInterval"-> {
resourceCleanerLongInterval = parseIntegerEntry(st.sval);
if (resourceCleanerLongInterval < 1_000) {
throw excLine(word + " must be at least 1000 ms");
throw excLine(st.sval + " must be at least 1000 ms");
}
} else if (word.equals("destroyTokenAfterLogout")) {
destroyTokenAfterLogout = parseBooleanEntry(word);
} else if (word.equals("showInfo")) {
showInfo = parseBooleanEntry(word);
} else if (word.equals("keyStoreCompatibilityMode")) {
keyStoreCompatibilityMode = parseBooleanEntry(word);
} else if (word.equals("explicitCancel")) {
explicitCancel = parseBooleanEntry(word);
} else if (word.equals("omitInitialize")) {
omitInitialize = parseBooleanEntry(word);
} else if (word.equals("allowSingleThreadedModules")) {
allowSingleThreadedModules = parseBooleanEntry(word);
} else if (word.equals("functionList")) {
functionList = parseStringEntry(word);
} else if (word.equals("nssUseSecmod")) {
nssUseSecmod = parseBooleanEntry(word);
} else if (word.equals("nssLibraryDirectory")) {
nssLibraryDirectory = parseLibrary(word);
}
case "destroyTokenAfterLogout"->
destroyTokenAfterLogout = parseBooleanEntry(st.sval);
case "showInfo"->
showInfo = parseBooleanEntry(st.sval);
case "keyStoreCompatibilityMode"->
keyStoreCompatibilityMode = parseBooleanEntry(st.sval);
case "explicitCancel"->
explicitCancel = parseBooleanEntry(st.sval);
case "omitInitialize"->
omitInitialize = parseBooleanEntry(st.sval);
case "allowSingleThreadedModules"->
allowSingleThreadedModules = parseBooleanEntry(st.sval);
case "functionList"->
functionList = parseStringEntry(st.sval);
case "nssUseSecmod"->
nssUseSecmod = parseBooleanEntry(st.sval);
case "nssLibraryDirectory"-> {
nssLibraryDirectory = parseLibrary(st.sval);
nssUseSecmod = true;
} else if (word.equals("nssSecmodDirectory")) {
nssSecmodDirectory = expand(parseStringEntry(word));
}
case "nssSecmodDirectory"-> {
nssSecmodDirectory = expand(parseStringEntry(st.sval));
nssUseSecmod = true;
} else if (word.equals("nssModule")) {
nssModule = parseStringEntry(word);
}
case "nssModule"-> {
nssModule = parseStringEntry(st.sval);
nssUseSecmod = true;
} else if (word.equals("nssDbMode")) {
String mode = parseStringEntry(word);
}
case "nssDbMode"-> {
String mode = parseStringEntry(st.sval);
if (mode.equals("readWrite")) {
nssDbMode = Secmod.DbMode.READ_WRITE;
} else if (mode.equals("readOnly")) {
Expand All @@ -479,22 +491,25 @@ private void parse() throws IOException {
throw excToken("nssDbMode must be one of readWrite, readOnly, and noDb:");
}
nssUseSecmod = true;
} else if (word.equals("nssNetscapeDbWorkaround")) {
nssNetscapeDbWorkaround = parseBooleanEntry(word);
}
case "nssNetscapeDbWorkaround"-> {
nssNetscapeDbWorkaround = parseBooleanEntry(st.sval);
nssUseSecmod = true;
} else if (word.equals("nssArgs")) {
parseNSSArgs(word);
} else if (word.equals("nssUseSecmodTrust")) {
nssUseSecmodTrust = parseBooleanEntry(word);
} else if (word.equals("useEcX963Encoding")) {
useEcX963Encoding = parseBooleanEntry(word);
} else if (word.equals("nssOptimizeSpace")) {
nssOptimizeSpace = parseBooleanEntry(word);
} else {
}
case "nssArgs"->
parseNSSArgs(st.sval);
case "nssUseSecmodTrust"->
nssUseSecmodTrust = parseBooleanEntry(st.sval);
case "useEcX963Encoding"->
useEcX963Encoding = parseBooleanEntry(st.sval);
case "nssOptimizeSpace"->
nssOptimizeSpace = parseBooleanEntry(st.sval);
default->
throw new ConfigurationException
("Unknown keyword '" + word + "', line " + st.lineno());
("Unknown keyword '" + st.sval + "', line " +
st.lineno());
}
parsedKeywords.add(word);
parsedKeywords.add(st.sval);
}
reader.close();
reader = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,13 @@ private void implInit(int opmode, Key key, byte[] iv, int tagLen,
}

private void cancelOperation() {
// cancel operation by finishing it; avoid killSession as some
token.ensureValid();
if (P11Util.trySessionCancel(token, session,
(encrypt ? CKF_ENCRYPT : CKF_DECRYPT))) {
return;
}

// cancel by finishing operations; avoid killSession as some
// hardware vendors may require re-login
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new cancelOperation() methods seems identical everywhere. Is it possible to consolidate it to a helper method like trySessionCancel(token, session, flags)? It can return true if canceled successfully, false if needs a fallback, and can still throw a ProviderException.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you mean the if-() block of code? I can move the code into a helper method inside the P11Util class.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, just keep duplicated lines as few as possible.

int bufLen = doFinalLength(0);
byte[] buffer = new byte[bufLen];
Expand Down Expand Up @@ -453,7 +459,7 @@ private void initialize() throws PKCS11Exception {

token.ensureValid();

byte[] aad = (aadBuffer.size() > 0? aadBuffer.toByteArray() : null);
byte[] aad = (aadBuffer.size() > 0 ? aadBuffer.toByteArray() : null);

long p11KeyID = p11Key.getKeyID();
try {
Expand Down Expand Up @@ -507,7 +513,7 @@ private int doFinalLength(int inLen) {
result -= tagLen;
}
}
return (result > 0? result : 0);
return (result > 0 ? result : 0);
}

// reset the states to the pre-initialized values
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,14 @@ private void reset(boolean doCancel) {

private void cancelOperation() {
token.ensureValid();
// cancel operation by finishing it; avoid killSession as some
// hardware vendors may require re-login

if (P11Util.trySessionCancel(token, session,
(encrypt ? CKF_ENCRYPT : CKF_DECRYPT))) {
return;
}

// cancel by finishing operations; avoid killSession as
// some hardware vendors may require re-login
try {
int bufLen = doFinalLength(0);
byte[] buffer = new byte[bufLen];
Expand All @@ -458,7 +464,7 @@ private void cancelOperation() {
} catch (PKCS11Exception e) {
if (e.match(CKR_OPERATION_NOT_INITIALIZED)) {
// Cancel Operation may be invoked after an error on a PKCS#11
// call. If the operation inside the token was already cancelled,
// call. If the operation inside the token is already cancelled,
// do not fail here. This is part of a defensive mechanism for
// PKCS#11 libraries that do not strictly follow the standard.
return;
Expand Down Expand Up @@ -488,7 +494,7 @@ private void initialize() throws PKCS11Exception {
if (session == null) {
session = token.getOpSession();
}
CK_MECHANISM mechParams = (blockMode == MODE_CTR?
CK_MECHANISM mechParams = (blockMode == MODE_CTR ?
new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) :
new CK_MECHANISM(mechanism, iv));
if (encrypt) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ private enum KeyWrapType {
String[] algoParts = algorithm.split("/");
if (algoParts[0].startsWith("AES")) {
int index = algoParts[0].indexOf('_');
fixedKeySize = (index == -1? -1 :
fixedKeySize = (index == -1 ? -1 :
// should be well-formed since we specify what we support
Integer.parseInt(algoParts[0].substring(index+1)) >> 3);
try {
Expand Down Expand Up @@ -180,7 +180,7 @@ protected byte[] engineGetIV() {
protected AlgorithmParameters engineGetParameters() {
// KW and KWP uses but not require parameters, return the default
// IV when no IV is supplied by caller
byte[] iv = (this.iv == null? type.defIv : this.iv);
byte[] iv = (this.iv == null ? type.defIv : this.iv);

AlgorithmParameterSpec spec = new IvParameterSpec(iv);
try {
Expand Down Expand Up @@ -213,7 +213,7 @@ protected void engineInit(int opmode, Key key,
("Only IvParameterSpec is supported");
}

byte[] ivValue = (params == null? null :
byte[] ivValue = (params == null ? null :
((IvParameterSpec)params).getIV());

implInit(opmode, key, ivValue, sr);
Expand Down Expand Up @@ -285,7 +285,14 @@ private void implInit(int opmode, Key key, byte[] iv, SecureRandom sr)
}

private void cancelOperation() {
// cancel operation by finishing it; avoid killSession as some
token.ensureValid();

if (P11Util.trySessionCancel(token, session,
(opmode == Cipher.ENCRYPT_MODE ? CKF_ENCRYPT : CKF_DECRYPT))) {
return;
}

// cancel by finishing operations; avoid killSession as some
// hardware vendors may require re-login
byte[] in = dataBuffer.toByteArray();
int inLen = in.length;
Expand Down Expand Up @@ -379,7 +386,7 @@ private int doFinalLength(int inLen) {
} else {
result -= BLK_SIZE; // minus the leading block including the ICV
}
return (result > 0? result : 0);
return (result > 0 ? result : 0);
}

// reset the states to the pre-initialized values
Expand Down Expand Up @@ -654,7 +661,7 @@ protected byte[] engineWrap(Key tbwKey) throws IllegalBlockSizeException,
P11Key tbwP11Key = null;
if (!(tbwKey instanceof P11Key)) {
try {
tbwP11Key = (tbwKey instanceof SecretKey?
tbwP11Key = (tbwKey instanceof SecretKey ?
P11SecretKeyFactory.convertKey(token, tbwKey,
tbwKey.getAlgorithm()) :
P11KeyFactory.convertKey(token, tbwKey,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ private void reset(boolean doCancel) {

private void cancelOperation() {
token.ensureValid();
// cancel operation by finishing it; avoid killSession as some

if (P11Util.trySessionCancel(token, session, CKF_SIGN)) {
return;
}

// cancel by finishing operations; avoid killSession as some
// hardware vendors may require re-login
try {
token.p11.C_SignFinal(session.id(), 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ private static boolean isDigestEqual(String stdAlg, String givenAlg) {
this.mechanism = new CK_MECHANISM(mechId);
int idx = algorithm.indexOf("with");
// convert to stdName
this.mdAlg = (idx == -1?
this.mdAlg = (idx == -1 ?
null : toStdName(algorithm.substring(0, idx)));

switch ((int)mechId) {
Expand All @@ -193,7 +193,7 @@ private static boolean isDigestEqual(String stdAlg, String givenAlg) {
throw new NoSuchAlgorithmException("Unsupported algorithm: " +
algorithm);
}
this.md = (this.mdAlg == null? null :
this.md = (this.mdAlg == null ? null :
MessageDigest.getInstance(this.mdAlg));
type = T_DIGEST;
break;
Expand Down Expand Up @@ -269,9 +269,16 @@ private void reset(boolean doCancel) {

private void cancelOperation() {
token.ensureValid();

if (DEBUG) System.out.print("Cancelling operation");

// cancel operation by finishing it; avoid killSession as some
if (P11Util.trySessionCancel(token, session,
(mode == M_SIGN ? CKF_SIGN : CKF_VERIFY))) {
if (DEBUG) System.out.println(" by C_SessionCancel");
return;
}

// cancel by finishing operations; avoid killSession call as some
// hardware vendors may require re-login
try {
if (mode == M_SIGN) {
Expand All @@ -280,7 +287,7 @@ private void cancelOperation() {
token.p11.C_SignFinal(session.id(), 0);
} else {
byte[] digest =
(md == null? new byte[0] : md.digest());
(md == null ? new byte[0] : md.digest());
if (DEBUG) System.out.println(" by C_Sign");
token.p11.C_Sign(session.id(), digest);
}
Expand All @@ -292,7 +299,7 @@ private void cancelOperation() {
token.p11.C_VerifyFinal(session.id(), signature);
} else {
byte[] digest =
(md == null? new byte[0] : md.digest());
(md == null ? new byte[0] : md.digest());
if (DEBUG) System.out.println(" by C_Verify");
token.p11.C_Verify(session.id(), digest, signature);
}
Expand Down
Loading