Skip to content

Commit ca630ee

Browse files
authored
Merge pull request #753 from segiddins/segiddins/add-x509-certificate-tbs_bytes
Add X509::Certificate#tbs_bytes
2 parents 600b422 + 99128be commit ca630ee

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

ext/openssl/extconf.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ def find_openssl_library
149149
have_func("ENGINE_load_#{name}()", "openssl/engine.h")
150150
}
151151

152+
# missing in libressl < 3.5
153+
have_func("i2d_re_X509_tbs(NULL, NULL)", x509_h)
154+
152155
# added in 1.1.0
153156
if !have_struct_member("SSL", "ctx", "openssl/ssl.h") || is_libressl
154157
$defs.push("-DHAVE_OPAQUE_OPENSSL")

ext/openssl/ossl_x509cert.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,38 @@ ossl_x509_eq(VALUE self, VALUE other)
707707
return !X509_cmp(a, b) ? Qtrue : Qfalse;
708708
}
709709

710+
#ifdef HAVE_I2D_RE_X509_TBS
711+
/*
712+
* call-seq:
713+
* cert.tbs_bytes => string
714+
*
715+
* Returns the DER-encoded bytes of the certificate's to be signed certificate.
716+
* This is mainly useful for validating embedded certificate transparency signatures.
717+
*/
718+
static VALUE
719+
ossl_x509_tbs_bytes(VALUE self)
720+
{
721+
X509 *x509;
722+
int len;
723+
unsigned char *p0;
724+
VALUE str;
725+
726+
GetX509(self, x509);
727+
len = i2d_re_X509_tbs(x509, NULL);
728+
if (len <= 0) {
729+
ossl_raise(eX509CertError, "i2d_re_X509_tbs");
730+
}
731+
str = rb_str_new(NULL, len);
732+
p0 = (unsigned char *)RSTRING_PTR(str);
733+
if (i2d_re_X509_tbs(x509, &p0) <= 0) {
734+
ossl_raise(eX509CertError, "i2d_re_X509_tbs");
735+
}
736+
ossl_str_adjust(str, p0);
737+
738+
return str;
739+
}
740+
#endif
741+
710742
struct load_chained_certificates_arguments {
711743
VALUE certificates;
712744
X509 *certificate;
@@ -999,4 +1031,7 @@ Init_ossl_x509cert(void)
9991031
rb_define_method(cX509Cert, "add_extension", ossl_x509_add_extension, 1);
10001032
rb_define_method(cX509Cert, "inspect", ossl_x509_inspect, 0);
10011033
rb_define_method(cX509Cert, "==", ossl_x509_eq, 1);
1034+
#ifdef HAVE_I2D_RE_X509_TBS
1035+
rb_define_method(cX509Cert, "tbs_bytes", ossl_x509_tbs_bytes, 0);
1036+
#endif
10021037
}

test/openssl/test_x509cert.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,15 @@ def test_load_file_fullchain_garbage
322322
end
323323
end
324324

325+
def test_tbs_precert_bytes
326+
pend "LibreSSL < 3.5 does not have i2d_re_X509_tbs" if libressl? && !libressl?(3, 5, 0)
327+
328+
cert = issue_cert(@ca, @rsa2048, 1, [], nil, nil)
329+
seq = OpenSSL::ASN1.decode(cert.tbs_bytes)
330+
331+
assert_equal 7, seq.value.size
332+
end
333+
325334
private
326335

327336
def certificate_error_returns_false

0 commit comments

Comments
 (0)