aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart de Water <bartdewater@gmail.com>2019-10-26 13:34:04 -0400
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2019-10-29 22:14:01 +1300
commitfeb6d2c5278bdd66cf0cfdbf828c6ef8effa3d70 (patch)
tree9fef8398774de584de517812ed9e23bc964c8b14
parent308fb199811d085c771e421eb304b4aedf501262 (diff)
downloadruby-openssl-feb6d2c5278bdd66cf0cfdbf828c6ef8effa3d70.tar.gz
Add Marshal support to X509 objects
This allows for example to use Rails' cache to store these objects. Without this patch you'd get errors like "TypeError (no _dump_data is defined for class OpenSSL::X509::Certificate)" Note that the X509::Revoked class doesn't need the newly introduced modules as the DER output of X509::CRL already includes these.
-rw-r--r--lib/openssl/x509.rb26
-rw-r--r--test/test_x509attr.rb10
-rw-r--r--test/test_x509cert.rb11
-rw-r--r--test/test_x509crl.rb16
-rw-r--r--test/test_x509ext.rb8
-rw-r--r--test/test_x509name.rb7
-rw-r--r--test/test_x509req.rb7
7 files changed, 85 insertions, 0 deletions
diff --git a/lib/openssl/x509.rb b/lib/openssl/x509.rb
index 4f3a4337..426f99d2 100644
--- a/lib/openssl/x509.rb
+++ b/lib/openssl/x509.rb
@@ -14,6 +14,22 @@
module OpenSSL
module X509
+ module Marshal
+ def self.included(base)
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods
+ def _load(string)
+ new(string)
+ end
+ end
+
+ def _dump(_level)
+ to_der
+ end
+ end
+
class ExtensionFactory
def create_extension(*arg)
if arg.size > 1
@@ -41,6 +57,8 @@ module OpenSSL
end
class Extension
+ include Marshal
+
def ==(other)
return false unless Extension === other
to_der == other.to_der
@@ -116,6 +134,8 @@ module OpenSSL
end
class Name
+ include Marshal
+
module RFC2253DN
Special = ',=+<>#;'
HexChar = /[0-9a-fA-F]/
@@ -219,6 +239,8 @@ module OpenSSL
end
class Attribute
+ include Marshal
+
def ==(other)
return false unless Attribute === other
to_der == other.to_der
@@ -232,6 +254,7 @@ module OpenSSL
end
class Certificate
+ include Marshal
include Extension::SubjectKeyIdentifier
include Extension::AuthorityKeyIdentifier
@@ -248,6 +271,7 @@ module OpenSSL
end
class CRL
+ include Marshal
include Extension::AuthorityKeyIdentifier
def ==(other)
@@ -264,6 +288,8 @@ module OpenSSL
end
class Request
+ include Marshal
+
def ==(other)
return false unless Request === other
to_der == other.to_der
diff --git a/test/test_x509attr.rb b/test/test_x509attr.rb
index c6c48e86..6864eec7 100644
--- a/test/test_x509attr.rb
+++ b/test/test_x509attr.rb
@@ -79,6 +79,16 @@ class OpenSSL::TestX509Attribute < OpenSSL::TestCase
assert_equal true, attr1 == attr2
assert_equal false, attr1 == attr3
end
+
+ def test_marshal
+ val = OpenSSL::ASN1::Set([
+ OpenSSL::ASN1::UTF8String("abc123")
+ ])
+ attr = OpenSSL::X509::Attribute.new("challengePassword", val)
+ deserialized = Marshal.load(Marshal.dump(attr))
+
+ assert_equal attr.to_der, deserialized.to_der
+ end
end
end
diff --git a/test/test_x509cert.rb b/test/test_x509cert.rb
index a490ccfc..2df28636 100644
--- a/test/test_x509cert.rb
+++ b/test/test_x509cert.rb
@@ -196,6 +196,17 @@ class OpenSSL::TestX509Certificate < OpenSSL::TestCase
assert_equal false, cert3 == cert4
end
+ def test_marshal
+ now = Time.now
+ cacert = issue_cert(@ca, @rsa1024, 1, [], nil, nil,
+ not_before: now, not_after: now + 3600)
+ cert = issue_cert(@ee1, @rsa2048, 2, [], cacert, @rsa1024,
+ not_before: now, not_after: now + 3600)
+ deserialized = Marshal.load(Marshal.dump(cert))
+
+ assert_equal cert.to_der, deserialized.to_der
+ end
+
private
def certificate_error_returns_false
diff --git a/test/test_x509crl.rb b/test/test_x509crl.rb
index 580052c6..9006481d 100644
--- a/test/test_x509crl.rb
+++ b/test/test_x509crl.rb
@@ -256,6 +256,22 @@ class OpenSSL::TestX509CRL < OpenSSL::TestCase
assert_equal true, rev2 == crl2.revoked[1]
end
+ def test_marshal
+ now = Time.now
+
+ cacert = issue_cert(@ca, @rsa1024, 1, [], nil, nil)
+ crl = issue_crl([], 1, now, now + 3600, [], cacert, @rsa1024, "sha256")
+ rev = OpenSSL::X509::Revoked.new.tap { |rev|
+ rev.serial = 1
+ rev.time = now
+ }
+ crl.add_revoked(rev)
+ deserialized = Marshal.load(Marshal.dump(crl))
+
+ assert_equal crl.to_der, deserialized.to_der
+ assert_equal crl.revoked[0].to_der, deserialized.revoked[0].to_der
+ end
+
private
def crl_error_returns_false
diff --git a/test/test_x509ext.rb b/test/test_x509ext.rb
index 6964af46..6614f7a6 100644
--- a/test/test_x509ext.rb
+++ b/test/test_x509ext.rb
@@ -87,6 +87,14 @@ class OpenSSL::TestX509Extension < OpenSSL::TestCase
assert_equal false, ext1 == ext3
end
+ def test_marshal
+ ef = OpenSSL::X509::ExtensionFactory.new
+ ext = ef.create_extension("basicConstraints", "critical, CA:TRUE, pathlen:2")
+ deserialized = Marshal.load(Marshal.dump(ext))
+
+ assert_equal ext.to_der, deserialized.to_der
+ end
+
def test_value_der
ext = OpenSSL::X509::Extension.new(@basic_constraints.to_der)
assert_equal @basic_constraints_value.to_der, ext.value_der
diff --git a/test/test_x509name.rb b/test/test_x509name.rb
index 738397d4..2bbe29ce 100644
--- a/test/test_x509name.rb
+++ b/test/test_x509name.rb
@@ -453,6 +453,13 @@ class OpenSSL::TestX509Name < OpenSSL::TestCase
assert_equal false, name0.eql?(name2)
end
+ def test_marshal
+ name = OpenSSL::X509::Name.new([["DC", "org"], ["DC", "ruby-lang"], ["CN", "bar.ruby-lang.org"]])
+ deserialized = Marshal.load(Marshal.dump(name))
+
+ assert_equal name.to_der, deserialized.to_der
+ end
+
def test_dup
name = OpenSSL::X509::Name.parse("/CN=ruby-lang.org")
assert_equal(name.to_der, name.dup.to_der)
diff --git a/test/test_x509req.rb b/test/test_x509req.rb
index 2c447ccd..b6022a6e 100644
--- a/test/test_x509req.rb
+++ b/test/test_x509req.rb
@@ -151,6 +151,13 @@ class OpenSSL::TestX509Request < OpenSSL::TestCase
assert_equal false, req1 == req3
end
+ def test_marshal
+ req = issue_csr(0, @dn, @rsa1024, "sha256")
+ deserialized = Marshal.load(Marshal.dump(req))
+
+ assert_equal req.to_der, deserialized.to_der
+ end
+
private
def request_error_returns_false