Skip to content

Commit

Permalink
Merge pull request #161 from rhenium/ky/x509-implement-eq
Browse files Browse the repository at this point in the history
x509*: implement ==
  • Loading branch information
rhenium authored Oct 22, 2017
2 parents 897ee5e + 5c4af48 commit d834e86
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 0 deletions.
21 changes: 21 additions & 0 deletions ext/openssl/ossl_x509cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,26 @@ ossl_x509_inspect(VALUE self)
ossl_x509_get_not_after(self));
}

/*
* call-seq:
* cert1 == cert2 -> true | false
*
* Compares the two certificates. Note that this takes into account all fields,
* not just the issuer name and the serial number.
*/
static VALUE
ossl_x509_eq(VALUE self, VALUE other)
{
X509 *a, *b;

GetX509(self, a);
if (!rb_obj_is_kind_of(other, cX509Cert))
return Qfalse;
GetX509(other, b);

return !X509_cmp(a, b) ? Qtrue : Qfalse;
}

/*
* INIT
*/
Expand Down Expand Up @@ -821,4 +841,5 @@ Init_ossl_x509cert(void)
rb_define_method(cX509Cert, "extensions=", ossl_x509_set_extensions, 1);
rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1);
rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0);
rb_define_method(cX509Cert, "==", ossl_x509_eq, 1);
}
21 changes: 21 additions & 0 deletions ext/openssl/ossl_x509revoked.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,26 @@ ossl_x509revoked_add_extension(VALUE self, VALUE ext)
return ext;
}

static VALUE
ossl_x509revoked_to_der(VALUE self)
{
X509_REVOKED *rev;
VALUE str;
int len;
unsigned char *p;

GetX509Rev(self, rev);
len = i2d_X509_REVOKED(rev, NULL);
if (len <= 0)
ossl_raise(eX509RevError, "i2d_X509_REVOKED");
str = rb_str_new(NULL, len);
p = (unsigned char *)RSTRING_PTR(str);
if (i2d_X509_REVOKED(rev, &p) <= 0)
ossl_raise(eX509RevError, "i2d_X509_REVOKED");
ossl_str_adjust(str, p);
return str;
}

/*
* INIT
*/
Expand Down Expand Up @@ -276,4 +296,5 @@ Init_ossl_x509revoked(void)
rb_define_method(cX509Rev, "extensions", ossl_x509revoked_get_extensions, 0);
rb_define_method(cX509Rev, "extensions=", ossl_x509revoked_set_extensions, 1);
rb_define_method(cX509Rev, "add_extension", ossl_x509revoked_add_extension, 1);
rb_define_method(cX509Rev, "to_der", ossl_x509revoked_to_der, 0);
}
33 changes: 33 additions & 0 deletions lib/openssl/x509.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ def create_ext_from_hash(hash)
end

class Extension
def ==(other)
return false unless Extension === other
to_der == other.to_der
end

def to_s # "oid = critical, value"
str = self.oid
str << " = "
Expand Down Expand Up @@ -160,6 +165,13 @@ def pretty_print(q)
end
end

class Attribute
def ==(other)
return false unless Attribute === other
to_der == other.to_der
end
end

class StoreContext
def cleanup
warn "(#{caller.first}) OpenSSL::X509::StoreContext#cleanup is deprecated with no replacement" if $VERBOSE
Expand All @@ -178,5 +190,26 @@ def pretty_print(q)
}
end
end

class CRL
def ==(other)
return false unless CRL === other
to_der == other.to_der
end
end

class Revoked
def ==(other)
return false unless Revoked === other
to_der == other.to_der
end
end

class Request
def ==(other)
return false unless Request === other
to_der == other.to_der
end
end
end
end
17 changes: 17 additions & 0 deletions test/test_x509attr.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,23 @@ def test_dup
attr = OpenSSL::X509::Attribute.new("challengePassword", val)
assert_equal(attr.to_der, attr.dup.to_der)
end

def test_eq
val1 = OpenSSL::ASN1::Set([
OpenSSL::ASN1::UTF8String("abc123")
])
attr1 = OpenSSL::X509::Attribute.new("challengePassword", val1)
attr2 = OpenSSL::X509::Attribute.new("challengePassword", val1)
ef = OpenSSL::X509::ExtensionFactory.new
val2 = OpenSSL::ASN1::Set.new([OpenSSL::ASN1::Sequence.new([
ef.create_extension("keyUsage", "keyCertSign", true)
])])
attr3 = OpenSSL::X509::Attribute.new("extReq", val2)

assert_equal false, attr1 == 12345
assert_equal true, attr1 == attr2
assert_equal false, attr1 == attr3
end
end

end
14 changes: 14 additions & 0 deletions test/test_x509cert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,20 @@ def test_read_from_file
}
end

def test_eq
cacert = issue_cert(@ca, @rsa1024, 1, [], nil, nil)
cert1 = issue_cert(@ee1, @rsa2048, 2, [], cacert, @rsa1024)
cert2 = issue_cert(@ee1, @rsa2048, 2, [], cacert, @rsa1024)
cert3 = issue_cert(@ee1, @rsa2048, 3, [], cacert, @rsa1024)
cert4 = issue_cert(@ee1, @rsa2048, 2, [], cacert, @rsa1024, digest: "sha512")

assert_equal false, cert1 == 12345
assert_equal true, cert1 == cert2
assert_equal false, cert1 == cert3
assert_equal false, cert1 == cert4
assert_equal false, cert3 == cert4
end

private

def certificate_error_returns_false
Expand Down
50 changes: 50 additions & 0 deletions test/test_x509crl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,56 @@ def test_sign_and_verify
assert_equal(false, crl.verify(@dsa512))
end

def test_revoked_to_der
# revokedCertificates SEQUENCE OF SEQUENCE {
# userCertificate CertificateSerialNumber,
# revocationDate Time,
# crlEntryExtensions Extensions OPTIONAL
# -- if present, version MUST be v2
# } OPTIONAL,

now = Time.utc(2000, 1, 1)
rev1 = OpenSSL::X509::Revoked.new
rev1.serial = 123
rev1.time = now
ext = OpenSSL::X509::Extension.new("CRLReason", OpenSSL::ASN1::Enumerated(1))
rev1.extensions = [ext]
asn1 = OpenSSL::ASN1::Sequence([
OpenSSL::ASN1::Integer(123),
OpenSSL::ASN1::UTCTime(now),
OpenSSL::ASN1::Sequence([ext.to_der])
])

assert_equal asn1.to_der, rev1.to_der
end

def test_eq
cacert = issue_cert(@ca, @rsa1024, 1, [], nil, nil)
crl1 = issue_crl([], 1, Time.now, Time.now + 3600, [], cacert, @rsa1024, "sha256")
rev1 = OpenSSL::X509::Revoked.new.tap { |rev|
rev.serial = 1
rev.time = Time.now
}
crl1.add_revoked(rev1)
crl2 = OpenSSL::X509::CRL.new(crl1.to_der)

# CRL
assert_equal false, crl1 == 12345
assert_equal true, crl1 == crl2
rev2 = OpenSSL::X509::Revoked.new.tap { |rev|
rev.serial = 2
rev.time = Time.now
}
crl2.add_revoked(rev2)
assert_equal false, crl1 == crl2

# Revoked
assert_equal false, rev1 == 12345
assert_equal true, rev1 == crl2.revoked[0]
assert_equal false, rev1 == crl2.revoked[1]
assert_equal true, rev2 == crl2.revoked[1]
end

private

def crl_error_returns_false
Expand Down
11 changes: 11 additions & 0 deletions test/test_x509ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ def test_dup
assert_equal(@basic_constraints.to_der, ext.to_der)
assert_equal(ext.to_der, ext.dup.to_der)
end

def test_eq
ext1 = OpenSSL::X509::Extension.new(@basic_constraints.to_der)
ef = OpenSSL::X509::ExtensionFactory.new
ext2 = ef.create_extension("basicConstraints", "critical, CA:TRUE, pathlen:2")
ext3 = ef.create_extension("basicConstraints", "critical, CA:TRUE")

assert_equal false, ext1 == 12345
assert_equal true, ext1 == ext2
assert_equal false, ext1 == ext3
end
end

end
10 changes: 10 additions & 0 deletions test/test_x509req.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,16 @@ def test_dup
assert_equal(req.to_der, req.dup.to_der)
end

def test_eq
req1 = issue_csr(0, @dn, @rsa1024, "sha1")
req2 = issue_csr(0, @dn, @rsa1024, "sha1")
req3 = issue_csr(0, @dn, @rsa1024, "sha256")

assert_equal false, req1 == 12345
assert_equal true, req1 == req2
assert_equal false, req1 == req3
end

private

def request_error_returns_false
Expand Down

0 comments on commit d834e86

Please sign in to comment.