After moving to a new computer the problem vanished. There was possibly another version of DLL somewhere in the java library / system path.
iaik pkcs#11 wrapper and java.lang.NoSuchMethodError
-
05-08-2022 - |
Question
I am trying to run a simple sample code from iaik pkcs#11 wrapper (version 1.3, the latest atm) but get NoSuchMethodError
on pkcs11Module.initialize
call.
Module pkcs11Module = Module.getInstance("siecap11");
pkcs11Module.initialize(null);
Slot[] slots = pkcs11Module.getSlotList(Module.SlotRequirement.TOKEN_PRESENT);
for (Slot s: slots) {
System.out.println(s.getSlotID());
}
pkcs11Module.finalize(null);
Exception stack trace is as following
java.lang.NoSuchMethodError: iaik.pkcs.pkcs11.wrapper.PKCS11.C_Initialize(Ljava/lang/Object;Z)V
at iaik.pkcs.pkcs11.Module.initialize(Module.java:308)
at test.pkcs11.Pkcs11Service.listSlotsWithTokens(Pkcs11Service.java:98)
at test.pkcs11.TestPkcs11Service.testListSlots(TestPkcs11Service.java:35)
A similar code works fine on Linux, so i am guessing there is something wrong with pkcs11wrapper.dll.
pkcs11wrapper.dll
and siecap11.dll
are in c\windows\system32
directory and both are 32bit modules.
I have tried a different pkcs#11 provider, debug and release versions of pkcs11wrapper but the result was the same.
The debug version of the pkcs11wrapper.dll generates the following output:
11/26/13 21:30:50 CALL: entering (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_initializeLibrary)
11/26/13 21:30:50 CALL: exiting (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_initializeLibrary)
11/26/13 21:30:50 CALL: entering (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_connect)
11/26/13 21:30:50 INFO: connect to PKCS#11 module: siecap11 ... (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_connect)
11/26/13 21:30:50 CALL: exiting (in Java_iaik_pkcs_pkcs11_wrapper_PKCS11Implementation_connect)
The utility applications that came with the smart cards work fine, so is opensc pkcs11-tool.
EDIT:
Using version 1.2.17 of pkcs11 wrapper library and its accompanying dll, the code above works without a problem. But the original question remains unresolved.
EDIT2:
Following code, suggested by SubOptimal generates the following output.
@Test
public void testFindLibrary() {
String lineSeparator = System.getProperty("path.separator");
String libraryPath = System.getProperty("java.library.path");
for (String dir : libraryPath.split(lineSeparator)) {
File f = new File(dir + "/" + "pkcs11wrapper.dll");
if (f.exists()) {
System.out.println("found in: " + f.getAbsolutePath());
}
}
}
output:
found in: C:\Windows\system32\pkcs11wrapper.dll
found in: C:\Windows\system32\pkcs11wrapper.dll
found in: C:\Windows\system32\pkcs11wrapper.dll
La solution 3
Autres conseils
the exception
java.lang.NoSuchMethodError: iaik.pkcs.pkcs11.wrapper.PKCS11.C_Initialize(Ljava/lang/Object;Z)V
states that a method with the signature void C_Initialize(Object o, boolean b)
should be called and doesn't exist. And you're right with your guess so i am guessing there is something wrong with pkcs11wrapper.dll.
Based on the Javadoc this method signature has been changed
PKCS#11 Wrapper version 1.3 and PKCS#11 Wrapper version 1.2.15 (could not find one for 1.2.17).
So your DDL pkcs11wrapper.dll
is for an older version. You can check the version in the file properties menu under Windows.
edit Seems the dll from version 1.2.17 is somewhere in the java.library.path. I did following tests with the GetInfo.java from iaikPkcs11Wrapper archive.
dll jar result
1.2.17 1.2.17 work successful
1.2.17 1.3 java.lang.UnsatisfiedLinkError: iaik.pkcs.pkcs11.wrapper.PKCS11Implementation.C_Initialize(Ljava/lang/Object;Z)V
1.3 1.3 work successful
1.3 1.2.17 java.lang.UnsatisfiedLinkError: iaik.pkcs.pkcs11.wrapper.PKCS11Implementation.C_Initialize(Ljava/lang/Object;)V
The combination dll-1.2.17 and jar-1.3 produces your exception.
You could run following code to find the dll in an unexpected location
import java.io.File;
class Scratch {
public static void main(String[] args) {
String lineSeparator = System.getProperty("path.separator");
String libraryPath = System.getProperty("java.library.path");
for (String dir : libraryPath.split(lineSeparator)) {
if (new File(dir + "/" + "pkcs11wrapper.dll").exists()) {
System.out.println("found in: " + dir);
}
}
}
}
}
edit 2 the exception of the poster java.lang.NoSuchMethodError
is not related to mixed DLL and JAR version, as this produces an java.lang.UnsatisfiedLinkError
another try to get the error reason
PKCS11Test.java
import iaik.pkcs.pkcs11.Module;
import iaik.pkcs.pkcs11.Info;
import iaik.pkcs.pkcs11.Slot;
public class PKCS11Test {
public static void main(String[] args) throws Exception {
Module pkcs11Module = Module.getInstance(args[0]);
pkcs11Module.initialize(null);
pkcs11Module.finalize(null);
}
}
PKCS11Test.cmd
set CLASS=PKCS11Test
set JAR=iaikPkcs11Wrapper.1.3.jar
set PKCS11_DLL=%~dp0\opensc_pkcs11.dll
rem cp PKCS11Wrapper.1.3.dll pkcs11wrapper.dll
javac -cp %JAR% %CLASS%.java || pause && exit
java -cp %JAR%;. -Djava.library.path=%~dp0 %CLASS% %PKCS11_DLL%
- replace the name of the DLL in the PKCS11_DLL variable with the name of your DLL
- the test expect all files in the same directory
Not directly related to your original question, but the suns bug 6880559 and its duplicates indicate that there is some issue with pkcs11 implementation in Windows 64 bit.