8255409: Support the new C_GetInterfaceList, C_GetInterface, and C_SessionCancel APIs in PKCS#11 v3.0
Reviewed-by: ascarpino, weijun
This commit is contained in:
parent
3cec700a5c
commit
83e6a4c0e9
@ -165,7 +165,7 @@ final class Config {
|
||||
// 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 @@ final class Config {
|
||||
}
|
||||
|
||||
String getFunctionList() {
|
||||
if (functionList == null) {
|
||||
// defaults to "C_GetFunctionList" for NSS secmod
|
||||
if (nssUseSecmod || nssUseSecmodTrust) {
|
||||
return "C_GetFunctionList";
|
||||
}
|
||||
}
|
||||
return functionList;
|
||||
}
|
||||
|
||||
@ -408,67 +414,73 @@ final class Config {
|
||||
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 @@ final class Config {
|
||||
throw excToken("nssDbMode must be one of readWrite, readOnly, and noDb:");
|
||||
}
|
||||
nssUseSecmod = true;
|
||||
} else if (word.equals("nssNetscapeDbWorkaround")) {
|
||||
nssNetscapeDbWorkaround = parseBooleanEntry(word);
|
||||
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 {
|
||||
throw new ConfigurationException
|
||||
("Unknown keyword '" + word + "', line " + st.lineno());
|
||||
}
|
||||
parsedKeywords.add(word);
|
||||
case "nssNetscapeDbWorkaround"-> {
|
||||
nssNetscapeDbWorkaround = parseBooleanEntry(st.sval);
|
||||
nssUseSecmod = true;
|
||||
}
|
||||
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 '" + st.sval + "', line " +
|
||||
st.lineno());
|
||||
}
|
||||
parsedKeywords.add(st.sval);
|
||||
}
|
||||
reader.close();
|
||||
reader = null;
|
||||
|
@ -401,7 +401,13 @@ final class P11AEADCipher extends CipherSpi {
|
||||
}
|
||||
|
||||
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 @@ final class P11AEADCipher extends CipherSpi {
|
||||
|
||||
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 @@ final class P11AEADCipher extends CipherSpi {
|
||||
result -= tagLen;
|
||||
}
|
||||
}
|
||||
return (result > 0? result : 0);
|
||||
return (result > 0 ? result : 0);
|
||||
}
|
||||
|
||||
// reset the states to the pre-initialized values
|
||||
|
@ -445,8 +445,14 @@ final class P11Cipher extends CipherSpi {
|
||||
|
||||
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 @@ final class P11Cipher extends CipherSpi {
|
||||
} 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 @@ final class P11Cipher extends CipherSpi {
|
||||
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 @@ final class P11KeyWrapCipher extends CipherSpi {
|
||||
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 @@ final class P11KeyWrapCipher extends CipherSpi {
|
||||
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 @@ final class P11KeyWrapCipher extends CipherSpi {
|
||||
("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 @@ final class P11KeyWrapCipher extends CipherSpi {
|
||||
}
|
||||
|
||||
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 @@ final class P11KeyWrapCipher extends CipherSpi {
|
||||
} 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 @@ final class P11KeyWrapCipher extends CipherSpi {
|
||||
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 @@ final class P11Mac extends MacSpi {
|
||||
|
||||
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 @@ final class P11PSSSignature extends SignatureSpi {
|
||||
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 @@ final class P11PSSSignature extends SignatureSpi {
|
||||
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 @@ final class P11PSSSignature extends SignatureSpi {
|
||||
|
||||
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 @@ final class P11PSSSignature extends SignatureSpi {
|
||||
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 @@ final class P11PSSSignature extends SignatureSpi {
|
||||
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,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, 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
|
||||
@ -37,6 +37,7 @@ import javax.crypto.spec.*;
|
||||
import static sun.security.pkcs11.TemplateManager.*;
|
||||
import sun.security.pkcs11.wrapper.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
||||
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
|
||||
import sun.security.util.KeyUtil;
|
||||
|
||||
@ -266,7 +267,21 @@ final class P11RSACipher extends CipherSpi {
|
||||
// state variables such as "initialized"
|
||||
private void cancelOperation() {
|
||||
token.ensureValid();
|
||||
// cancel operation by finishing it; avoid killSession as some
|
||||
|
||||
long flags = switch(mode) {
|
||||
case MODE_ENCRYPT -> CKF_ENCRYPT;
|
||||
case MODE_DECRYPT -> CKF_DECRYPT;
|
||||
case MODE_SIGN -> CKF_SIGN;
|
||||
case MODE_VERIFY -> CKF_VERIFY;
|
||||
default -> {
|
||||
throw new AssertionError("Unexpected value: " + mode);
|
||||
}
|
||||
};
|
||||
if (P11Util.trySessionCancel(token, session, flags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// cancel by finishing operations; avoid killSession as some
|
||||
// hardware vendors may require re-login
|
||||
try {
|
||||
PKCS11 p11 = token.p11;
|
||||
|
@ -283,7 +283,13 @@ final class P11Signature extends SignatureSpi {
|
||||
|
||||
private void cancelOperation() {
|
||||
token.ensureValid();
|
||||
// cancel operation by finishing it; avoid killSession as some
|
||||
|
||||
if (P11Util.trySessionCancel(token, session,
|
||||
(mode == M_SIGN ? CKF_SIGN : CKF_VERIFY))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// cancel by finishing operations; avoid killSession call as some
|
||||
// hardware vendors may require re-login
|
||||
try {
|
||||
if (mode == M_SIGN) {
|
||||
@ -315,9 +321,9 @@ final class P11Signature extends SignatureSpi {
|
||||
} 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,
|
||||
// do not fail here. This is part of a defensive mechanism for
|
||||
// PKCS#11 libraries that do not strictly follow the standard.
|
||||
// call. If the operation was 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;
|
||||
}
|
||||
if (mode == M_VERIFY) {
|
||||
|
@ -28,6 +28,9 @@ package sun.security.pkcs11;
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
|
||||
import sun.security.pkcs11.wrapper.PKCS11Exception;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Exception.RV.*;
|
||||
|
||||
/**
|
||||
* Collection of static utility methods.
|
||||
*
|
||||
@ -187,4 +190,22 @@ public final class P11Util {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// returns true if successfully cancelled
|
||||
static boolean trySessionCancel(Token token, Session session, long flags)
|
||||
throws ProviderException {
|
||||
if (token.p11.getVersion().major == 3) {
|
||||
try {
|
||||
token.p11.C_SessionCancel(session.id(), flags);
|
||||
return true;
|
||||
} catch (PKCS11Exception e) {
|
||||
// return false for CKR_OPERATION_CANCEL_FAILED, so callers
|
||||
// can cancel in the pre v3.0 way, i.e. by finishing off the
|
||||
// current operation
|
||||
if (!e.match(CKR_OPERATION_CANCEL_FAILED)) {
|
||||
throw new ProviderException("cancel failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
this.config = c;
|
||||
|
||||
if (debug != null) {
|
||||
System.out.println("SunPKCS11 loading " + config.getFileName());
|
||||
debug.println("SunPKCS11 loading " + config.getFileName());
|
||||
}
|
||||
|
||||
String library = config.getLibrary();
|
||||
@ -176,7 +176,6 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
// switch to using the NSS trust attributes for trusted certs
|
||||
// (KeyStore).
|
||||
//
|
||||
|
||||
if (useSecmod) {
|
||||
// note: Config ensures library/slot/slotListIndex not specified
|
||||
// in secmod mode.
|
||||
@ -328,8 +327,7 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
initArgs.flags = CKF_OS_LOCKING_OK;
|
||||
PKCS11 tmpPKCS11;
|
||||
try {
|
||||
tmpPKCS11 = PKCS11.getInstance(
|
||||
library, functionList, initArgs,
|
||||
tmpPKCS11 = PKCS11.getInstance(library, functionList, initArgs,
|
||||
config.getOmitInitialize());
|
||||
} catch (PKCS11Exception e) {
|
||||
if (debug != null) {
|
||||
@ -345,18 +343,18 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
} else {
|
||||
initArgs.flags = 0;
|
||||
}
|
||||
tmpPKCS11 = PKCS11.getInstance(library,
|
||||
functionList, initArgs, config.getOmitInitialize());
|
||||
tmpPKCS11 = PKCS11.getInstance(library, functionList, initArgs,
|
||||
config.getOmitInitialize());
|
||||
}
|
||||
p11 = tmpPKCS11;
|
||||
|
||||
CK_INFO p11Info = p11.C_GetInfo();
|
||||
if (p11Info.cryptokiVersion.major < 2) {
|
||||
if (p11.getVersion().major < 2) {
|
||||
throw new ProviderException("Only PKCS#11 v2.0 and later "
|
||||
+ "supported, library version is v" + p11Info.cryptokiVersion);
|
||||
+ "supported, library version is v" + p11.getVersion());
|
||||
}
|
||||
boolean showInfo = config.getShowInfo();
|
||||
if (showInfo) {
|
||||
CK_INFO p11Info = p11.C_GetInfo();
|
||||
System.out.println("Information for provider " + getName());
|
||||
System.out.println("Library info:");
|
||||
System.out.println(p11Info);
|
||||
@ -1482,12 +1480,10 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
}
|
||||
|
||||
// get the pin if necessary
|
||||
|
||||
char[] pin = null;
|
||||
if ((token.tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH) == 0) {
|
||||
|
||||
// get password
|
||||
|
||||
CallbackHandler myHandler = getCallbackHandler(handler);
|
||||
if (myHandler == null) {
|
||||
throw new LoginException
|
||||
@ -1503,6 +1499,7 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
PasswordCallback pcall = new PasswordCallback(form.format(source),
|
||||
false);
|
||||
Callback[] callbacks = { pcall };
|
||||
|
||||
try {
|
||||
myHandler.handle(callbacks);
|
||||
} catch (Exception e) {
|
||||
@ -1522,13 +1519,12 @@ public final class SunPKCS11 extends AuthProvider {
|
||||
}
|
||||
|
||||
// perform token login
|
||||
|
||||
Session session = null;
|
||||
try {
|
||||
session = token.getOpSession();
|
||||
|
||||
// pin is NULL if using CKF_PROTECTED_AUTHENTICATION_PATH
|
||||
p11.C_Login(session.id(), CKU_USER, pin);
|
||||
|
||||
if (debug != null) {
|
||||
debug.println("login succeeded");
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class PKCS11 {
|
||||
* e.g. pk2priv.dll.
|
||||
*/
|
||||
private final String pkcs11ModulePath;
|
||||
|
||||
private final CK_VERSION version;
|
||||
private long pNativeData;
|
||||
|
||||
/**
|
||||
@ -141,13 +141,30 @@ public class PKCS11 {
|
||||
* path, if the driver is not in the system's search path.
|
||||
*
|
||||
* @param pkcs11ModulePath the PKCS#11 library path
|
||||
* @param functionList the method name for retrieving the PKCS#11
|
||||
* function list; may be null if not set in config file
|
||||
* @preconditions (pkcs11ModulePath <> null)
|
||||
* @postconditions
|
||||
*/
|
||||
PKCS11(String pkcs11ModulePath, String functionListName)
|
||||
PKCS11(String pkcs11ModulePath, String functionList)
|
||||
throws IOException {
|
||||
connect(pkcs11ModulePath, functionListName);
|
||||
this.version = connect(pkcs11ModulePath, functionList);
|
||||
this.pkcs11ModulePath = pkcs11ModulePath;
|
||||
// bug in native PKCS#11 lib; workaround it by calling C_GetInfo()
|
||||
// and get cryptoki version from there
|
||||
if (this.version.major != 2 && this.version.major != 3) {
|
||||
try {
|
||||
CK_INFO p11Info = C_GetInfo();
|
||||
this.version.major = p11Info.cryptokiVersion.major;
|
||||
this.version.minor = p11Info.cryptokiVersion.minor;
|
||||
} catch (PKCS11Exception e) {
|
||||
// give up; just use what is returned by connect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CK_VERSION getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public static synchronized PKCS11 getInstance(String pkcs11ModulePath,
|
||||
@ -186,11 +203,14 @@ public class PKCS11 {
|
||||
* native part.
|
||||
*
|
||||
* @param pkcs11ModulePath The PKCS#11 library path.
|
||||
* @param functionList the method name for retrieving the PKCS#11
|
||||
* function list; may be null if not set in config file
|
||||
* @return the actual PKCS11 interface version
|
||||
* @preconditions (pkcs11ModulePath <> null)
|
||||
* @postconditions
|
||||
*/
|
||||
private native void connect(String pkcs11ModulePath, String functionListName)
|
||||
throws IOException;
|
||||
private native CK_VERSION connect(String pkcs11ModulePath,
|
||||
String functionList) throws IOException;
|
||||
|
||||
/**
|
||||
* Disconnects the PKCS#11 library from this object. After calling this
|
||||
@ -463,6 +483,20 @@ public class PKCS11 {
|
||||
public native CK_SESSION_INFO C_GetSessionInfo(long hSession)
|
||||
throws PKCS11Exception;
|
||||
|
||||
/**
|
||||
* C_SessionCancel terminates active session based operations.
|
||||
* (Session management) (New in PKCS#11 v3.0)
|
||||
*
|
||||
* @param hSession the session's handle
|
||||
* (PKCS#11 param: CK_SESSION_HANDLE hSession)
|
||||
* @param flags indicates the operations to cancel.
|
||||
* (PKCS#11 param: CK_FLAGS flags)
|
||||
* @exception PKCS11Exception If function returns other value than CKR_OK.
|
||||
* @preconditions
|
||||
* @postconditions
|
||||
*/
|
||||
public native void C_SessionCancel(long hSession, long flags)
|
||||
throws PKCS11Exception;
|
||||
|
||||
/**
|
||||
* C_GetOperationState obtains the state of the cryptographic operation
|
||||
@ -521,6 +555,24 @@ public class PKCS11 {
|
||||
public native void C_Login(long hSession, long userType, char[] pPin)
|
||||
throws PKCS11Exception;
|
||||
|
||||
///**
|
||||
// * C_LoginUser logs a user into a token. (New in PKCS#11 v3.0)
|
||||
// * (Session management)
|
||||
// *
|
||||
// * @param hSession the session's handle
|
||||
// * (PKCS#11 param: CK_SESSION_HANDLE hSession)
|
||||
// * @param userType the user type
|
||||
// * (PKCS#11 param: CK_USER_TYPE userType)
|
||||
// * @param pPin the user's PIN and the length of the PIN
|
||||
// * (PKCS#11 param: CK_CHAR_PTR pPin, CK_ULONG ulPinLen)
|
||||
// * @param pUsername the user name and the length of the user name
|
||||
// * (PKCS#11 param: CK_CHAR_PTR pUsername, CK_ULONG ulUsernameLen)
|
||||
// * @exception PKCS11Exception If function returns other value than CKR_OK.
|
||||
// * @preconditions
|
||||
// * @postconditions
|
||||
// */
|
||||
//public native void C_LoginUser(long hSession, long userType, char[] pPin,
|
||||
// String pUsername) throws PKCS11Exception;
|
||||
|
||||
/**
|
||||
* C_Logout logs a user out from a token.
|
||||
@ -807,7 +859,6 @@ public class PKCS11 {
|
||||
public native int C_EncryptFinal(long hSession, long directOut, byte[] out,
|
||||
int outOfs, int outLen) throws PKCS11Exception;
|
||||
|
||||
|
||||
/**
|
||||
* C_DecryptInit initializes a decryption operation.
|
||||
* (Encryption and decryption)
|
||||
@ -902,8 +953,6 @@ public class PKCS11 {
|
||||
public native int C_DecryptFinal(long hSession, long directOut, byte[] out,
|
||||
int outOfs, int outLen) throws PKCS11Exception;
|
||||
|
||||
|
||||
|
||||
/* *****************************************************************************
|
||||
* Message digesting
|
||||
******************************************************************************/
|
||||
@ -1624,9 +1673,9 @@ public class PKCS11 {
|
||||
// parent. Used for tokens that only support single threaded access
|
||||
static class SynchronizedPKCS11 extends PKCS11 {
|
||||
|
||||
SynchronizedPKCS11(String pkcs11ModulePath, String functionListName)
|
||||
SynchronizedPKCS11(String pkcs11ModulePath, String functionList)
|
||||
throws IOException {
|
||||
super(pkcs11ModulePath, functionListName);
|
||||
super(pkcs11ModulePath, functionList);
|
||||
}
|
||||
|
||||
synchronized void C_Initialize(Object pInitArgs) throws PKCS11Exception {
|
||||
@ -1682,11 +1731,22 @@ static class SynchronizedPKCS11 extends PKCS11 {
|
||||
return super.C_GetSessionInfo(hSession);
|
||||
}
|
||||
|
||||
public synchronized void C_Login(long hSession, long userType, char[] pPin)
|
||||
public synchronized void C_SessionCancel(long hSession, long flags)
|
||||
throws PKCS11Exception {
|
||||
super.C_SessionCancel(hSession, flags);
|
||||
}
|
||||
|
||||
public synchronized void C_Login(long hSession, long userType,
|
||||
char[] pPin) throws PKCS11Exception {
|
||||
super.C_Login(hSession, userType, pPin);
|
||||
}
|
||||
|
||||
//public synchronized void C_LoginUser(long hSession, long userType,
|
||||
// char[] pPin, String pUsername)
|
||||
// throws PKCS11Exception {
|
||||
// super.C_LoginUser(hSession, userType, pPin, pUsername);
|
||||
//}
|
||||
|
||||
public synchronized void C_Logout(long hSession) throws PKCS11Exception {
|
||||
super.C_Logout(hSession);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
|
||||
@ -272,6 +272,33 @@ JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSessionI
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef P11_ENABLE_C_SESSIONCANCEL
|
||||
/*
|
||||
* Class: sun_security_pkcs11_wrapper_PKCS11
|
||||
* Method: C_SessionCancel
|
||||
* Signature: (JJ)V
|
||||
* Parametermapping: *PKCS11*
|
||||
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
|
||||
* @param jlong jFlags CK_FLAGS flags
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SessionCancel
|
||||
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jFlags)
|
||||
{
|
||||
CK_SESSION_HANDLE ckSessionHandle;
|
||||
CK_RV rv;
|
||||
|
||||
CK_FUNCTION_LIST_3_0_PTR ckpFunctions30 = getFunctionList30(env, obj);
|
||||
if (ckpFunctions30 == NULL) { return; }
|
||||
|
||||
ckSessionHandle = jLongToCKULong(jSessionHandle);
|
||||
|
||||
rv = (*ckpFunctions30->C_SessionCancel)(ckSessionHandle,
|
||||
jLongToCKULong(jFlags));
|
||||
|
||||
ckAssertReturnValueOK(env, rv);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef P11_ENABLE_C_GETOPERATIONSTATE
|
||||
/*
|
||||
* Class: sun_security_pkcs11_wrapper_PKCS11
|
||||
@ -351,7 +378,7 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationSt
|
||||
|
||||
free(ckpState);
|
||||
|
||||
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
|
||||
ckAssertReturnValueOK(env, rv);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -367,30 +394,85 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationSt
|
||||
* CK_ULONG ulPinLen
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Login
|
||||
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType, jcharArray jPin)
|
||||
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType,
|
||||
jcharArray jPin)
|
||||
{
|
||||
CK_SESSION_HANDLE ckSessionHandle;
|
||||
CK_USER_TYPE ckUserType;
|
||||
CK_CHAR_PTR ckpPinArray = NULL_PTR;
|
||||
CK_ULONG ckPinLength;
|
||||
CK_RV rv;
|
||||
CK_FUNCTION_LIST_PTR ckpFunctions;
|
||||
|
||||
CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
|
||||
if (ckpFunctions == NULL) { return; }
|
||||
ckpFunctions = getFunctionList(env, obj);
|
||||
|
||||
if (ckpFunctions == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ckSessionHandle = jLongToCKULong(jSessionHandle);
|
||||
ckUserType = jLongToCKULong(jUserType);
|
||||
jCharArrayToCKCharArray(env, jPin, &ckpPinArray, &ckPinLength);
|
||||
if ((*env)->ExceptionCheck(env)) { return; }
|
||||
|
||||
rv = (*ckpFunctions->C_Login)(ckSessionHandle, ckUserType, ckpPinArray, ckPinLength);
|
||||
|
||||
rv = (*ckpFunctions->C_Login)(ckSessionHandle, ckUserType, ckpPinArray,
|
||||
ckPinLength);
|
||||
free(ckpPinArray);
|
||||
|
||||
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
|
||||
ckAssertReturnValueOK(env, rv);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef P11_ENABLE_C_LOGINUSER
|
||||
/*
|
||||
* Class: sun_security_pkcs11_wrapper_PKCS11
|
||||
* Method: C_LoginUser
|
||||
* Signature: (JJ[C;Ljava/lang/String;)V
|
||||
* Parametermapping: *PKCS11*
|
||||
* @param jlong jSessionHandle CK_SESSION_HANDLE hSession
|
||||
* @param jlong jUserType CK_USER_TYPE userType
|
||||
* @param jcharArray jPin CK_CHAR_PTR pPin
|
||||
* CK_ULONG ulPinLen
|
||||
* @param jstring jUsername CK_CHAR_PTR pUsername
|
||||
* CK_ULONG ulUsernameLen
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1LoginUser
|
||||
(JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType,
|
||||
jcharArray jPin, jstring jUsername)
|
||||
{
|
||||
CK_SESSION_HANDLE ckSessionHandle;
|
||||
CK_USER_TYPE ckUserType;
|
||||
CK_CHAR_PTR ckpPinArray = NULL_PTR;
|
||||
CK_ULONG ckPinLength;
|
||||
CK_CHAR_PTR ckpUsername = NULL_PTR;
|
||||
CK_ULONG ckUsernameLength;
|
||||
CK_RV rv;
|
||||
CK_FUNCTION_LIST_3_0_PTR ckpFunctions30;
|
||||
|
||||
ckpFunctions30 = getFunctionList30(env, obj);
|
||||
|
||||
ckSessionHandle = jLongToCKULong(jSessionHandle);
|
||||
ckUserType = jLongToCKULong(jUserType);
|
||||
jCharArrayToCKCharArray(env, jPin, &ckpPinArray, &ckPinLength);
|
||||
if ((*env)->ExceptionCheck(env)) { return; }
|
||||
jStringToCKUTF8CharArray(env, jUsername, &ckpUsername,
|
||||
&ckUsernameLength);
|
||||
if ((*env)->ExceptionCheck(env)) { return; }
|
||||
|
||||
if (ckpFunctions30 == NULL) {
|
||||
return;
|
||||
}
|
||||
rv = (*ckpFunctions30->C_LoginUser)(ckSessionHandle, ckUserType,
|
||||
ckpPinArray, ckPinLength, ckpUsername, ckUsernameLength);
|
||||
|
||||
free(ckpPinArray);
|
||||
free(ckpUsername);
|
||||
|
||||
ckAssertReturnValueOK(env, rv);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef P11_ENABLE_C_LOGOUT
|
||||
/*
|
||||
* Class: sun_security_pkcs11_wrapper_PKCS11
|
||||
@ -411,7 +493,7 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Logout
|
||||
ckSessionHandle = jLongToCKULong(jSessionHandle);
|
||||
|
||||
rv = (*ckpFunctions->C_Logout)(ckSessionHandle);
|
||||
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
|
||||
ckAssertReturnValueOK(env, rv);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -136,6 +136,20 @@ CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation)
|
||||
return ckpFunctions;
|
||||
}
|
||||
|
||||
CK_FUNCTION_LIST_3_0_PTR getFunctionList30(JNIEnv *env, jobject
|
||||
pkcs11Implementation) {
|
||||
ModuleData *moduleData;
|
||||
CK_FUNCTION_LIST_3_0_PTR ckpFunctions30;
|
||||
|
||||
moduleData = getModuleEntry(env, pkcs11Implementation);
|
||||
if (moduleData == NULL) {
|
||||
throwDisconnectedRuntimeException(env);
|
||||
return NULL;
|
||||
}
|
||||
ckpFunctions30 = moduleData->ckFunctionList30Ptr;
|
||||
return ckpFunctions30;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns 1, if the given pkcs11Implementation is in the list.
|
||||
|
@ -100,9 +100,11 @@
|
||||
#define P11_ENABLE_C_CLOSESESSION
|
||||
#undef P11_ENABLE_C_CLOSEALLSESSIONS
|
||||
#define P11_ENABLE_C_GETSESSIONINFO
|
||||
#define P11_ENABLE_C_SESSIONCANCEL
|
||||
#define P11_ENABLE_C_GETOPERATIONSTATE
|
||||
#define P11_ENABLE_C_SETOPERATIONSTATE
|
||||
#define P11_ENABLE_C_LOGIN
|
||||
//#define P11_ENABLE_C_LOGINUSER
|
||||
#define P11_ENABLE_C_LOGOUT
|
||||
#define P11_ENABLE_C_CREATEOBJECT
|
||||
#define P11_ENABLE_C_COPYOBJECT
|
||||
@ -209,17 +211,21 @@
|
||||
//#define TRACE0d(s) { printf(s); fflush(stdout); }
|
||||
//#define TRACE1d(s, p1) { printf(s, p1); fflush(stdout); }
|
||||
//#define TRACE2d(s, p1, p2) { printf(s, p1, p2); fflush(stdout); }
|
||||
//#define TRACE3d(s, p1, p2, p3) { printf(s, p1, p2, p3); fflush(stdout); }
|
||||
//#define TRACE4d(s, p1, p2, p3, p4) { printf(s, p1, p2, p3, p4); fflush(stdout); }
|
||||
|
||||
#ifdef P11_DEBUG
|
||||
#define TRACE0(s) { printf(s); fflush(stdout); }
|
||||
#define TRACE1(s, p1) { printf(s, p1); fflush(stdout); }
|
||||
#define TRACE2(s, p1, p2) { printf(s, p1, p2); fflush(stdout); }
|
||||
#define TRACE3(s, p1, p2, p3) { printf(s, p1, p2, p3); fflush(stdout); }
|
||||
#define TRACE4(s, p1, p2, p3, p4) { printf(s, p1, p2, p3, p4); fflush(stdout); }
|
||||
#else
|
||||
#define TRACE0(s)
|
||||
#define TRACE1(s, p1)
|
||||
#define TRACE2(s, p1, p2)
|
||||
#define TRACE3(s, p1, p2, p3)
|
||||
#define TRACE4(s, p1, p2, p3, p4)
|
||||
#define TRACE_INTEND
|
||||
#define TRACE_UNINTEND
|
||||
#endif
|
||||
@ -412,6 +418,8 @@ CK_RV callJUnlockMutex(CK_VOID_PTR pMutex);
|
||||
void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData);
|
||||
ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation);
|
||||
CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation);
|
||||
CK_FUNCTION_LIST_3_0_PTR getFunctionList30(JNIEnv *env, jobject
|
||||
pkcs11Implementation);
|
||||
|
||||
/* A structure to encapsulate the required data for a Notify callback */
|
||||
struct NotifyEncapsulation {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
|
||||
@ -72,26 +72,34 @@
|
||||
/*
|
||||
* Class: sun_security_pkcs11_wrapper_PKCS11
|
||||
* Method: connect
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
* Signature: (Ljava/lang/String;)Lsun/security/pkcs11/wrapper/CK_VERSION;
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
(JNIEnv *env, jobject obj, jstring jPkcs11ModulePath, jstring jGetFunctionList)
|
||||
{
|
||||
JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
(JNIEnv *env, jobject obj, jstring jPkcs11ModulePath,
|
||||
jstring jGetFunctionList) {
|
||||
|
||||
void *hModule;
|
||||
char *error;
|
||||
CK_C_GetFunctionList C_GetFunctionList=NULL;
|
||||
int i;
|
||||
CK_ULONG ulCount = 0;
|
||||
CK_C_GetInterfaceList C_GetInterfaceList = NULL;
|
||||
CK_INTERFACE_PTR iList = NULL;
|
||||
CK_C_GetInterface C_GetInterface = NULL;
|
||||
CK_INTERFACE_PTR interface = NULL;
|
||||
CK_C_GetFunctionList C_GetFunctionList = NULL;
|
||||
CK_RV rv;
|
||||
ModuleData *moduleData;
|
||||
ModuleData *moduleData = NULL;
|
||||
jobject globalPKCS11ImplementationReference;
|
||||
char *systemErrorMessage;
|
||||
char *exceptionMessage;
|
||||
const char *getFunctionListStr;
|
||||
const char *getFunctionListStr = NULL;
|
||||
|
||||
const char *libraryNameStr = (*env)->GetStringUTFChars(env, jPkcs11ModulePath, 0);
|
||||
const char *libraryNameStr = (*env)->GetStringUTFChars(env,
|
||||
jPkcs11ModulePath, 0);
|
||||
if (libraryNameStr == NULL) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
|
||||
TRACE1("Connect: connect to PKCS#11 module: %s ... ", libraryNameStr);
|
||||
|
||||
/*
|
||||
* Load the PKCS #11 DLL
|
||||
@ -108,39 +116,92 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
exceptionMessage = (char *) malloc(sizeof(char) * (strlen(systemErrorMessage) + strlen(libraryNameStr) + 1));
|
||||
if (exceptionMessage == NULL) {
|
||||
throwOutOfMemoryError(env, 0);
|
||||
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
strcpy(exceptionMessage, systemErrorMessage);
|
||||
strcat(exceptionMessage, libraryNameStr);
|
||||
throwIOException(env, exceptionMessage);
|
||||
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
|
||||
free(exceptionMessage);
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
|
||||
|
||||
/*
|
||||
* Get function pointer to C_GetFunctionList
|
||||
*/
|
||||
dlerror(); /* clear any old error message not fetched */
|
||||
// with the old JAR file jGetFunctionList is null, temporarily check for that
|
||||
if (jGetFunctionList != NULL) {
|
||||
getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
|
||||
if (getFunctionListStr == NULL) {
|
||||
return;
|
||||
// clear any old error message not fetched
|
||||
dlerror();
|
||||
|
||||
#ifdef DEBUG
|
||||
C_GetInterfaceList = (CK_C_GetInterfaceList) dlsym(hModule,
|
||||
"C_GetInterfaceList");
|
||||
if (C_GetInterfaceList != NULL) {
|
||||
TRACE0("Connect: Found C_GetInterfaceList func\n");
|
||||
rv = (C_GetInterfaceList)(NULL, &ulCount);
|
||||
if (rv == CKR_OK) {
|
||||
TRACE1("Connect: interface list size %ld \n", ulCount);
|
||||
// retrieve available interfaces and report their info
|
||||
iList = (CK_INTERFACE_PTR)
|
||||
malloc(ulCount*sizeof(CK_INTERFACE));
|
||||
rv = C_GetInterfaceList(iList, &ulCount);
|
||||
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
|
||||
TRACE0("Connect: error polling interface list\n");
|
||||
goto cleanup;
|
||||
}
|
||||
for (i=0; i < (int)ulCount; i++) {
|
||||
TRACE4("Connect: name %s, version %d.%d, flags 0x%lX\n",
|
||||
iList[i].pInterfaceName,
|
||||
((CK_VERSION *)iList[i].pFunctionList)->major,
|
||||
((CK_VERSION *)iList[i].pFunctionList)->minor,
|
||||
iList[i].flags);
|
||||
}
|
||||
} else {
|
||||
TRACE0("Connect: error polling interface list size\n");
|
||||
}
|
||||
C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule, getFunctionListStr);
|
||||
(*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
|
||||
} else {
|
||||
TRACE0("Connect: No C_GetInterfaceList func\n");
|
||||
}
|
||||
if (C_GetFunctionList == NULL) {
|
||||
throwIOException(env, "ERROR: C_GetFunctionList == NULL");
|
||||
return;
|
||||
} else if ( (systemErrorMessage = dlerror()) != NULL ){
|
||||
throwIOException(env, systemErrorMessage);
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (jGetFunctionList != NULL) {
|
||||
getFunctionListStr = (*env)->GetStringUTFChars(env,
|
||||
jGetFunctionList, 0);
|
||||
if (getFunctionListStr == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule,
|
||||
getFunctionListStr);
|
||||
if ((systemErrorMessage = dlerror()) != NULL){
|
||||
throwIOException(env, systemErrorMessage);
|
||||
goto cleanup;
|
||||
}
|
||||
if (C_GetFunctionList == NULL) {
|
||||
TRACE1("Connect: No %s func\n", getFunctionListStr);
|
||||
throwIOException(env, "ERROR: C_GetFunctionList == NULL");
|
||||
goto cleanup;
|
||||
}
|
||||
TRACE1("Connect: Found %s func\n", getFunctionListStr);
|
||||
} else {
|
||||
// if none specified, then we try 3.0 API first before trying 2.40
|
||||
C_GetInterface = (CK_C_GetInterface) dlsym(hModule, "C_GetInterface");
|
||||
if ((C_GetInterface != NULL) && (dlerror() == NULL)) {
|
||||
TRACE0("Connect: Found C_GetInterface func\n");
|
||||
rv = (C_GetInterface)(NULL, NULL, &interface, 0L);
|
||||
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
|
||||
goto setModuleData;
|
||||
}
|
||||
}
|
||||
C_GetFunctionList = (CK_C_GetFunctionList) dlsym(hModule,
|
||||
"C_GetFunctionList");
|
||||
if ((systemErrorMessage = dlerror()) != NULL){
|
||||
throwIOException(env, systemErrorMessage);
|
||||
goto cleanup;
|
||||
}
|
||||
if (C_GetFunctionList == NULL) {
|
||||
TRACE0("Connect: No C_GetFunctionList func\n");
|
||||
throwIOException(env, "ERROR: C_GetFunctionList == NULL");
|
||||
goto cleanup;
|
||||
}
|
||||
TRACE0("Connect: Found C_GetFunctionList func\n");
|
||||
}
|
||||
|
||||
setModuleData:
|
||||
/*
|
||||
* Get function pointers to all PKCS #11 functions
|
||||
*/
|
||||
@ -148,19 +209,56 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
if (moduleData == NULL) {
|
||||
dlclose(hModule);
|
||||
throwOutOfMemoryError(env, 0);
|
||||
return;
|
||||
goto cleanup;
|
||||
}
|
||||
moduleData->hModule = hModule;
|
||||
moduleData->applicationMutexHandler = NULL;
|
||||
rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
|
||||
if (C_GetFunctionList != NULL) {
|
||||
rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
|
||||
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (interface != NULL) {
|
||||
moduleData->ckFunctionListPtr = interface->pFunctionList;
|
||||
if (((CK_VERSION *)moduleData->ckFunctionListPtr)->major == 3) {
|
||||
moduleData->ckFunctionList30Ptr = interface->pFunctionList;
|
||||
}
|
||||
} else {
|
||||
// should never happen
|
||||
throwIOException(env, "ERROR: No function list ptr found");
|
||||
goto cleanup;
|
||||
}
|
||||
if (((CK_VERSION *)moduleData->ckFunctionListPtr)->major == 3) {
|
||||
moduleData->ckFunctionList30Ptr = interface->pFunctionList;
|
||||
} else {
|
||||
moduleData->ckFunctionList30Ptr = NULL;
|
||||
}
|
||||
|
||||
TRACE2("Connect: FunctionListPtr version = %d.%d\n",
|
||||
((CK_VERSION *)moduleData->ckFunctionListPtr)->major,
|
||||
((CK_VERSION *)moduleData->ckFunctionListPtr)->minor);
|
||||
|
||||
globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
|
||||
putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
|
||||
|
||||
TRACE0("FINISHED\n");
|
||||
|
||||
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
|
||||
cleanup:
|
||||
if (jPkcs11ModulePath != NULL && libraryNameStr != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
|
||||
}
|
||||
if (jGetFunctionList != NULL && getFunctionListStr != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, jGetFunctionList,
|
||||
getFunctionListStr);
|
||||
}
|
||||
TRACE0("Connect: FINISHED\n");
|
||||
if (moduleData != NULL) {
|
||||
return ckVersionPtrToJVersion(env,
|
||||
(CK_VERSION *)moduleData->ckFunctionListPtr);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Class: sun_security_pkcs11_wrapper_PKCS11
|
||||
* Method: disconnect
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -83,8 +83,9 @@ struct ModuleData {
|
||||
/* the module (DLL or shared library) handle */
|
||||
void *hModule;
|
||||
|
||||
/* The pointer to the PKCS#11 functions of this module. */
|
||||
/* The pointers to the PKCS#11 functions of this module. */
|
||||
CK_FUNCTION_LIST_PTR ckFunctionListPtr;
|
||||
CK_FUNCTION_LIST_3_0_PTR ckFunctionList30Ptr;
|
||||
|
||||
/* Reference to the object to use for mutex handling. NULL, if not used. */
|
||||
jobject applicationMutexHandler;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2002 Graz University of Technology. All rights reserved.
|
||||
@ -72,16 +72,22 @@
|
||||
/*
|
||||
* Class: sun_security_pkcs11_wrapper_PKCS11
|
||||
* Method: connect
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
* Signature: (Ljava/lang/String;)Lsun/security/pkcs11/wrapper/CK_VERSION;
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
(JNIEnv *env, jobject obj, jstring jPkcs11ModulePath,
|
||||
jstring jGetFunctionList)
|
||||
jstring jGetFunctionList)
|
||||
{
|
||||
HINSTANCE hModule;
|
||||
CK_C_GetFunctionList C_GetFunctionList;
|
||||
int i = 0;
|
||||
CK_ULONG ulCount = 0;
|
||||
CK_C_GetInterfaceList C_GetInterfaceList = NULL;
|
||||
CK_INTERFACE_PTR iList = NULL;
|
||||
CK_C_GetInterface C_GetInterface = NULL;
|
||||
CK_INTERFACE_PTR interface = NULL;
|
||||
CK_C_GetFunctionList C_GetFunctionList = NULL;
|
||||
CK_RV rv = CK_ASSERT_OK;
|
||||
ModuleData *moduleData;
|
||||
ModuleData *moduleData = NULL;
|
||||
jobject globalPKCS11ImplementationReference;
|
||||
LPVOID lpMsgBuf = NULL;
|
||||
char *exceptionMessage = NULL;
|
||||
@ -91,10 +97,9 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
jPkcs11ModulePath, 0);
|
||||
TRACE1("DEBUG: connect to PKCS#11 module: %s ... ", libraryNameStr);
|
||||
|
||||
|
||||
/*
|
||||
* Load the PKCS #11 DLL
|
||||
*/
|
||||
/*
|
||||
* Load the PKCS #11 DLL
|
||||
*/
|
||||
hModule = LoadLibrary(libraryNameStr);
|
||||
if (hModule == NULL) {
|
||||
FormatMessage(
|
||||
@ -120,29 +125,93 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Get function pointer to C_GetFunctionList
|
||||
* Get function pointer to C_GetInterfaceList
|
||||
*/
|
||||
getFunctionListStr = (*env)->GetStringUTFChars(env, jGetFunctionList, 0);
|
||||
C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule,
|
||||
getFunctionListStr);
|
||||
(*env)->ReleaseStringUTFChars(env, jGetFunctionList, getFunctionListStr);
|
||||
if (C_GetFunctionList == NULL) {
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
0, /* Default language */
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
throwIOException(env, (LPTSTR) lpMsgBuf);
|
||||
goto cleanup;
|
||||
C_GetInterfaceList = (CK_C_GetInterfaceList) GetProcAddress(hModule,
|
||||
"C_GetInterfaceList");
|
||||
if (C_GetInterfaceList != NULL) {
|
||||
TRACE0("Found C_GetInterfaceList func\n");
|
||||
rv = (C_GetInterfaceList)(NULL, &ulCount);
|
||||
if (rv == CKR_OK) {
|
||||
/* get copy of interfaces */
|
||||
iList = (CK_INTERFACE_PTR)
|
||||
malloc(ulCount*sizeof(CK_INTERFACE));
|
||||
rv = C_GetInterfaceList(iList, &ulCount);
|
||||
for (i=0; i < (int)ulCount; i++) {
|
||||
printf("interface %s version %d.%d funcs %p flags 0x%lu\n",
|
||||
iList[i].pInterfaceName,
|
||||
((CK_VERSION *)iList[i].pFunctionList)->major,
|
||||
((CK_VERSION *)iList[i].pFunctionList)->minor,
|
||||
iList[i].pFunctionList, iList[i].flags);
|
||||
}
|
||||
} else {
|
||||
TRACE0("Connect: error polling interface list size\n");
|
||||
}
|
||||
} else {
|
||||
TRACE0("Connect: No C_GetInterfaceList func\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (jGetFunctionList != NULL) {
|
||||
getFunctionListStr = (*env)->GetStringUTFChars(env,
|
||||
jGetFunctionList, 0);
|
||||
if (getFunctionListStr == NULL) {
|
||||
goto cleanup;
|
||||
}
|
||||
C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule,
|
||||
getFunctionListStr);
|
||||
if (C_GetFunctionList == NULL) {
|
||||
TRACE1("Connect: No %s func\n", getFunctionListStr);
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
0, /* Default language */
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
throwIOException(env, (LPTSTR) lpMsgBuf);
|
||||
goto cleanup;
|
||||
}
|
||||
TRACE1("Connect: Found %s func\n", getFunctionListStr);
|
||||
} else {
|
||||
// if none specified, then we try 3.0 API first before trying 2.40
|
||||
C_GetInterface = (CK_C_GetInterface) GetProcAddress(hModule,
|
||||
"C_GetInterface");
|
||||
if (C_GetInterface != NULL) {
|
||||
TRACE0("Connect: Found C_GetInterface func\n");
|
||||
rv = (C_GetInterface)(NULL, NULL, &interface, 0);
|
||||
if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) {
|
||||
goto setModuleData;
|
||||
}
|
||||
}
|
||||
C_GetFunctionList = (CK_C_GetFunctionList) GetProcAddress(hModule,
|
||||
"C_GetFunctionList");
|
||||
if (C_GetFunctionList == NULL) {
|
||||
TRACE0("Connect: No C_GetFunctionList func\n");
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
0, /* Default language */
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
throwIOException(env, (LPTSTR) lpMsgBuf);
|
||||
goto cleanup;
|
||||
}
|
||||
TRACE0("Connect: Found C_GetFunctionList func\n");
|
||||
}
|
||||
|
||||
setModuleData:
|
||||
/*
|
||||
* Get function pointers to all PKCS #11 functions
|
||||
*/
|
||||
@ -153,12 +222,31 @@ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_connect
|
||||
}
|
||||
moduleData->hModule = hModule;
|
||||
moduleData->applicationMutexHandler = NULL;
|
||||
rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
|
||||
if (C_GetFunctionList != NULL) {
|
||||
rv = (C_GetFunctionList)(&(moduleData->ckFunctionListPtr));
|
||||
if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (interface != NULL) {
|
||||
moduleData->ckFunctionListPtr = interface->pFunctionList;
|
||||
} else {
|
||||
// should never happen
|
||||
throwIOException(env, "ERROR: No function list ptr found");
|
||||
goto cleanup;
|
||||
}
|
||||
if (((CK_VERSION *)moduleData->ckFunctionListPtr)->major == 3) {
|
||||
moduleData->ckFunctionList30Ptr = interface->pFunctionList;
|
||||
} else {
|
||||
moduleData->ckFunctionList30Ptr = NULL;
|
||||
}
|
||||
|
||||
TRACE2("Connect: FunctionListPtr version = %d.%d\n",
|
||||
((CK_VERSION *)moduleData->ckFunctionListPtr)->major,
|
||||
((CK_VERSION *)moduleData->ckFunctionListPtr)->minor);
|
||||
|
||||
globalPKCS11ImplementationReference = (*env)->NewGlobalRef(env, obj);
|
||||
putModuleEntry(env, globalPKCS11ImplementationReference, moduleData);
|
||||
|
||||
TRACE0("FINISHED\n");
|
||||
|
||||
cleanup:
|
||||
/* Free up allocated buffers we no longer need */
|
||||
if (lpMsgBuf != NULL) {
|
||||
@ -167,11 +255,21 @@ cleanup:
|
||||
if (libraryNameStr != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, jPkcs11ModulePath, libraryNameStr);
|
||||
}
|
||||
if (jGetFunctionList != NULL && getFunctionListStr != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, jGetFunctionList,
|
||||
getFunctionListStr);
|
||||
}
|
||||
if (exceptionMessage != NULL) {
|
||||
free(exceptionMessage);
|
||||
}
|
||||
TRACE0("Connect: FINISHED\n");
|
||||
if (moduleData != NULL) {
|
||||
return ckVersionPtrToJVersion(env,
|
||||
(CK_VERSION *)moduleData->ckFunctionListPtr);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -93,8 +93,9 @@ struct ModuleData {
|
||||
|
||||
HINSTANCE hModule;
|
||||
|
||||
/* The pointer to the PKCS#11 functions of this module. */
|
||||
/* The pointers to the PKCS#11 functions of this module. */
|
||||
CK_FUNCTION_LIST_PTR ckFunctionListPtr;
|
||||
CK_FUNCTION_LIST_3_0_PTR ckFunctionList30Ptr;
|
||||
|
||||
/* Reference to the object to use for mutex handling. NULL, if not used. */
|
||||
jobject applicationMutexHandler;
|
||||
|
Loading…
Reference in New Issue
Block a user