XML digital signature (Xades) with JRuby

Good morning,

I am trying to use the Java's Xades signature with JRuby in my Ruby on
Rails application.
But since two days now, i am facing the following errors without
getting any response to solve them.

This is the corresponding java code from this page:
http://java.sun.com/developer/technicalArticles/xml/dig_signature_api/

Load the KeyStore and get the signing key and certificate.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("mykeystore.jks"),
"changeit".toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
    (KeyStore.PrivateKeyEntry) ks.getEntry
        ("mykey", new
KeyStore.PasswordProtection("changeit".toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

My corresponding JRuby code is the following:

require 'java'

include_class 'java.lang.System'
include_class 'java.lang.Object'
include_class('java.lang.String'){|package,name| "J#{name}"}
include_class 'java.io.IOException'
include_class 'java.io.InputStream'
include_class 'java.io.FileOutputStream'
include_class 'java.io.FileInputStream'
include_class 'java.security.KeyStore'
include_class 'java.security.KeyStoreException'

password = JString.new("changeit")
ks = KeyStore.getInstance("JKS")
ks.load(FileInputStream.new("keys/keystoreCps.jks"),
password.toCharArray())

keyEntry = KeyStore.PrivateKeyEntry.new
keyEntry = ks.getEntry("mykey",
KeyStore.PasswordProtection.new(password.toCharArray()))
cert = keyEntry.getCertificate()

#Create the KeyInfo containing the X509Data.
kif = sigFactory.getKeyInfoFactory()
x509Content = ArrayList.new
x509Content.add(cert.getSubjectX500Principal().getName())
x509Content.add(cert)
xd = kif.newX509Data(x509Content)
ki = kif.newKeyInfo(Collections.singletonList(xd))

So i am getting these errors with these 2 lines:
keyEntry = KeyStore.PrivateKeyEntry.new
keyEntry = ks.getEntry("mykey",
KeyStore.PasswordProtection.new(password.toCharArray())):

1) NoMethodError: undefined method `PrivateKeyEntry' for
Java::JavaSecurity::KeyStore:Class
2) undefined method `PasswordProtection' for
Java::JavaSecurity::KeyStore:Class

I have visited this javadoc site, but still don't know how to solve
those problems

Kindly help me solve these errors.
Thanks in advance for your responses

Regards,

Good morning,

I am trying to use the Java's Xades signature with JRuby in my Ruby on
Rails application.
But since two days now, i am facing the following errors without
getting any response to solve them.

This is the corresponding java code from this page:
http://java.sun.com/developer/technicalArticles/xml/dig_signature_api/

Load the KeyStore and get the signing key and certificate.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("mykeystore.jks"),
"changeit".toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
(KeyStore.PrivateKeyEntry) ks.getEntry
("mykey", new
KeyStore.PasswordProtection("changeit".toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

My corresponding JRuby code is the following:

require 'java'

include_class 'java.lang.System'
include_class 'java.lang.Object'
include_class('java.lang.String'){|package,name| "J#{name}"}
include_class 'java.io.IOException'
include_class 'java.io.InputStream'
include_class 'java.io.FileOutputStream'
include_class 'java.io.FileInputStream'
include_class 'java.security.KeyStore'
include_class 'java.security.KeyStoreException'

password = JString.new("changeit")
ks = KeyStore.getInstance("JKS")
ks.load(FileInputStream.new("keys/keystoreCps.jks"),
password.toCharArray())

keyEntry = KeyStore.PrivateKeyEntry.new

I don't really know what I am talking about here, but that line tries
to call method PrivateKeyEntry on class KeyStore. Is PrivateKeyEntry
not in fact a class? Should it be KeyStore::PrivateKeyEntry or
something along those lines?

Colin

I don't really know what I am talking about here, but that line tries
to call method PrivateKeyEntry on class KeyStore. Is PrivateKeyEntry
not in fact a class? Should it be KeyStore::PrivateKeyEntry or
something along those lines?

Colin

HI,
Thanks for your answer.
KeyStore.PrivateKeyEntry is a java static class:
http://docs.oracle.com/javase/1.5.0/docs/api/java/security/KeyStore.PrivateKeyEntry.html

Still getting the same error
gsaly

What? You get exactly the same error if you replace the . with ::

The question is what is the right syntax in jruby for referencing that
class? I don't know the answer to that question, but I think that may
be where the problem lies.

Colin

Thank you fro your help.

I ve used the :: unless of . and it seem to work so i have the
following lines now:

password = JString.new("changeit")
ks = KeyStore.getInstance("JKS")
ks.load(FileInputStream.new("keys/keystoreCps.jks"),
password.toCharArray())
keyEntry = ks.getEntry("mykey",
KeyStore::PasswordProtection.new(password.toCharArray()))
cert = keyEntry.getCertificate

Then i am now getting the following error for the last line:
"NoMethodError: undefined method `getCertificate' for nil:NilClass"

Then i tried
cert = X509Certificate.new
cert = keyEntry.getCertificate
Then i am getting the following error:" TypeError: no public
constructors for Java::JavaSecurityCert::X509Certificate"

Thanks

Thank you fro your help.

I ve used the :: unless of . and it seem to work so i have the
following lines now:

password = JString.new("changeit")
ks = KeyStore.getInstance("JKS")
ks.load(FileInputStream.new("keys/keystoreCps.jks"),
password.toCharArray())
keyEntry = ks.getEntry("mykey",
KeyStore::PasswordProtection.new(password.toCharArray()))
cert = keyEntry.getCertificate

Then i am now getting the following error for the last line:
"NoMethodError: undefined method `getCertificate' for nil:NilClass"

That means that keyEntry is nil, so presumably your getEntry call failed.

Then i tried
cert = X509Certificate.new
cert = keyEntry.getCertificate
Then i am getting the following error:" TypeError: no public
constructors for Java::JavaSecurityCert::X509Certificate"

Well that error is pretty self explanatory. But that line is not
achieving anything anyway as you are immediately overwriting cert with
something else.

Colin

Well that error is pretty self explanatory. But that line is not
achieving anything anyway as you are immediately overwriting cert with
something else.

Colin

The complete code is now:

ks = KeyStore.getInstance("JKS")
charsPass = "changeit".to_java_string.toCharArray
ks.load(FileInputStream.new("keys/truststore.jks"), charsPass)
keyEntry = ks.getEntry("mykey",
KeyStore::PasswordProtection.new(charsPass))
cert = keyEntry.getCertificate

#Create the KeyInfo containing the X509Data.
kif = sigFactory.getKeyInfoFactory
x509Content = ArrayList.new
x509Content.add(cert.getSubjectX500Principal.getName)
x509Content.add(cert)
xd = kif.newX509Data(x509Content)
ki = kif.newKeyInfo(Collections.singletonList(xd))

But i am getting "NoMethodError: undefined method `getCertificate' for
nil:NilClass" error
for this line: cert = keyEntry.getCertificate

Am i missing something?
do you know for which reason my getEntry call failed ? because i am
doing exactly the same...

Thanks