Skip to content
Permalink
Browse files
8255409: Support the new C_GetInterfaceList, C_GetInterface, and C_Se…
…ssionCancel APIs in PKCS#11 v3.0

Reviewed-by: ascarpino, weijun
  • Loading branch information
Valerie Peng committed Dec 8, 2021
1 parent 3cec700 commit 83e6a4c0e9e4a9474ae0c1252378b1a09d1d2df0
Show file tree
Hide file tree
Showing 18 changed files with 643 additions and 197 deletions.
@@ -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.
@@ -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;
}

@@ -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")) {
@@ -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;
@@ -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
int bufLen = doFinalLength(0);
byte[] buffer = new byte[bufLen];
@@ -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 {
@@ -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
@@ -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];
@@ -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;
@@ -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) {
@@ -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 {
@@ -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 {
@@ -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);
@@ -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;
@@ -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
@@ -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,
@@ -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);
@@ -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) {
@@ -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;
@@ -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) {
@@ -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);
}
@@ -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);
}

1 comment on commit 83e6a4c

@openjdk-notifier
Copy link

@openjdk-notifier openjdk-notifier bot commented on 83e6a4c Dec 8, 2021

Choose a reason for hiding this comment

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

Please sign in to comment.