From 6c1013df582c08e4e6ab8eb83776db8f624c69ea Mon Sep 17 00:00:00 2001 From: HoneyryderChuck Date: Tue, 12 Nov 2024 15:58:46 +0000 Subject: [PATCH] make cert/crl/ext/extfactory shareable when frozen --- ext/openssl/ossl_x509attr.c | 8 ++++++-- ext/openssl/ossl_x509cert.c | 13 +++++++++++- ext/openssl/ossl_x509crl.c | 10 ++++++++- ext/openssl/ossl_x509ext.c | 37 ++++++++++++++++++++++++++++++++-- ext/openssl/ossl_x509name.c | 4 +++- ext/openssl/ossl_x509revoked.c | 36 ++++++++++++++++++++++++++++++--- test/openssl/test_x509cert.rb | 6 ++++++ 7 files changed, 104 insertions(+), 10 deletions(-) diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index 967fe89f0..e9d8562b7 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -105,6 +105,7 @@ ossl_x509attr_initialize(int argc, VALUE *argv, VALUE self) X509_ATTRIBUTE *attr, *x; const unsigned char *p; + rb_check_frozen(self); GetX509Attr(self, attr); if(rb_scan_args(argc, argv, "11", &oid, &value) == 1){ oid = ossl_to_der_if_possible(oid); @@ -128,7 +129,6 @@ ossl_x509attr_initialize_copy(VALUE self, VALUE other) { X509_ATTRIBUTE *attr, *attr_other, *attr_new; - rb_check_frozen(self); GetX509Attr(self, attr); GetX509Attr(other, attr_other); @@ -153,6 +153,7 @@ ossl_x509attr_set_oid(VALUE self, VALUE oid) ASN1_OBJECT *obj; char *s; + rb_check_frozen(self); GetX509Attr(self, attr); s = StringValueCStr(oid); obj = OBJ_txt2obj(s, 0); @@ -201,9 +202,12 @@ static VALUE ossl_x509attr_set_value(VALUE self, VALUE value) { X509_ATTRIBUTE *attr; - GetX509Attr(self, attr); + + rb_check_frozen(self); OSSL_Check_Kind(value, cASN1Data); + GetX509Attr(self, attr); + VALUE der = ossl_to_der(value); const unsigned char *p = (const unsigned char *)RSTRING_PTR(der); STACK_OF(ASN1_TYPE) *sk = d2i_ASN1_SET_ANY(NULL, &p, RSTRING_LEN(der)); diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c index 846dd0701..f4daf1845 100644 --- a/ext/openssl/ossl_x509cert.c +++ b/ext/openssl/ossl_x509cert.c @@ -41,7 +41,7 @@ static const rb_data_type_t ossl_x509_type = { { 0, ossl_x509_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE, }; /* @@ -279,6 +279,7 @@ ossl_x509_set_version(VALUE self, VALUE version) X509 *x509; long ver; + rb_check_frozen(self); if ((ver = NUM2LONG(version)) < 0) { ossl_raise(eX509CertError, "version must be >= 0!"); } @@ -313,6 +314,7 @@ ossl_x509_set_serial(VALUE self, VALUE num) { X509 *x509; + rb_check_frozen(self); GetX509(self, x509); X509_set_serialNumber(x509, num_to_asn1integer(num, X509_get_serialNumber(x509))); @@ -370,6 +372,7 @@ ossl_x509_set_subject(VALUE self, VALUE subject) { X509 *x509; + rb_check_frozen(self); GetX509(self, x509); if (!X509_set_subject_name(x509, GetX509NamePtr(subject))) { /* DUPs name */ ossl_raise(eX509CertError, NULL); @@ -405,6 +408,7 @@ ossl_x509_set_issuer(VALUE self, VALUE issuer) { X509 *x509; + rb_check_frozen(self); GetX509(self, x509); if (!X509_set_issuer_name(x509, GetX509NamePtr(issuer))) { /* DUPs name */ ossl_raise(eX509CertError, NULL); @@ -441,6 +445,7 @@ ossl_x509_set_not_before(VALUE self, VALUE time) X509 *x509; ASN1_TIME *asn1time; + rb_check_frozen(self); GetX509(self, x509); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_set1_notBefore(x509, asn1time)) { @@ -480,6 +485,7 @@ ossl_x509_set_not_after(VALUE self, VALUE time) X509 *x509; ASN1_TIME *asn1time; + rb_check_frozen(self); GetX509(self, x509); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_set1_notAfter(x509, asn1time)) { @@ -519,6 +525,7 @@ ossl_x509_set_public_key(VALUE self, VALUE key) X509 *x509; EVP_PKEY *pkey; + rb_check_frozen(self); GetX509(self, x509); pkey = GetPKeyPtr(key); ossl_pkey_check_public_key(pkey); @@ -538,6 +545,7 @@ ossl_x509_sign(VALUE self, VALUE key, VALUE digest) EVP_PKEY *pkey; const EVP_MD *md; + rb_check_frozen(self); pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */ if (NIL_P(digest)) { md = NULL; /* needed for some key types, e.g. Ed25519 */ @@ -641,6 +649,7 @@ ossl_x509_set_extensions(VALUE self, VALUE ary) long i; Check_Type(ary, T_ARRAY); + rb_check_frozen(self); /* All ary's members should be X509Extension */ for (i=0; i= 0!"); } @@ -199,6 +200,7 @@ ossl_x509crl_set_issuer(VALUE self, VALUE issuer) { X509_CRL *crl; + rb_check_frozen(self); GetX509CRL(self, crl); if (!X509_CRL_set_issuer_name(crl, GetX509NamePtr(issuer))) { /* DUPs name */ @@ -227,6 +229,7 @@ ossl_x509crl_set_last_update(VALUE self, VALUE time) X509_CRL *crl; ASN1_TIME *asn1time; + rb_check_frozen(self); GetX509CRL(self, crl); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_CRL_set1_lastUpdate(crl, asn1time)) { @@ -302,6 +305,7 @@ ossl_x509crl_set_revoked(VALUE self, VALUE ary) STACK_OF(X509_REVOKED) *sk; long i; + rb_check_frozen(self); Check_Type(ary, T_ARRAY); /* All ary members should be X509 Revoked */ for (i=0; i string + */ static VALUE ossl_x509ext_set_oid(VALUE self, VALUE oid) { X509_EXTENSION *ext; ASN1_OBJECT *obj; + rb_check_frozen(self); GetX509Ext(self, ext); obj = OBJ_txt2obj(StringValueCStr(oid), 0); if (!obj) @@ -337,12 +344,17 @@ ossl_x509ext_set_oid(VALUE self, VALUE oid) return oid; } +/* + * call-seq: + * extension.value = string => string + */ static VALUE ossl_x509ext_set_value(VALUE self, VALUE data) { X509_EXTENSION *ext; ASN1_OCTET_STRING *asn1s; + rb_check_frozen(self); GetX509Ext(self, ext); data = ossl_to_der_if_possible(data); StringValue(data); @@ -356,17 +368,26 @@ ossl_x509ext_set_value(VALUE self, VALUE data) return data; } +/* + * call-seq: + * extension.critical = bool => bool + */ static VALUE ossl_x509ext_set_critical(VALUE self, VALUE flag) { X509_EXTENSION *ext; + rb_check_frozen(self); GetX509Ext(self, ext); X509_EXTENSION_set_critical(ext, RTEST(flag) ? 1 : 0); return flag; } +/* + * call-seq: + * extension.oid => string + */ static VALUE ossl_x509ext_get_oid(VALUE obj) { @@ -390,6 +411,10 @@ ossl_x509ext_get_oid(VALUE obj) return ret; } +/* + * call-seq: + * extension.value => string + */ static VALUE ossl_x509ext_get_value(VALUE obj) { @@ -420,6 +445,10 @@ ossl_x509ext_get_value_der(VALUE obj) return rb_str_new((const char *)value->data, value->length); } +/* + * call-seq: + * extension.critical = bool + */ static VALUE ossl_x509ext_get_critical(VALUE obj) { @@ -429,6 +458,10 @@ ossl_x509ext_get_critical(VALUE obj) return X509_EXTENSION_get_critical(ext) ? Qtrue : Qfalse; } +/* + * call-seq: + * extension.to_der => string + */ static VALUE ossl_x509ext_to_der(VALUE obj) { diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index 5060be92c..6a962b6c4 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -46,7 +46,7 @@ static const rb_data_type_t ossl_x509name_type = { { 0, ossl_x509name_free, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED }; /* @@ -148,6 +148,7 @@ ossl_x509name_initialize(int argc, VALUE *argv, VALUE self) X509_NAME *name; VALUE arg, template; + rb_check_frozen(self); GetX509Name(self, name); if (rb_scan_args(argc, argv, "02", &arg, &template) == 0) { return self; @@ -229,6 +230,7 @@ VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self) kwargs_ids[1] = rb_intern_const("set"); } rb_scan_args(argc, argv, "21:", &oid, &value, &type, &opts); + rb_check_frozen(self); rb_get_kwargs(opts, kwargs_ids, 0, 2, kwargs); oid_name = StringValueCStr(oid); StringValue(value); diff --git a/ext/openssl/ossl_x509revoked.c b/ext/openssl/ossl_x509revoked.c index 5b82470c8..bf0e86d5d 100644 --- a/ext/openssl/ossl_x509revoked.c +++ b/ext/openssl/ossl_x509revoked.c @@ -110,7 +110,6 @@ ossl_x509revoked_initialize_copy(VALUE self, VALUE other) { X509_REVOKED *rev, *rev_other, *rev_new; - rb_check_frozen(self); GetX509Rev(self, rev); GetX509Rev(other, rev_other); @@ -124,6 +123,10 @@ ossl_x509revoked_initialize_copy(VALUE self, VALUE other) return self; } +/* + * call-seq: + * revoked.serial => integer + */ static VALUE ossl_x509revoked_get_serial(VALUE self) { @@ -134,12 +137,17 @@ ossl_x509revoked_get_serial(VALUE self) return asn1integer_to_num(X509_REVOKED_get0_serialNumber(rev)); } +/* + * call-seq: + * revoked.serial = integer => integer + */ static VALUE ossl_x509revoked_set_serial(VALUE self, VALUE num) { X509_REVOKED *rev; ASN1_INTEGER *asn1int; + rb_check_frozen(self); GetX509Rev(self, rev); asn1int = num_to_asn1integer(num, NULL); if (!X509_REVOKED_set_serialNumber(rev, asn1int)) { @@ -151,6 +159,10 @@ ossl_x509revoked_set_serial(VALUE self, VALUE num) return num; } +/* + * call-seq: + * revoked.time => time + */ static VALUE ossl_x509revoked_get_time(VALUE self) { @@ -165,12 +177,17 @@ ossl_x509revoked_get_time(VALUE self) return asn1time_to_time(time); } +/* + * call-seq: + * revoked.time = time => time + */ static VALUE ossl_x509revoked_set_time(VALUE self, VALUE time) { X509_REVOKED *rev; ASN1_TIME *asn1time; + rb_check_frozen(self); GetX509Rev(self, rev); asn1time = ossl_x509_time_adjust(NULL, time); if (!X509_REVOKED_set_revocationDate(rev, asn1time)) { @@ -181,8 +198,10 @@ ossl_x509revoked_set_time(VALUE self, VALUE time) return time; } + /* - * Gets X509v3 extensions as array of X509Ext objects + * call-seq: + * revoked.extension = [extension, ...] */ static VALUE ossl_x509revoked_get_extensions(VALUE self) @@ -208,7 +227,8 @@ ossl_x509revoked_get_extensions(VALUE self) } /* - * Sets X509_EXTENSIONs + * call-seq: + * revoked.extensions = [extension, ...] => [extension, ...] */ static VALUE ossl_x509revoked_set_extensions(VALUE self, VALUE ary) @@ -219,6 +239,7 @@ ossl_x509revoked_set_extensions(VALUE self, VALUE ary) VALUE item; Check_Type(ary, T_ARRAY); + rb_check_frozen(self); for (i=0; i extension + */ static VALUE ossl_x509revoked_add_extension(VALUE self, VALUE ext) { X509_REVOKED *rev; + rb_check_frozen(self); GetX509Rev(self, rev); if (!X509_REVOKED_add_ext(rev, GetX509ExtPtr(ext), -1)) { ossl_raise(eX509RevError, NULL); @@ -249,6 +275,10 @@ ossl_x509revoked_add_extension(VALUE self, VALUE ext) return ext; } +/* + * call-seq: + * revoked.to_der => string + */ static VALUE ossl_x509revoked_to_der(VALUE self) { diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb index 6c16218f3..9c37a0c63 100644 --- a/test/openssl/test_x509cert.rb +++ b/test/openssl/test_x509cert.rb @@ -410,6 +410,12 @@ def test_tbs_precert_bytes assert_equal 7, seq.value.size end + if respond_to?(:ractor) + ractor + def test_ractor + assert Ractor.shareable?(issue_cert(@ca, @rsa2048, 1, [], nil, nil).freeze) + end + end private def certificate_error_returns_false