Error reading objects from Gemalto smartcard using IAIK pkcs11wrapper - java

I'm trying to read the public certificate names from a smartcard to display to the user before they sign a file using a gemalto smartcard.
I've followed the getInfo example from iaikPkcs11Wrapper demos as below :
Module pkcs11Module = Module.getInstance(settings.getCryptoDll());
Slot[] slotList;
try{
slotList = pkcs11Module.getSlotList(true);
}catch(TokenException tex){//module is not initialised
tex.printStackTrace();
pkcs11Module.initialize(new DefaultInitializeArgs());
slotList = pkcs11Module.getSlotList(true);
}
for (Slot slot : slotList) {
Token token = slot.getToken();
iaik.pkcs.pkcs11.Session session = token.openSession(true, SessionReadWriteBehavior.RO_SESSION, null, null);
session.findObjectsInit(null);
Object[] objects = new Object[0];
try {
objects = session.findObjects(1);
This fails always at the line objects = findObjects(1); with a CKR_TEMPLATE_INCONSISTENT exception.
As I understand from the documentation session.findObjectsInit(null) should just return all accessible objects on the card and you can then compare them for type.
I have various smartcards and they all fail like this, I've also tried calling session.findObjectsInit(tempObj) with a GenericTemplate object and a X509PublicKeyCertificate which both return the same exception, and with an X509AttributeCertificate which returns no objects but does not throw the exception.
I'd appreciate any pointers anyone can give. Or do I need to create a matching template object using GenericTemplate? I'm unsure why I'm getting the exception as I thought passing the object into the getObjectInit method filtered for thet object so anything returned should match.
EDIT
I've subsequently tried with other templates and ones for objects not on the card just return an empty array- no exception and ones I think are on the cards just throw the ckr_template_inconsistent exception, any help would be gratefully received.
EDIT2
I've now tried with some new 'V3' cards, which do infact work, all my test cards work using another technique (we currently use capicom via com4J for signing), so maybe there is an issue with the iaik wrapper, or gclib.dll (or me).

Related

C_FindObjectsInit(..) from PKCS11 class exception

To sign data, I am using signserver open-source code. I was exploring a legacy code where
it gives error at this place:
Module.getPKCS11Module().C_FindObjectsInit(session.getSessionHandle(), attributes,true);
where the Module class is from iaikpkcs11Wrapper.jar (package: iaik.pkcs.pkcs11)
As I navigate further, PKCS11 interface has this method void C_FindObjectsInit(long var1, CK_ATTRIBUTE[] var3, boolean var4) mentioned above.
Moreover, the attributes param is constructed like below:
CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTEKeyStoreContainerBase[2];
attributes[0] = new CK_ATTRIBUTE();
attributes[0].type = PKCS11Constants.CKA_CLASS;
attributes[0].pValue = new Long(PKCS11Constants.CKO_SECRET_KEY);
attributes[1] = new CK_ATTRIBUTE();
attributes[1].type = PKCS11Constants.CKA_ID;
attributes[1].pValue = id; //id is byteArray. For this param's value the error is causing
My question is, do I need to store any kind of key/certificate from where C_FindObjectsInit(..) will read or match as it says that it couldn't find any key? Where does this method search the key or how to resolve this issue?
Btw, I have read C_FindObjectsInit-JavaDoc and couldn't understand this line properly, that's why I am here:
pTemplate - the object's attribute values to match and the number of
attributes in search template (PKCS#11 param: CK_ATTRIBUTE_PTR
pTemplate, CK_ULONG ulCount)
[this may sound peculiar question, but I am really blank and stuck for few days]
PKCS#11 specification don't force us to use some strictly composed data.
But in most implementations I saw it was binary encoded OID field.
Also check for 0 (null) bytes in sequence.

Play 2.5: Form validation - on error, value of form is "Optional.empty"

I am developing an application with Play 2.5. Models and Form data are separate classes, so I have a class "Page" and "PageForm".
In PageForm is a method "validate()" which returns null if there was no error or a List if the validation failed:
public List<ValidationError> validate() {
List<ValidationError> errors = new ArrayList<>();
Page checkForDuplicatePage = PageRepository.getInstance().getByName(name);
if(checkForDuplicatePage != null && checkForDuplicatePage.id != id) {
errors.add(new ValidationError("name", "The name is already in use by another page"));
}
// ...
return errors.isEmpty() ? null : errors;
}
In my controller I call:
Form<PageForm> form = formFactory(PageForm.class).bindFromRequest();
This works really well if the data in the form is correct. However, if validate() finds an error (and it really doesn't matter what kind, even a return new ArrayList<>() triggers this), the "value" attribute of my form is Optional.empty. The "data" attribute actually has all the data passed to the form.
This means I can't use the form to pass it to my view, which should display the data with error messages. Instead I get a [CompletionException: java.util.NoSuchElementException: No value present]. Sometimes (I haven't figured out why that happens yet) it also says [CompletionException: java.util.NoSuchElementException: None.get].
I compared my code with other projects and the official docs, but they all seem to be doing what I have here.
I use Scala Play rather than Java, so YMMV. But to me, I don't think that validate should return null at all. It should return the empty ArrayList if there are no errors. I suspect that this will eliminate the None.get error message. I'm not sure how much I can help, though, because I don't really understand very well what your code is intended to do. For example, the sentence
However, if validate() finds an error (and it really doesn't matter what kind, even a return new ArrayList<>() triggers this)
seems kind of ambiguous to me. Where is the return new ArrayList<>() call that triggers the error?

PeopleSoft Component Interfaces: Create Method Doesn't Persist The New Object

I'm working with the PSJOA library. I have a Java app, and I'm testing each of the standard operations using the CI_PERSONAL_DATA. Everything works fine with the Get, Find and Save. But not with the Create, even though when I invoke the method, I get an OK response, with no apparent errors. The input parameter I'm sending (taken from the CreateKeys) is the KEYPROP_EMPLID.
The odd thing here is that, if instead I call the Create method using Web Services (through SoapUI), the new instances is correctly created. However, in this scenario, passing just the primary key KEYPROP_EMPLID is not enough and I have to fill more fields (as it I was performing an update).
Can someone point to me what might be happening? Is there some missing data? Maybe I misunderstood the creation behavior?
Thanks.
What exactly goes awry when you call create? That will create a new entry in the personal data component in PeopleSoft for the person with the supplied emplid. It will be editable, so you can fill in other information, but it will not persist until/unless you call save() afterwards.
Does the emplid already exist in the personal data component? If so, you should be calling get() instead.
Does the emplid already exist in the peoplesoft instance? If not, you should make sure it is in the system prior to using it.
Regarding the lack of error behavior, I have found the peoplesoft component interface APIs for java are notoriously unreliable. You can test them in real time through Application Designer (Via the "Test Component Interface" option in the drop-down menu), which I often find helpful.
Finally, calling session.checkMessages() on your session after performing a method on a CI can often generate error messages that otherwise will not be displayed.
EDIT: Here is a snippet of how we typically call/use it in our PeopleSoft HR instance:
ICiPersonalData wh = (ICiPersonalData)ses.getComponent("CI_PERSONAL_DATA");
if (wh == null) throw new UpdateException("Failed to get component");
wh.setInteractiveMode(true);
wh.setGetHistoryItems(true);
wh.setEditHistoryItems(true);
wh.setKeypropEmplid(emplid);
if (!existsInHR(emplid)) { // Direct database check
LOG.debug("Creating a new HR person.");
if ( ! wh.create() )
LOG.warn("wh.create returned false for emplid ="+emplid);
ses.checkMessages(); // will throw exception if errors exist
wh.setPropDerivedEmp("Y");
rs.put("NEW","Y");
setKeyPersonalData(wh, emplid, rs); // Sets name, etc.
} else {
if (!wh.get())
LOG.warn("wh.get returned false for emplid ="+emplid);
ses.checkMessages();
}

Java Code to fetch Session Store attribute values

I am writing an Assertion Generator Plugin in Java to fetch a user details from Session Store and modify the values in Assertion(SAML 2.0) accordingly.
I am able to identify the method(Link) using which I can pull the user values from Session Store (agentAPIObject.getSessionVariables()) based on SessionID, but, I am having trouble writing a code to fetch specific parameters from the session store. (speficially around setting values for Attribute method and making it as an array)
Can someone post a sample code if you have ever seen/written around it, so that I can fetch user attributes from Session Store.
I am having trouble understanding Java docs around it.
Thanks in advance,
The API mentions this:
responseAttributeList - On successful return from this method (YES is
returned), this output parameter contains the retrieved variable names
and their values. If the method returns UNRESOLVED, this parameter
includes variables that could not be retrieved.
You'll need to create two AttributeList Objects. If the response of getSessionVariables(...) is YES, then the variable responseAttributeList will contain the session variables. Since Java uses references, that same variable responseAttributeList will be updated. You can then use getAttributeAt(...) to access the Attribute Objects.
String sessionID = "sampleID";
ResourceContextDef rcd = //whatever it needs to be equal to
AttributeList requestAttributeList = new AttributeList();
AttributeList responseAttributeList = new AttributeList();
if(getSessionVariables(sessionId, rcd, requestAttributeList, responseAttributeList) == YES){
Attribute att = responseAttributeList.getAttributeAt(0);//or whatever index.
}
Remember to carefully read the API.
NOTE: This is just pseudo code. I have not tested this. However, this should be plenty enough to get you going where you need to.

Java InvocationTargetException

I have used EMC Documentum Foundation Classes to perform some actions in documentum repository. The code was working fine. I exported the project as a runnable JAR and then tried to run it. However I got following error and I am not able to understand it.
And here is the code for DocMovementHandler.getSession()
Actually this is no new code but regular code for obtaining documentum session
public IDfSession getSession(String userName, String password)
{
DfClientX clientx = null;
IDfClient client = null;
IDfSession session = null;
try {
// create a client object using a factory method in DfClientX
clientx = new DfClientX();
client = clientx.getLocalClient(); //takes time
// call a factory method to create the session manager
IDfSessionManager sessionMgr = client.newSessionManager();
// create an IDfLoginInfo object and set its fields
IDfLoginInfo loginInfo = clientx.getLoginInfo();
loginInfo.setUser(userName);
loginInfo.setPassword(password);
// set single identity for all docbases
sessionMgr.setIdentity("xyz_repo", loginInfo);
session = sessionMgr.getSession("xyz_repo"); //takes time
//sessionMgr.beginTransaction();
System.out.println("Session obtaied.");
}
catch (DfServiceException dse)
{
DfLogger.debug(this, "Error while beginning transaction. ", null, dse);
dse.printStackTrace();
}
catch (Exception e)
{
DfLogger.debug(this, "Error while creating a new session. ", null, e);
e.printStackTrace();
}
return session;
}
And that line 38 is client = clientx.getLocalClient();
InvocationTargetException is a wrapper. It says, "an exception occurred behind this reflection call", and you use getCause() to get at the inner exception.
The stack trace contains the inner exception. It's an ExceptionInInitializerError. That's another wrapper. It says, "whatever you did caused a new class to be loaded, and that class's static initializer threw an exception".
The final exception in this chain is the NullPointerException. That's the one you need to solve. Which means you need to debug this com.documentum thing. As the comments pointed out, that's not going to be easy.
Here is the most likely problem:
The static initializer in one of the classes whose names you have struck is adding an entry with either a null key or a null value to a Hashtable, which does not allow null keys or values.
It is using the Hashtable as a place to store a bunch of persistent properties and all that, and my guess is that the value for one of the entries was the null (which is a perfectly reasonable way to indicate that some feature is unavailable or something like that).
The now deprecated Hashtable needs to be replaced with the more modern HashMap.
If it is a library, that you can't just modify, you should replace the whole library with an updated version.
Here are some clues may be helpful.
The NullPointerException is thrown by Hashtable#put, and this is normally because either the key or the value is null.
Hashtable#put is called by PreferenceManager.readPersistenceProperties, so most likely it's because something is missing in a properties file so the value is null.
This NPE caused the DfClient class could not be loaded.
DfPreferences is the class loading the DFC configuration file dfc.properties. There must be something wrong with it.
Ohkay I did not pin pointed the root cause, but found the solution that will definitely work everytime.
EMC provides a flavor of Eclipse called Documentum Composer to work with Documentum Projects. Since Eclipse variation we can create other types of projects like normal Java project, dynamic web project, web services in this. So I recreated my project in Documetnum Composer and exported it as JAR and whoaaaa it worked.
I tried this many times and this worked all time.
Some points to note:
You have to replace dfc.properties file in Composer installation folder with one in Content Server
The Export to JAR wizard in Composer is a bit different than one in Eclipse
This is usually caused by dfc.properties being incorrect.
Preferences are stored on the global registry repository and the connection details should be specified in dfc.properties. If not, this (or a similar error can occur).
Also, always try to clear cache and use the correct version of the dfc jar's (v6.7 content server requires 6.7 jars, etc...).

Categories