When I try to verify signed pdf document I get RuntimeException:
Exception in thread "main" java.lang.RuntimeException: algorithm identifier 1.2.398.3.10.1.1.1.1 in key not recognised
at org.bouncycastle.jce.provider.JDKKeyFactory.createPublicKeyFromPublicKeyInfo(Unknown Source)
at org.bouncycastle.jce.provider.X509CertificateObject.getPublicKey(Unknown Source)
at com.itextpdf.text.pdf.PdfPKCS7.<init>(PdfPKCS7.java:582)
at com.itextpdf.text.pdf.PdfPKCS7.<init>(PdfPKCS7.java:421)
at com.itextpdf.text.pdf.AcroFields.verifySignature(AcroFields.java:2307)
at Main.verifyPDF(Main.java:62)
at Main.main(Main.java:90)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
my verification piece of code looks like this:
public static boolean verifyPDF(String fileToVerify, KeyStore trustedStore, CRL crl) throws IOException, GeneralSecurityException {
List<CRL> crls = null;
if (crl != null) {
crls = new ArrayList<CRL>(1);
crls.add(crl);
}
boolean result = false;
PdfReader checker = new PdfReader(fileToVerify);
AcroFields af = checker.getAcroFields();
ArrayList<String> names = af.getSignatureNames();
for (int k = 0; k < names.size(); ++k) {
String name = (String) names.get(k);
System.out.println("Signature: " + name);
com.itextpdf.text.pdf.PdfPKCS7 pk = af.verifySignature(name, "KALKAN");
result = pk.verify();
System.out.println("Signer certificate DN: " + pk.getSigningCertificate().getSubjectDN());
Calendar cal = pk.getSignDate();
X509Certificate pkc[] = (X509Certificate[]) pk.getSignCertificateChain();
System.out.println("Document modified: " + !result);
Object fails[] = PdfPKCS7.verifyCertificates(pkc, trustedStore, crls, cal);
if (fails == null)
System.out.println("Certificates verified against the KeyStore");
else
System.out.println("Certificate failed: " + fails[1]);
}
return result;
}
the exception occurs on this string:
com.itextpdf.text.pdf.PdfPKCS7 pk = af.verifySignature(name, "KALKAN");
I use patched iText library. I had to patch it because there was no algorithm like ECGOST34310 and I just added it. Signing is performed in usual way, there is no problem with it.
Please help!
Thanks.
At first glance that OID 1.2.398.3.10.1.1.1.1 seems to be defined by a Kazakh authority (cf. this page), related to GOST 34,310-2.004 represented by the parent OID, without having yet been included in the mainstream BouncyCastle distribution, cf. the BouncyCastle specifications.
Thus, just like you have extended iText to be able to sign using GOST 34,310-2.004
I use patched iText library. I had to patch it because there was no algorithm like ECGOST34310 and I just added it.
you have to extend it (or in this case more exactly the crypto library BouncyCastle used by iText) to be able to verify signatures using GOST 34,310-2.004. Maybe, though, someone else already has done that and comes forth to help?
By the way, it would be great if you shared the results as soon as they work.
That all been said I am not aware of GOST being mentioned in the context of either ISO 32000-1 or PAdES integrated PDF signatures. Using GOST for PDF signatures, therefore, will likely result in very limited interoperability.
Related
I'm working on a java application that interacts with Word through an OLE library (org.eclipse.swt.ole.win32) to merge documents (mail merge).
the java method which makes it possible to merge has been working for several years without any particular problem.
but recently the data source can no longer be associated with the merge document.
This problem is random (on some workstations it works and on others it doesn't, yet same system configuration)
I have no explicit error reported on the java side
Here is the method that communicates with Word:
public void mergeDocument(File model, File source) throws Exception {
OleAutomation autoMailMerge = null;
LOGGER.log(new Status(IStatus.INFO, pluginID, "Merge d un document"));
LOGGER.log(new Status(IStatus.INFO, pluginID, "fichier modele: " + model.getCanonicalPath()));
LOGGER.log(new Status(IStatus.INFO, pluginID, "fichier source: " + source.getPath()));
openDocumentReadOnly(model);
autoMailMerge = OLEHelper.getAutomationProperty(autoDocument, "MailMerge");
if ((source != null) && (source.exists()) && (!source.isDirectory())) {
OLEHelper.invoke(autoMailMerge, "OpenDataSource", source.getPath());
} else {
throw new MSWordOleInterfaceException(MSWordOleInterfaceCst.MSG_ERROR_EMPTY_SOURCE_PATH
+ ((source == null) ? "null" : source.getPath()));
}
OLEHelper.invoke(autoMailMerge, "Execute");
OleAutomation autoDocumentMerged = getActiveDocument();
closeDocument(autoDocument);
activateDocument(autoDocumentMerged);
autoDocument = autoDocumentMerged;
autoMailMerge.dispose();
}
Merging by hand from Word (associating the data source and merging) works on workstations where the java application does not work.
thanks to the OLE command I validated that it is the data source which is not passed (on a workstation which works I have a return with the name of the source, on one or it does not work the return is empty)
LOGGER.log(new Status(IStatus.INFO, pluginID, "data source name: "
+ OLEHelper.getVariantProperty(autoDataSource, "Name").getString()));
-a temporary solution has been found, by deleting the registry key related to office:
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Word\DocumentTemplateCache
but this is only a temporary solution, the problem comes back.
I'm using BouncyCastle to issue X509 certificates. I've found many code examples where the signature algorithm name is fixed like "SHA256WithRSAEncryption" here:
ContentSigner sigGen = new JcaContentSignerBuilder("SHA256WithRSAEncryption")
.setProvider(BC).build(privKey);
Is there a method in BouncyCastle or JDK to find the preferred signature algorithm name for given PrivateKey? Something like getPreferredSignatureAlgorithm() here:
// is there method like this?
String signatureAlgorithm = getPreferredSignatureAlgorithm(issuerPrivKey);
JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(...);
ContentSigner signer = new JcaContentSignerBuilder(signatureAlgorithm)
.build(issuerPrivKey);
X509Certificate certificate = new JcaX509CertificateConverter()
.setProvider(new BouncyCastleProvider())
.getCertificate(builder.build(signer));
Answering to my own question, I ended up simply implementing my own method like this
private static String signatureAlgorithm(PublicKey pub) {
switch (pub.getAlgorithm()) {
case "EC":
EllipticCurve curve = ((ECPublicKey) pub).getParams().getCurve();
switch (curve.getField().getFieldSize()) {
case 224:
case 256:
return "SHA256withECDSA";
case 384:
return "SHA384withECDSA";
case 521:
return "SHA512withECDSA";
default:
throw new IllegalArgumentException("unknown elliptic curve: " + curve);
}
case "RSA":
return "SHA256WithRSAEncryption";
default:
throw new UnsupportedOperationException("unsupported private key algorithm: " + pub.getAlgorithm());
}
}
Recommended message digest algorithms for EC curves are given in RFC5480 in a table on page 9 (errata).
I encounter "No suitable native library found" when running some library (HDF5).
Full trace is follows:
java.lang.ExceptionInInitializerError
at ch.systemsx.cisd.hdf5.hdf5lib.HDF5Constants.javaToC(HDF5Constants.java:1938)
at ch.systemsx.cisd.hdf5.hdf5lib.HDF5Constants.<clinit>(HDF5Constants.java:982)
at ch.systemsx.cisd.hdf5.CharacterEncoding.<clinit>(CharacterEncoding.java:29)
at ch.systemsx.cisd.hdf5.HDF5BaseReader.<init>(HDF5BaseReader.java:137)
at ch.systemsx.cisd.hdf5.HDF5BaseWriter.<init>(HDF5BaseWriter.java:147)
at ch.systemsx.cisd.hdf5.HDF5WriterConfigurator.writer(HDF5WriterConfigurator.java:133)
at ch.systemsx.cisd.hdf5.HDF5FactoryProvider$HDF5Factory.open(HDF5FactoryProvider.java:48)
at ch.systemsx.cisd.hdf5.HDF5Factory.open(HDF5Factory.java:47)
at tests.jhdf5.TestHDF5.testReaderWriter(TestHDF5.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
...
Caused by: java.lang.UnsupportedOperationException: No suitable HDF5 native library found for this platform.
at ch.systemsx.cisd.hdf5.hdf5lib.H5.<clinit>(H5.java:41)
... 30 more
As you see, library is called from inside HDF5 java library.
Java library is attached as bunch of jars in global libraries:
As you see, native library is included.
The question is whether this setting is sufficient? May be I require to add some directories to the PATH variable?
UPDATE
I found, that HDF5 code expects library inside native.libpath.jhdf5, the code is from ch.systemsx.cisd.base.utilities.NativeLibraryUtilities#loadNativeLibrary():
public static boolean loadNativeLibrary(String libraryName) {
String linkLibNameOrNull = System.getProperty("native.libpath." + libraryName);
if(linkLibNameOrNull != null) {
return loadLib(linkLibNameOrNull);
} else {
String linkLibPathOrNull = System.getProperty("native.libpath");
if(linkLibPathOrNull != null) {
linkLibNameOrNull = getLibPath(linkLibPathOrNull, libraryName);
return loadLib(linkLibNameOrNull);
} else {
linkLibNameOrNull = tryCopyNativeLibraryToTempFile(libraryName);
return linkLibNameOrNull != null?loadLib(linkLibNameOrNull):loadSystemLibrary(libraryName);
}
}
}
While IntelliJ sets java.library.path:
public static void main(String[] args) {
System.out.println("native.libpath.jhdf5 = " + System.getProperty("native.libpath.jhdf5") );
System.out.println("java.library.path = " + System.getProperty("java.library.path") );
prints:
native.libpath.jhdf5 = null
java.library.path = D:\Users\Dims\Design\!Lib\sis-jhdf5-SNAPSHOT-r32355\sis-jhdf5\lib\nativejar\hdf5-windows-intel.jar
Why?
You may have the same problem as me.
The problem was that i had include the jar for the 3 differents platforms (linux, windows and macOS) thus there was a conflict and this problem happen
If it does not solved the case (as it has do in mine) i suggest to consult the jhdf5 faq https://wiki-bsse.ethz.ch/display/JHDF5/JHDF5+FAQ
So far, I've been working with a certificate which I added to a SoapUI 5.2 project and which gave me access to a pre-production server. However, now that I'm ready to move to a production environment, I'm trying to check the new production certificate with SoapUI, but I'm getting the next error:
WARN:Using fallback method to load keystore/truststore due to: Invalid keystore format
ERROR:An error occurred [java.lang.NullPointerException], see error log for details
And the error log says:
ERROR:Could not load keystore/truststore
ERROR:java.lang.NullPointerException
java.lang.NullPointerException
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:176)
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:97)
at org.apache.commons.ssl.KeyStoreBuilder.build(KeyStoreBuilder.java:88)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.fallbackLoad(KeyMaterialWssCrypto.java:206)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.load(KeyMaterialWssCrypto.java:168)
at com.eviware.soapui.impl.wsdl.support.wss.crypto.KeyMaterialWssCrypto.getStatus(KeyMaterialWssCrypto.java:216)
at com.eviware.soapui.impl.wsdl.panels.project.WSSTabPanel$CryptoTableModel.getValueAt(WSSTabPanel.java:643)
at javax.swing.JTable.getValueAt(Unknown Source)
at javax.swing.JTable.prepareRenderer(Unknown Source)
...
The only difference I found between the pre-production and production certificates was that the latter did not have the CommonName field defined.
I know that field is not mandatory, so how is that possible? How can I solve this problem without asking for a new certificate? That's not an option.
Any suggestion would be appreciated.
I check the pom.xml of SOAPUI project for 5.2 versión, and it use not-yet-commons-ssl versión 0.3.11:
<dependency>
<groupId>commons-ssl</groupId>
<artifactId>not-yet-commons-ssl</artifactId>
<version>0.3.11</version>
</dependency>
And If you check the build method for org.apache.commons.ssl.KeyStoreBuilder class as the exception thrown in your error log you'll see:
public static KeyStore build(byte[] jksOrCerts, byte[] privateKey,
char[] jksPassword, char[] keyPassword)
throws IOException, CertificateException, KeyStoreException,
NoSuchAlgorithmException, InvalidKeyException,
NoSuchProviderException, ProbablyBadPasswordException,
UnrecoverableKeyException {
...
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, jksPassword);
Iterator keysIt = keys.iterator();
Iterator chainsIt = chains.iterator();
int i = 1;
while (keysIt.hasNext() && chainsIt.hasNext()) {
Key key = (Key) keysIt.next();
Certificate[] c = (Certificate[]) chainsIt.next();
X509Certificate theOne = buildChain(key, c);
String alias = "alias_" + i++;
// The theOne is not null, then our chain was probably altered.
// Need to trim out the newly introduced null entries at the end of
// our chain.
if (theOne != null) {
c = Certificates.trimChain(c);
alias = Certificates.getCN(theOne);
/* line 176 */ alias = alias.replace(' ', '_');
}
ks.setKeyEntry(alias, key, keyPassword, c);
}
return ks;
}
}
So seems that you're right and the problem is that your certificate has no common name, so org.apache.commons.ssl.Certificates.getCN(X509Certificate) returns null as alias and then alias.replace is throwing the NPE.
alias = Certificates.getCN(theOne);
/* line 176 */ alias = alias.replace(' ', '_');
I don't see nothing that says that Common Name is mandatory in RFC5280, however various code/software use it for different purposes as not-yet-commons-ssl does.
Your certificate is probably right but you can't use it with SOAPUI 5.2 version to test your environment if it hasn't the CN, so if you want to use SOAPUI to test your environment I think that you've to reissue the certificate generating a CSR with CN. Or you can report the problem to http://juliusdavies.ca/commons-ssl/ and then ask to SOAPUI to include the latest version...
Hope this helps,
Please note: Although there are several questions on SO that paste in a similar exception & stack trace, this question is definitely not a dupe of any of them, as I'm trying to understand where my classloading is going awry.
Hi, Java 8/Groovy 2.4.3/Eclipse Luna here. I'm using the BigIP iControl Java client (for controlling a powerful load balancer programmatically) which in turn uses Apache Axis 1.4. In its use of Axis 1.4 I am getting the following stacktrace (from Eclipse console):
Caught: javax.xml.parsers.FactoryConfigurationError: Provider for javax.xml.parsers.DocumentBuilderFactory cannot be found
javax.xml.parsers.FactoryConfigurationError: Provider for javax.xml.parsers.DocumentBuilderFactory cannot be found
at org.apache.axis.utils.XMLUtils.getDOMFactory(XMLUtils.java:221)
at org.apache.axis.utils.XMLUtils.<clinit>(XMLUtils.java:83)
at org.apache.axis.configuration.FileProvider.configureEngine(FileProvider.java:179)
at org.apache.axis.AxisEngine.init(AxisEngine.java:172)
at org.apache.axis.AxisEngine.<init>(AxisEngine.java:156)
at org.apache.axis.client.AxisClient.<init>(AxisClient.java:52)
at org.apache.axis.client.Service.getAxisClient(Service.java:104)
at org.apache.axis.client.Service.<init>(Service.java:113)
at iControl.LocalLBPoolLocator.<init>(LocalLBPoolLocator.java:21)
at iControl.Interfaces.getLocalLBPool(Interfaces.java:351)
at com.me.myapp.F5Client.run(F5Client.groovy:27)
Hmmm, let's have a look at that XMLUtils.getDOMFactory method:
private static DocumentBuilderFactory getDOMFactory() {
DocumentBuilderFactory dbf;
try {
dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
}
catch( Exception e ) {
log.error(Messages.getMessage("exception00"), e );
dbf = null;
}
return( dbf );
}
OK, LN 221 is that call to DocumentBuilderFactory.newInstance() so let's have a look at it:
public static DocumentBuilderFactory newInstance() {
return FactoryFinder.find(
/* The default property name according to the JAXP spec */
DocumentBuilderFactory.class, // "javax.xml.parsers.DocumentBuilderFactory"
/* The fallback implementation class name */
"com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
}
The plot thickens! Now let's take a final look at FactoryFinder.find:
static <T> T find(Class<T> type, String fallbackClassName)
throws FactoryConfigurationError
{
final String factoryId = type.getName();
dPrint("find factoryId =" + factoryId);
// lots of nasty cruft omitted for brevity...
// Try Jar Service Provider Mechanism
T provider = findServiceProvider(type);
if (provider != null) {
return provider;
}
if (fallbackClassName == null) {
throw new FactoryConfigurationError(
"Provider for " + factoryId + " cannot be found"); // <<-- Ahh, here we go
}
dPrint("loaded from fallback value: " + fallbackClassName);
return newInstance(type, fallbackClassName, null, true);
}
So if I'm interpreting this right, it's throwing the FactoryConfigurationError because it can't find the main "provider class" (whatever that means) and no fallback has been specified. But hasn't it?!? The call to FactoryFinder.find included the non-null "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl" string argument. This has me suspicious that something is really wonky with my classpath, and that I have a rogue DocumentBuilderFactory (not the one defined in rt.jar/javax/xml/parsers) somewhere in my code that is passing a NULL arg to this finder method.
But that doesn't make sense either, because Axis 1.4 doesn't appear (at least according to Maven repo) to have any dependencies...which means the only "provider" for javax.xml.* would be the rt.jar. Unless, perhaps, Eclipse is mucking things up somehow? I'm so confused, please help :-/
Update
This is definitely an Eclipse issue. If I package my app as an executable JAR and run it from the command line I don't get this exception.