aboutsummaryrefslogtreecommitdiffstats
path: root/ext/openssl
diff options
context:
space:
mode:
authorSamuel Giddins <segiddins@segiddins.me>2024-04-30 13:09:05 -0700
committerKazuki Yamaguchi <k@rhe.jp>2024-06-08 19:40:28 +0900
commit99128bea5dca264e6b2992bdca793eff5e53811f (patch)
treea5d604cf3432bc91e4a006c4c3e1bdb8b12cb4e4 /ext/openssl
parent5a5236838b712553dbdca0c68e253107e768d5ed (diff)
downloadruby-openssl-99128bea5dca264e6b2992bdca793eff5e53811f.tar.gz
Add X509::Certificate#tbs_bytes
Ref https://github.com/ruby/openssl/issues/519 This makes verifying embedded certificate transparency signatures significantly easier, as otherwise the alternative was manipulating the ASN1 sequence, as in https://github.com/segiddins/sigstore-cosign-verify/pull/2/commits/656d992fa816613fd9936f53ce30972c2f2f4957
Diffstat (limited to 'ext/openssl')
-rw-r--r--ext/openssl/extconf.rb3
-rw-r--r--ext/openssl/ossl_x509cert.c35
2 files changed, 38 insertions, 0 deletions
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index dd3732d0..4b0c84eb 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -149,6 +149,9 @@ engines.each { |name|
have_func("ENGINE_load_#{name}()", "openssl/engine.h")
}
+# missing in libressl < 3.5
+have_func("i2d_re_X509_tbs(NULL, NULL)", x509_h)
+
# added in 1.1.0
if !have_struct_member("SSL", "ctx", "openssl/ssl.h") || is_libressl
$defs.push("-DHAVE_OPAQUE_OPENSSL")
diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c
index aa6b9bb7..ab5d0d41 100644
--- a/ext/openssl/ossl_x509cert.c
+++ b/ext/openssl/ossl_x509cert.c
@@ -707,6 +707,38 @@ ossl_x509_eq(VALUE self, VALUE other)
return !X509_cmp(a, b) ? Qtrue : Qfalse;
}
+#ifdef HAVE_I2D_RE_X509_TBS
+/*
+ * call-seq:
+ * cert.tbs_bytes => string
+ *
+ * Returns the DER-encoded bytes of the certificate's to be signed certificate.
+ * This is mainly useful for validating embedded certificate transparency signatures.
+ */
+static VALUE
+ossl_x509_tbs_bytes(VALUE self)
+{
+ X509 *x509;
+ int len;
+ unsigned char *p0;
+ VALUE str;
+
+ GetX509(self, x509);
+ len = i2d_re_X509_tbs(x509, NULL);
+ if (len <= 0) {
+ ossl_raise(eX509CertError, "i2d_re_X509_tbs");
+ }
+ str = rb_str_new(NULL, len);
+ p0 = (unsigned char *)RSTRING_PTR(str);
+ if (i2d_re_X509_tbs(x509, &p0) <= 0) {
+ ossl_raise(eX509CertError, "i2d_re_X509_tbs");
+ }
+ ossl_str_adjust(str, p0);
+
+ return str;
+}
+#endif
+
struct load_chained_certificates_arguments {
VALUE certificates;
X509 *certificate;
@@ -999,4 +1031,7 @@ Init_ossl_x509cert(void)
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);
+#ifdef HAVE_I2D_RE_X509_TBS
+ rb_define_method(cX509Cert, "tbs_bytes", ossl_x509_tbs_bytes, 0);
+#endif
}