From cc529c4c0c9d2ad2552ed6894d0dabc8f7ae8651 Mon Sep 17 00:00:00 2001 From: Brice Figureau Date: Sat, 23 May 2009 15:02:19 +0200 Subject: [PATCH 1/7] Allow OpenSSL::X509::CRL to be created with PEM CRL OpenSSL:X509::CRL could be created only with binary DER encoded content, although MRI ruby could be created with PEM content. Signed-off-by: Brice Figureau --- src/java/org/jruby/ext/openssl/X509CRL.java | 20 +++++++- .../ext/openssl/x509store/PEMInputOutput.java | 57 ++++++++++++++++++++ test/openssl/test_x509crl.rb | 16 ++++++ 3 files changed, 92 insertions(+), 1 deletions(-) diff --git a/src/java/org/jruby/ext/openssl/X509CRL.java b/src/java/org/jruby/ext/openssl/X509CRL.java index 7c1e6da..eaaa950 100644 --- a/src/java/org/jruby/ext/openssl/X509CRL.java +++ b/src/java/org/jruby/ext/openssl/X509CRL.java @@ -28,6 +28,7 @@ package org.jruby.ext.openssl; import java.io.ByteArrayInputStream; +import java.io.StringReader; import java.io.StringWriter; import java.math.BigInteger; import java.security.GeneralSecurityException; @@ -48,6 +49,7 @@ import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; +import org.bouncycastle.jce.provider.PEMUtil; import org.bouncycastle.x509.X509V2CRLGenerator; import org.jruby.Ruby; import org.jruby.RubyArray; @@ -59,6 +61,7 @@ import org.jruby.RubyString; import org.jruby.RubyTime; import org.jruby.anno.JRubyMethod; import org.jruby.exceptions.RaiseException; +import org.jruby.ext.openssl.impl.utils.Base64; import org.jruby.ext.openssl.x509store.PEMInputOutput; import org.jruby.runtime.Block; import org.jruby.runtime.ObjectAllocator; @@ -123,7 +126,22 @@ public class X509CRL extends RubyObject { ByteArrayInputStream bis = new ByteArrayInputStream(args[0].convertToString().getBytes()); CertificateFactory cf = CertificateFactory.getInstance("X.509",OpenSSLReal.PROVIDER); crl = (java.security.cert.X509CRL)cf.generateCRL(bis); - crl_v = new ASN1InputStream(new ByteArrayInputStream(args[0].convertToString().getBytes())).readObject(); + + byte[] crl_bytes = args[0].convertToString().getBytes(); + // Parse PEM if we ever get passed some PEM contents + try { + StringReader in = new StringReader(args[0].toString()); + byte[] bytes = PEMInputOutput.readPEMToDER(in); + if (bytes != null) + crl_bytes = bytes; + in.close(); + } + catch(Exception e) { + // this is not PEM encoded, let's use the default argument + } + + crl_v = new ASN1InputStream(new ByteArrayInputStream(crl_bytes)).readObject(); + DEREncodable v0 = ((DERSequence)(((DERSequence)crl_v).getObjectAt(0))).getObjectAt(0); if(v0 instanceof DERInteger) { set_version(getRuntime().newFixnum(((DERInteger)v0).getValue().intValue())); diff --git a/src/java/org/jruby/ext/openssl/x509store/PEMInputOutput.java b/src/java/org/jruby/ext/openssl/x509store/PEMInputOutput.java index c899649..ef3b1bc 100644 --- a/src/java/org/jruby/ext/openssl/x509store/PEMInputOutput.java +++ b/src/java/org/jruby/ext/openssl/x509store/PEMInputOutput.java @@ -210,6 +210,63 @@ public class PEMInputOutput { return null; } + public static byte[] readPEMToDER(Reader in) throws IOException { + BufferedReader _in = makeBuffered(in); + String line; + while ((line = _in.readLine()) != null) { + if(line.indexOf(BEF_G+PEM_STRING_PUBLIC) != -1) { + try { + return readBytes(_in,BEF_E+PEM_STRING_PUBLIC); + } catch (Exception e) { + throw new IOException("problem reading PEM public key: " + e.toString()); + } + } else if(line.indexOf(BEF_G+PEM_STRING_DSA) != -1) { + try { + return readBytes(_in, BEF_E+PEM_STRING_DSA); + } catch (Exception e) { + throw new IOException("problem reading PEM DSA private key: " + e.toString()); + } + } else if(line.indexOf(BEF_G+PEM_STRING_RSA_PUBLIC) != -1) { + try { + return readBytes(_in,BEF_E+PEM_STRING_RSA_PUBLIC); + } catch (Exception e) { + throw new IOException("problem reading PEM RSA public key: " + e.toString()); + } + } else if(line.indexOf(BEF_G+PEM_STRING_X509_OLD) != -1) { + try { + return readBytes(_in,BEF_E+PEM_STRING_X509_OLD); + } catch (Exception e) { + throw new IOException("problem reading PEM X509 Aux certificate: " + e.toString()); + } + } else if(line.indexOf(BEF_G+PEM_STRING_X509) != -1) { + try { + return readBytes(_in,BEF_E+PEM_STRING_X509); + } catch (Exception e) { + throw new IOException("problem reading PEM X509 Aux certificate: " + e.toString()); + } + } else if(line.indexOf(BEF_G+PEM_STRING_X509_TRUSTED) != -1) { + try { + return readBytes(_in,BEF_E+PEM_STRING_X509_TRUSTED); + } catch (Exception e) { + throw new IOException("problem reading PEM X509 Aux certificate: " + e.toString()); + } + } else if(line.indexOf(BEF_G+PEM_STRING_X509_CRL) != -1) { + try { + return readBytes(_in,BEF_E+PEM_STRING_X509_CRL); + } catch (Exception e) { + throw new IOException("problem reading PEM X509 CRL: " + e.toString()); + } + } else if(line.indexOf(BEF_G+PEM_STRING_X509_REQ) != -1) { + try { + return readBytes(_in,BEF_E+PEM_STRING_X509_REQ); + } catch (Exception e) { + throw new IOException("problem reading PEM X509 REQ: " + e.toString()); + } + } + } + return null; + } + public static DSAPublicKey readDSAPubKey(Reader in, char[] f) throws IOException { // System.out.println("WARNING: read_DSA_PUBKEY"); return null; diff --git a/test/openssl/test_x509crl.rb b/test/openssl/test_x509crl.rb index c31a454..12252d7 100644 --- a/test/openssl/test_x509crl.rb +++ b/test/openssl/test_x509crl.rb @@ -213,6 +213,22 @@ class OpenSSL::TestX509CRL < Test::Unit::TestCase crl.version = 0 assert_equal(false, crl.verify(@dsa512)) end + + def test_create_from_pem + crl = <