How to generate a pkcs7 signature envelope using pkcs11interop - signature

To prevent the token password dialog, I usually use pkcs11interop to login to the usbkey and do data signature use capi or some COM+ control in C#.
But now I have a new usbkey. When I do signature the first time it still display the login dialog. This key's pkcs11 dll does not implement function C_SignUpdate, so when I try to do signature use SunPkcs11 and BouncyCastle in Java it throw a exception:
public static void main(String args[]) throws Exception {
String configName = "d:\\javakey_My.cfg";
String PIN = "123456";
Provider prv = new SunPKCS11(configName);
Security.addProvider(prv);
KeyStore credentials = KeyStore.getInstance("PKCS11");
char[] pin = PIN.toCharArray();
credentials.load(null, pin);
Key key = (PrivateKey) credentials.getKey("My Cert ID", null);
Certificate[] chain = credentials
.getCertificateChain("My Cert ID");
X509Certificate cert = (X509Certificate) chain[0];
Store certs = new JcaCertStore(Arrays.asList(chain));
// set up the generator
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder()
.setProvider("SunPKCS11-MyKey").build("SHA1withRSA",
(PrivateKey) key, cert));
gen.addCertificates(certs);
// create the signed-data object
CMSTypedData data = new CMSProcessableByteArray(
"Hello World!".getBytes());
CMSSignedData signed = gen.generate(data, false);
}
Exception in thread "main" java.security.ProviderException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_FUNCTION_NOT_SUPPORTED
at sun.security.pkcs11.P11Signature.engineUpdate(P11Signature.java:436)
at java.security.Signature$Delegate.engineUpdate(Unknown Source)
at java.security.Signature.update(Unknown Source)
at java.security.Signature.update(Unknown Source)
at org.bouncycastle.operator.jcajce.JcaContentSignerBuilder$SignatureOutputStream.write(Unknown Source)
at org.bouncycastle.cms.SignerInfoGenerator.generate(Unknown Source)
at org.bouncycastle.cms.CMSSignedDataGenerator.generate(Unknown Source)
at Tryit.main(Tryit.java:108)
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_FUNCTION_NOT_SUPPORTED
at sun.security.pkcs11.wrapper.PKCS11.C_SignUpdate(Native Method)
at sun.security.pkcs11.P11Signature.engineUpdate(P11Signature.java:430)
... 7 more
Is there any way to do a P7 signature use this key? by .Net or Java, without login dialog.

Related

com.jscape.inet.sftp.SftpException: cause: java.util.NoSuchElementException: no common elements found- JSCAPE Java library

I tried to connect and download a file from a Linux server but faced the following exception when connecting to the server using the jscape java library.
Code
package com.example.util;
import com.jscape.inet.sftp.Sftp;
import com.jscape.inet.ssh.util.SshParameters;
public class TestFTPManager
{
private static final String hostname = "mycompany.example.com";
private static final String username = "exampleuser";
private static final String password = "examplepassword";
private static final int port = 22;
private Sftp sftpClient;
public TestFTPManager()
{
this.sftpClient = new Sftp( new SshParameters(hostname, port, username, password ));
}
public void connect() throws Exception
{
this.sftpClient.connect();
}
public void setAscii() throws Exception
{
this.sftpClient.setAscii();
}
public void setBinary() throws Exception
{
this.sftpClient.setBinary();
}
public Sftp getSftpClient()
{
return sftpClient;
}
public void setSftpClient( Sftp sftpClient )
{
this.sftpClient = sftpClient;
}
public static void main(String[] args)
{
try
{
TestFTPManager sftpManager = new TestFTPManager();
sftpManager.getSftpClient().connect(); // Error
System.out.println( "Connection successful!" );
// download operation is done here.
sftpManager.getSftpClient().disconnect();
System.out.println( "Disconnection successful!" );
} catch (Exception e)
{
e.printStackTrace();
}
}
}
Error
com.jscape.inet.sftp.SftpException: cause: java.util.NoSuchElementException: no common elements found
at com.jscape.inet.sftp.SftpConfiguration.createClient(Unknown Source)
at com.jscape.inet.sftp.Sftp.connect(Unknown Source)
at com.jscape.inet.sftp.Sftp.connect(Unknown Source)
at com.example.util.TestFTPManager.main(TestFTPManager.java:54)
Caused by: com.jscape.inet.ssh.transport.TransportException: cause: java.util.NoSuchElementException: no common elements found
at com.jscape.inet.ssh.transport.AlgorithmSuite.<init>(Unknown Source)
at com.jscape.inet.ssh.transport.TransportClient.getSuite(Unknown Source)
at com.jscape.inet.ssh.transport.Transport.exchangeKeys(Unknown Source)
at com.jscape.inet.ssh.transport.Transport.exchangeKeys(Unknown Source)
at com.jscape.inet.ssh.transport.TransportClient.<init>(Unknown Source)
at com.jscape.inet.ssh.transport.TransportClient.<init>(Unknown Source)
at com.jscape.inet.ssh.SshConfiguration.createConnectionClient(Unknown Source)
at com.jscape.inet.ssh.SshStandaloneConnector.openConnection(Unknown Source)
... 4 more
Caused by: java.util.NoSuchElementException: no common elements found
at com.jscape.inet.ssh.types.SshNameList.getFirstCommonNameFrom(Unknown Source)
at com.jscape.inet.ssh.transport.AlgorithmSuite.a(Unknown Source)
at com.jscape.inet.ssh.transport.AlgorithmSuite.h(Unknown Source)
... 12 more
However, when I commented down the following lines (lines no 23,23,25) in the /etc/ssh/sshd_config file in the server. I could successfully connect and download the file from the server without any exceptions.
Question: How to get rid of getting this exception without commenting down (lines no 23,23,25) the /etc/ssh/sshd_config file in the server? I would appreciate having an explanation why I get this exception too.
If you are facing this issue please check the following findings.
I used JSCAPE (Java) library version 8.8.0. According to my understanding, this version is not supported some of the Ciphers and KexAlgorithms specified in the sshd_config file.
When you refer to the JSCAPE documentation, com.jscape.inet.sftp class contains what you need to set key exchanges, ciphers, macs and compressions if needed. Please click here to see the official documentation, there you can see how you can put these things into code.
However, the JSCAPE (Java) library that I use (version 8.8.0) does not contain these classes and methods to set key exchanges, ciphers, macs and compressions if needed.
One of the things you can try is to use the latest version of the JSCAPE library, but I doubt it is available for free.

adal4j Auth issue

Hi i wrote a deamon app that uses Microsoft active directory, the app works fine in development environment but in production (AWS EC2 instance) i get this error :
java.lang.Exception: Server returned error in RSTR - ErrorCode: FailedAuthentication : FaultMessage: MSIS7068 : accès refusé.
at com.microsoft.aad.adal4j.WSTrustResponse.parse(WSTrustResponse.java:103) ~[adal4j-1.0.0.jar:1.0.0]
at com.microsoft.aad.adal4j.WSTrustRequest.execute(WSTrustRequest.java:69) ~[adal4j-1.0.0.jar:1.0.0]
at com.microsoft.aad.adal4j.AuthenticationContext.processPasswordGrant(AuthenticationContext.java:790) ~[adal4j-1.0.0.jar:1.0.0]
at com.microsoft.aad.adal4j.AuthenticationContext.access$000(AuthenticationContext.java:63) ~[adal4j-1.0.0.jar:1.0.0]
at com.microsoft.aad.adal4j.AuthenticationContext$1.call(AuthenticationContext.java:129) [adal4j-1.0.0.jar:1.0.0]
at com.microsoft.aad.adal4j.AuthenticationContext$1.call(AuthenticationContext.java:119) [adal4j-1.0.0.jar:1.0.0]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_171]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_171]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_171]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171]
2018-07-19 08:40:02.829 ERROR 5072 --- [nio-8083-exec-1] f.a.agent.reservation.utils.OAuth : java.util.concurrent.ExecutionException: java.lang.Exception: Server returned error in RSTR - ErrorCode: FailedAuthentication : FaultMessage: MSIS7068 : accès refusé.
I dont understand what's going on here because Dev and Prod envs are ISO.
This is the class that connects to active directory :
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.microsoft.aad.adal4j.AuthenticationContext;
import com.microsoft.aad.adal4j.AuthenticationResult;
import lombok.extern.java.Log;
#Log
public class OAuth {
private static String TOKEN = null;
private final static String AUTHORITY_URL = "https://login.microsoftonline.com/common/";
private final static String GRAPH_URL = "https://graph.microsoft.com";
private final static String CLIENT_ID = "*****";
private final static String USERNAME = "*****";
private final static String PASSWORD = "*****";
public static final String getToken() throws Exception {
if (null == TOKEN) {
AuthenticationContext context;
AuthenticationResult result = null;
ExecutorService service = null;
log.info("Auth with : " + USERNAME);
try {
service = Executors.newFixedThreadPool(1);
context = new AuthenticationContext(AUTHORITY_URL, false, service);
Future<AuthenticationResult> future = context.acquireToken(GRAPH_URL, CLIENT_ID, USERNAME, PASSWORD, null);
result = future.get();
}catch (Exception e){
log.severe(e.toString());
} finally {
service.shutdown();
}
if (result == null) {
log.severe("AUTH FAILLURE");
} else {
TOKEN = result.getAccessToken();
}
}
return TOKEN;
}
}
Thank you.
I just found the origin of this problem by trying to connect using a refresh token obtained from my company's network.
"error_description":"AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '00000003-0000-0000-c000-000000000000'.\r\nTrace ID: xxxxx\r\nCorrelation ID: xxxxxx b\r\nTimestamp: 2018-07-20 12:34:45Z","error":"interaction_required"
So i understand that two factor auth is not required from inside my company's network but it is required outside of it.
I will have to contact the administrator of office 365 in my company to have special account to authenticate without two factor authentication.
For the flow you are using (resource owner password credential - by directly providing user credentials) you have to use the tenant specific endpoint. Which means, you have to change:
private final static String AUTHORITY_URL = "https://login.microsoftonline.com/common/";
to
private final static String AUTHORITY_URL = "https://login.microsoftonline.com/<tenant_id>/";
Where you can use your either tenant domain (i.e. yourdomain.onmicrosoft.com) or the tenant_id in <tenant_id>.

how to configure a certificate to invoke a HTTPS end point using HTTP POST action API application

I am new to Azure development and want some help.
I have a HTTPS end point of a web service from my third party.
The webservice call uses a client certificate and user name and password for invoking the SOAP action.
I am using a default HTTP action API and passing the URL, headers, authentication and body as required.
How can i set the certificate setting there ??
Any help or way forward would be great help.Thanks in advance
This is an example for Java, you should find the right implementation for the language that you use.
public static void main(String[] args) throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
try {
SSLContext ctx = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = getTrustManagers("jks", new FileInputStream(new File("cacerts")), "changeit");
KeyManager[] keyManagers = getKeyManagers("pkcs12", new FileInputStream(new File("clientCert.pfx")), "password");
ctx.init(keyManagers, trustManagers, new SecureRandom());
SSLSocketFactory factory = new SSLSocketFactory(ctx, new StrictHostnameVerifier());
ClientConnectionManager manager = httpClient.getConnectionManager();
manager.getSchemeRegistry().register(new Scheme("https", 443, factory));
//as before
}
}
protected static KeyManager[] getKeyManagers(String keyStoreType, InputStream keyStoreFile, String keyStorePassword) throws Exception {
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(keyStoreFile, keyStorePassword.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keyStorePassword.toCharArray());
return kmf.getKeyManagers();
}
protected static TrustManager[] getTrustManagers(String trustStoreType, InputStream trustStoreFile, String trustStorePassword) throws Exception {
KeyStore trustStore = KeyStore.getInstance(trustStoreType);
trustStore.load(trustStoreFile, trustStorePassword.toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
return tmf.getTrustManagers();
}
PS: This code was provided by Barry Pitman in this link

SMB connection with java

Hi i have created a test program to connect with SMB protocol. My motive is to create a test.txt file on a shared location like String path="smb://192.168.143.134/rtf2xml/"+sharedFolder+"/test.txt";
But when I try to run my program (below is the code sample)
import java.io.IOException;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileOutputStream;
public class Test {
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
String user = "abc";
String pass ="123456";
String sharedFolder="INPUT";
String path="smb://192.168.143.134/rtf2xml/"+sharedFolder+"/test.txt";
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("192.168.143.134",user, pass);
SmbFile smbFile = new SmbFile(path, auth);
smbFile.createNewFile();
SmbFileOutputStream smbfos = new SmbFileOutputStream(smbFile);
smbfos.write("testing....and writing to a file".getBytes());
System.out.println("completed ...nice !");
}
}
It is throwing exception
Exception in thread "main" jcifs.smb.SmbException: Failed to negotiate
jcifs.smb.SmbException: Timeout trying to open socket
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at jcifs.netbios.NbtSocket.<init>(NbtSocket.java:59)
at jcifs.smb.SmbTransport.run(SmbTransport.java:342)
at java.lang.Thread.run(Unknown Source)
at jcifs.smb.SmbTransport.start(SmbTransport.java:315)
at jcifs.smb.SmbTransport.negotiate0(SmbTransport.java:865)
at jcifs.smb.SmbTransport.negotiate(SmbTransport.java:941)
at jcifs.smb.SmbTree.treeConnect(SmbTree.java:119)
at jcifs.smb.SmbFile.connect(SmbFile.java:827)
at jcifs.smb.SmbFile.connect0(SmbFile.java:797)
at jcifs.smb.SmbFile.open0(SmbFile.java:852)
at jcifs.smb.SmbFile.createNewFile(SmbFile.java:2265)
at Test.main(Test.java:22)
at jcifs.smb.SmbTransport.negotiate(SmbTransport.java:947)
at jcifs.smb.SmbTree.treeConnect(SmbTree.java:119)
at jcifs.smb.SmbFile.connect(SmbFile.java:827)
at jcifs.smb.SmbFile.connect0(SmbFile.java:797)
at jcifs.smb.SmbFile.open0(SmbFile.java:852)
at jcifs.smb.SmbFile.createNewFile(SmbFile.java:2265)
at Test.main(Test.java:22)
How to get rid of this?
But l think you have to make sure that the destination server(192.168.143.134) is up and alive.
you can write it the following way, since the IP in included in the smb link.
public static void main(String[] args) throws IOException {
String user = "abc";
String pass ="123456";
String sharedFolder="INPUT";
String path="smb://192.168.143.134/rtf2xml/"+sharedFolder+"/test.txt";
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("",user, pass);//note here
SmbFile smbFile = new SmbFile(path, auth);
smbFile.createNewFile();
SmbFileOutputStream smbfos = new SmbFileOutputStream(smbFile);
smbfos.write("testing....and writing to a file".getBytes());
System.out.println("completed ...nice !");
}
....

rewriting a series in JavaFX linechart

I have a JavaFX app that utilizes the lineChart chart. I can write a chart to the app, and clear it, but when I want to write a new series and have it displayed, I get an error,
java.lang.IllegalArgumentException: Children: duplicate children added:
I understand the meaning, but not how to fix (I am very new to Java, let alone to FX).
Here is the relevant code from my controller (minus some class declarations):
(method called by the 'submit' button in chart tab window)
#FXML
private void getEngDataPlot(ActionEvent event) {
//check time inputs
boolean start = FieldVerifier.isValidUtcString(startRange.getText());
boolean end = FieldVerifier.isValidUtcString(endRange.getText());
type = engData.getValue().toString();
// Highlight errors.
startRangeMsg.setTextFill(Color.web(start ? "#000000" : "#ff0000"));
endRangeMsg.setTextFill(Color.web(end ? "#000000" : "#ff0000"));
if (!start || !end ) {
return;
}
// Save the preferences.
Preferences prefs = Preferences.userRoot().node(this.getClass().getName());
prefs.put("startRange", startRange.getText());
prefs.put("endRange", endRange.getText());
prefs.put("engData", engData.getValue().toString());
StringBuilder queryString = new StringBuilder();
queryString.append(String.format("edit out",
startRange.getText(),
endRange.getText()));
queryString.append(type);
log(queryString.toString());
// Start the query task.
submitEngData.setDisable(true);
// remove the old series.
engChart.getData().clear();
engDataProgressBar.setDisable(false);
engDataProgressBar.setProgress(-1.0);
//ProgressMessage.setText("Working...");
Thread t = new Thread(new EngDataPlotTask(queryString.toString()));
t.setDaemon(true);
t.start();
}
(the task called by above method:)
public EngDataPlotTask(String query) {
this.query = query;
}
#Override
protected Void call() {
try {
URL url = new URL(query);
String inputLine = null;
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
// while ( in.readLine() != null){
inputLine = in.readLine(); //}
Gson gson = new GsonBuilder().create();
DataObject[] dbin = gson.fromJson(inputLine, DataObject[].class);
in.close();
for (DataObject doa : dbin) {
series.getData().add(new XYChart.Data(doa.danTime, doa.Fvalue));
}
xAxis.setLabel("Dan Time (msec)");
} catch (Exception ex) {
log(ex.getLocalizedMessage());
}
Platform.runLater(new Runnable() {
#Override
public void run() {
submitEngData.setDisable(false);
// do some pretty stuff
String typeName = typeNameToTitle.get(type);
series.setName(typeName);
// put this series on the chart
engChart.getData().add(series);
engDataProgressBar.setDisable(true);
engDataProgressBar.setProgress(1.0);
}
});
return null;
}
}
The chart draws a first time, clears, and then the exception occurs. Requested stack trace follows:
Exception in runnable
java.lang.IllegalArgumentException: Children: duplicate children added: parent = Group#8922394[styleClass=plot-content]
at javafx.scene.Parent$1.onProposedChange(Unknown Source)
at com.sun.javafx.collections.VetoableObservableList.add(Unknown Source)
at com.sun.javafx.collections.ObservableListWrapper.add(Unknown Source)
at javafx.scene.chart.LineChart.seriesAdded(Unknown Source)
at javafx.scene.chart.XYChart$2.onChanged(Unknown Source)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(Unknown Source)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(Unknown Source)
at com.sun.javafx.collections.ObservableListWrapper.callObservers(Unknown Source)
at com.sun.javafx.collections.ObservableListWrapper.add(Unknown Source)
at com.sun.javafx.collections.ObservableListWrapper.add(Unknown Source)
at edu.arizona.lpl.dan.DanQueryToolFX.QueryToolController$EngDataPlotTask$1.run(QueryToolController.java:231)
at com.sun.javafx.application.PlatformImpl$4.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(Unknown Source)
at com.sun.glass.ui.win.WinApplication$2$1.run(Unknown Source)
at java.lang.Thread.run(Thread.java:722)
Any ideas what I am doing wrong. I am a RANK NEWBIE, so please take that into account if you wish to reply. Thank you!
It took long time to find a workaround solution for this issue.
Please add below piece of code and test:
engChart.getData().retainAll();
engChart.getData().add(series);
My guess about the root cause according to your incomplete code is this line:
engChart.getData().add(series);
You should add series only once in initialize block for instance. But I think in your task thread, you are adding the already added same series again and having that mentioned exception. If your aim is to refresh the only series data, then just manipulate the series, getting it by engChart.getData().get(0); and delete that line in the code.
Once you add the series to the graph all you do is edit the series. Don't add it to the graph again.
The graph will follow whatever happens to the series i.e. just change the series data and the graph will automatically reflect the changes.

Resources