How could I express this java code in JRuby:
// Convert the store to a certificate chain
CertStore store = response.getCertStore();
Collection<? extends Certificate> certs = store
.getCertificates(null);
Certificate[] chain = new Certificate[certs.size()];
int i = 0;
for (Certificate certificate : certs) {
chain[i++] = certificate;
}
I have the "store" within JRuby and its recognised as a collection.
e.g.
puts store.type
#Collection
OK so the problem here is that I was passing in a regular expression and not a CertSelector object.
This code now works as expected.
store.get_certificates(nil)
Related
We have added pdfRevocationInfoArchival OID (1.2.840.113583.1.1.8) as a signed attribute while generating signature. While building this attribute we used external CRL file (ca-crl.crl) and builds the OID 1.2.840.113583.1.1.8 as ASN1 object. After signing pdf and timestamping signature, everything works fine. But we are not able to understand the identifier (adbe-revocationInfoArchival) which added is in the PDF is correct and which can be used to verify this PDF by fetching this OID. Also we are not able to check that this attribute is in proper format in which PDF can verify it. Is there any tool or utility available to check this attribute which is inserted as a signed attribute is valid.
If any PDF tool/utility is available to visualize attribute are available in PDF please share.
We have build the issuers CRL info at position [0] is this correct to way add the CRL in this OID? I have share the code below code snippet
The following object identifier identifies Adobe's revocation information attribute:
adbe-revocationInfoArchival OBJECT IDENTIFIER ::=
{ adbe(1.2.840.113583) acrobat(1) security(1) 8 }
Adobe's Revocation Information attribute value has ASN.1 type RevocationInfoArchival:
/**
** RevocationInfoArchival ::= SEQUENCE {
** crl [0] EXPLICIT SEQUENCE of CRLs, OPTIONAL
** ocsp [1] EXPLICIT SEQUENCE of OCSP Responses, OPTIONAL
** otherRevInfo [2] EXPLICIT SEQUENCE of OtherRevInfo, OPTIONAL
}
*/
Adobe's Revocation Information attribute value building using in Java Bouncy Castle API:
private ASN1EncodableVector genPdfInfoArchival(ASN1EncodableVector v) {
ASN1EncodableVector v1 = new ASN1EncodableVector();
List<X509CRL> crls = new ArrayList<X509CRL>();
ASN1InputStream t = null;
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
CRL crl = certFactory.generateCRL(new FileInputStream(new File("e://app//esp//crl//NSDLe-GovCA2019-Test-2.crl")));
System.out.println("crl:" + crl);
crls.add((X509CRL)crl);
if (!crls.isEmpty()) {
ASN1EncodableVector v11 = new ASN1EncodableVector();
for (Iterator<X509CRL> i = crls.iterator(); i.hasNext();) {
t = new ASN1InputStream(new ByteArrayInputStream(i.next().getEncoded()));
v11.add(t.readObject());
}
//0 for CRL
v1.add(new DERTaggedObject(true, 0, new DERSequence(v11)));
}
}
return v1;}
After building OID adding it in SignerInforGeneratorBuilder as a signed attribute and generating the signature and then adding this signature in PDF
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ASN1EncodableVector signedAttr = new ASN1EncodableVector();
String ID_ADBE_REVOCATION = "1.2.840.113583.1.1.8";
//TODO add message digest for sgning - nikhilW
Attribute attr = new Attribute(CMSAttributes.messageDigest, new DERSet(new DEROctetString(IOUtils.toByteArray(hashdata))));
signedAttr.add(attr);
//TODO generate pdf info archival and add it as CMS signed attribute - nikhilW
ASN1EncodableVector pdfInfo = genPdfInfoArchival(signedAttr);
Attribute ar = new Attribute(new ASN1ObjectIdentifier(ID_ADBE_REVOCATION), new DERSet (new DERSequence(pdfInfo)));
signedAttr.add(ar);
List<Certificate> certList = new ArrayList<Certificate>();
certList.addAll(Arrays.asList(certificateChain));
Store certs = new JcaCertStore(certList);
DefaultSignedAttributeTableGenerator sa = new DefaultSignedAttributeTableGenerator(new AttributeTable(signedAttr));
SignerInfoGeneratorBuilder builder = new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider());
builder.setSignedAttributeGenerator(sa);
Please find below google drive link contains sample signed pdf file hello_signed_ts_pdfarchivalinfo.pdf
pdf_sample_signed
Any help would be appreciated.
I have checked for the attribute added in pdf using below java source code. Also there is iText Java utility which will debug pdf object tree iText RUP or download it from my google drive link Download iTextRUP Java Jar run it with java -jar jar-name may it will help debuging pdf objects.
Pdf Archival Info Retrieval Source Code Returns CRL stream object at position [0]
private void getPdfRevoInfoArch(SignerInformation signerInform) {
AttributeTable at = signerInform.getSignedAttributes();
ASN1Encodable arch = at.get(new ASN1ObjectIdentifier("1.2.840.113583.1.1.8")).getAttrValues().getObjectAt(0);
//ASN1Encodable arch1 = at.get(new ASN1ObjectIdentifier("1.2.840.113583.1.1.8")).getAttrValues().getObjectAt(1);
System.out.println("arc:" + arch);
System.out.println("archSize:" + at.get(new ASN1ObjectIdentifier("1.2.840.113583.1.1.8")).getAttrValues().size());
}
I'm trying to make a post request to one of our clients with certificate as part of their security.
I tried testing it in postman, just like the usual attached the certificate on postman settings and then able to make a post request to their api.
Now my problem is i'm encountering this error when i'm doing the request on our platform built in java
java.base/sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:664)
java.base/sun.security.util.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:222)
java.base/java.security.KeyStore.load(KeyStore.java:1479)
On the test environment they don't require the password hence null.
try (InputStream inputStream = new ByteArrayInputStream(p12Cert))
{
KeyStore keyStore = KeyStore.getInstance("jks");
keyStore.load(inputStream, null);
I traced the engineLoad method from javakeystore.
private static final int MAGIC = 0xfeedfeed;
private static final int VERSION_1 = 0x01;
private static final int VERSION_2 = 0x02;
if (xMagic!=MAGIC ||
(xVersion!=VERSION_1 && xVersion!=VERSION_2)) {
throw new IOException("Invalid keystore format");
}
Can someone elaborate the above?
Able to fix the problem above, first is the p12 cert i am trying to encode in base64 is in utf-8 encoding which is wrong and should be converted from HEXADECIMAL to base64.
I'm looking to write something that can enumerate and use (to sign) certificates in CurrentUser/My and LocalMachine/My, but I haven't been able to find anything for the Windows cert store, only Java's own secret store. This link looks promising, but I can only use what ships with Java.
I found this question asked on SO before, but it's from five years ago, which is a long time in computer years. Thanks!
Start Java with -Djavax.net.ssl.trustStoreType=WINDOWS-ROOT.
See https://www.oracle.com/technical-resources/articles/javase/security.html for more information.
The cross-platform nature of the Java has its own downsides -- you cannot access some (or many) OS-specific things without external libraries. Windows certificate store is accessible only via CryptoAPI native functions which are not support by Java default installation.
You may take a look at this thread: Calling Win32 API method from Java
If you can use JNA, then you can use various Certificate and Certificate Store Functions in crypt32.dll to enumerate certificates and perform signing operations.
KeyStore keyStore = KeyStore.getInstance(getKeyStoreType(), "SunMSCAPI");
keyStore.load(null, null);
try {
Field field = keyStore.getClass().getDeclaredField("keyStoreSpi");
field.setAccessible(true);
KeyStoreSpi keyStoreVeritable = (KeyStoreSpi)field.get(keyStore);
field = keyStoreVeritable.getClass().getEnclosingClass().getDeclaredField("entries");
field.setAccessible(true);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Set accessible keyStoreSpi problem", e);
}
Enumeration enumeration = keyStore.aliases();
I picked from where Crypt32 left, used JNA to access the certificates using the same windows dialog that pops up if you were to use any windows specific program:
NativeLibrary cryptUI = NativeLibrary.getInstance("Cryptui");
NativeLibrary crypt32 = NativeLibrary.getInstance("Crypt32");
Function functionCertOpenSystemStore = crypt32.getFunction("CertOpenSystemStoreA");
Object[] argsCertOpenSystemStore = new Object[] { 0, "CA"};
HANDLE h = (HANDLE) functionCertOpenSystemStore.invoke(HANDLE.class, argsCertOpenSystemStore);
Function functionCryptUIDlgSelectCertificateFromStore = cryptUI.getFunction("CryptUIDlgSelectCertificateFromStore");
System.out.println(functionCryptUIDlgSelectCertificateFromStore.getName());
Object[] argsCryptUIDlgSelectCertificateFromStore = new Object[] { h, 0, 0, 0, 16, 0, 0};
Pointer ptrCertContext = (Pointer) functionCryptUIDlgSelectCertificateFromStore.invoke(Pointer.class, argsCryptUIDlgSelectCertificateFromStore);
Function functionCertGetNameString = crypt32.getFunction("CertGetNameStringW");
char[] ptrName = new char[128];
Object[] argsCertGetNameString = new Object[] { ptrCertContext, 5, 0, 0, ptrName, 128};
functionCertGetNameString.invoke(argsCertGetNameString);
System.out.println("Selected certificate is " + new String(ptrName));
Function functionCertFreeCertificateContext = crypt32.getFunction("CertFreeCertificateContext");
Object[] argsCertFreeCertificateContext = new Object[] { ptrCertContext};
functionCertFreeCertificateContext.invoke(argsCertFreeCertificateContext);
Function functionCertCloseStore = crypt32.getFunction("CertCloseStore");
Object[] argsCertCloseStore = new Object[] { h, 0};
functionCertCloseStore.invoke(argsCertCloseStore);
It is just a piece of code that works; feel free to apply your coding practices.
I need to write an applet that reads info from smartcards, I based my script on the code example provided by #Jovo Krneta here.
My concern is about this specific piece of code:
keyStore.load(null, null); // opens the windows security window
Enumeration<String> enums = keyStore.aliases(); // looks for local certificates
while (enums.hasMoreElements()) {
this.jComboBox1.addItem((String) enums.nextElement());
}
I'm finding it hard to find a way to validate if the user clicked on Cancel once the window is opened.
My question is if exists something like
keyStore.load(null, null);
if(keyStore.canceled()){
// do nothing
}else{
Enumeration<String> enums = keyStore.aliases(); // looks for local certificates
while (enums.hasMoreElements()) {
this.jComboBox1.addItem((String) enums.nextElement());
}
}
According to several posts I've found out it's now possible to perform CAdES using BouncyCastle but there is hardly any documentation on the topic.
For starters I want to perform CAdES-BES without any optional signed attributes on a file with a file based certificate.
In response to dander:
I have something that might be helpful, you have your SignerInformation, you need to extend it, first you need to create an attribute from the timestamp, I'll assume you already have a TimeStampResponse as tspResp
TimeStampToken token = tsresp.getTimeStampToken();
Attribute timeStamp = new Attribute(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken, new DERSet(ASN1Object.fromByteArray(token.getEncoded())));
Then you need to extend your SignerInformation
AttributeTable unsigned = signerInformation.getUnsignedAttributes();
Hashtable<ASN1ObjectIdentifier, Attribute> unsignedAttrHash = null;
if (unsigned == null) {
unsignedAttrHash = new Hashtable<ASN1ObjectIdentifier, Attribute>();
} else {
unsignedAttrHash = signerInformation.getUnsignedAttributes().toHashtable();
}
unsignedAttrHash.put(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken, signatureTimeStamp);
SignerInformation newsi = SignerInformation.replaceUnsignedAttributes(si, new AttributeTable(
unsignedAttrHash));
I think that's about it.
Here is how I got the signin-certificate attribute
Attribute signingCertificateAttribute;
MessageDigest dig = MessageDigest.getInstance(DigestAlgorithm().getName(),
new BouncyCastleProvider());
byte[] certHash = dig.digest(SigningCertificate().getEncoded());
if (DigestAlgorithm() == DigestAlgorithm.SHA1) {
SigningCertificate sc = new SigningCertificate(new ESSCertID(certHash));
signingCertificateAttribute = new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificate, new DERSet(sc));
} else {
ESSCertIDv2 essCert = new ESSCertIDv2(new AlgorithmIdentifier(DigestAlgorithm().getOid()), certHash);
SigningCertificateV2 scv2 = new SigningCertificateV2(new ESSCertIDv2[] { essCert });
signingCertificateAttribute = new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new DERSet(scv2));
}
Hope it helps
CAdES is an extension of CMS (aka PKCS7), which is possible to do with BouncyCastle. RFC5126 contains everything needed for a CAdES signature, also, I recommend lookup info on ASN.1 since most of the parts are described in that format.
I am currently in hunt for the same answer you are looking for and found that the book Beginning Cryptography with Java by David Hook gives a lot of detailed information you might need.
Useful code could be found on "https://joinup.ec.europa.eu/"
Take a look on CAdESProfileBES.java.
Someone put the same code on Fork of the original SD - Digital Signature Service.