From 9cdfa3a4d11d2bbcc4a69c18d2ff9dfe9245b1ea Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Thu, 31 Aug 2023 14:58:14 +0900 Subject: [PATCH 1/3] test/openssl/test_ossl.rb: relax assertion for error messages The test case test_error_data utilizes the error message generated by X509V3_EXT_nconf_nid(). The next commit will use X509V3_EXT_nconf(), which generates a slightly different error message. Let's adapt the check to it. --- test/openssl/test_ossl.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/openssl/test_ossl.rb b/test/openssl/test_ossl.rb index 5759c75b8..979669a00 100644 --- a/test/openssl/test_ossl.rb +++ b/test/openssl/test_ossl.rb @@ -67,8 +67,9 @@ def test_error_data # # The generated message should look like: # "subjectAltName = IP:not.a.valid.ip.address: bad ip address (value=not.a.valid.ip.address)" + # "subjectAltName = IP:not.a.valid.ip.address: error in extension (name=subjectAltName, value=IP:not.a.valid.ip.address)" ef = OpenSSL::X509::ExtensionFactory.new - assert_raise_with_message(OpenSSL::X509::ExtensionError, /\(value=not.a.valid.ip.address\)/) { + assert_raise_with_message(OpenSSL::X509::ExtensionError, /value=(IP:)?not.a.valid.ip.address\)/) { ef.create_ext("subjectAltName", "IP:not.a.valid.ip.address") } end From 91ae46c8d745e11ff1985017fa81143f7be816d8 Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Thu, 31 Aug 2023 14:12:57 +0900 Subject: [PATCH 2/3] x509ext: test OpenSSL::X509::ExtensionFactory#create_ext with ln OpenSSL::X509::ExtensionFactory#create_ext and #create_extensions accepts both sn (short names) and ln (long names) for registered OIDs. This is different from the behavior of the openssl command-line utility which accepts only sn in openssl.cnf keys. Add a test case to check this. --- test/openssl/test_x509ext.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/openssl/test_x509ext.rb b/test/openssl/test_x509ext.rb index 7ad010d1e..c04c06574 100644 --- a/test/openssl/test_x509ext.rb +++ b/test/openssl/test_x509ext.rb @@ -70,6 +70,14 @@ def test_create_by_factory assert_match(%r{http://cps.example.com}, cp.value) end + def test_factory_create_extension_sn_ln + ef = OpenSSL::X509::ExtensionFactory.new + bc_sn = ef.create_extension("basicConstraints", "critical, CA:TRUE, pathlen:2") + bc_ln = ef.create_extension("X509v3 Basic Constraints", "critical, CA:TRUE, pathlen:2") + assert_equal(@basic_constraints.to_der, bc_sn.to_der) + assert_equal(@basic_constraints.to_der, bc_ln.to_der) + end + def test_dup ext = OpenSSL::X509::Extension.new(@basic_constraints.to_der) assert_equal(@basic_constraints.to_der, ext.to_der) From 9f15741331ae12a9dda2dbf91122af22184da7f2 Mon Sep 17 00:00:00 2001 From: Michael Richardson Date: Sat, 26 Aug 2017 20:09:38 -0400 Subject: [PATCH 3/3] x509ext: let X509::ExtensionFactory#create_ext take a dotted OID string instead of looking of NIDs and then using X509V3_EXT_nconf_nid, instead just pass strings to X509V3_EXT_nconf, which has all the logic for processing dealing with generic extensions also process the oid through ln2nid() to retain compatibility. [rhe: tweaked commit message and added a test case] --- ext/openssl/ossl_x509ext.c | 16 +++++++++++----- test/openssl/test_x509ext.rb | 11 +++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/ext/openssl/ossl_x509ext.c b/ext/openssl/ossl_x509ext.c index ac46fcf15..192d09bd3 100644 --- a/ext/openssl/ossl_x509ext.c +++ b/ext/openssl/ossl_x509ext.c @@ -209,15 +209,16 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) int nid; VALUE rconf; CONF *conf; + const char *oid_cstr = NULL; rb_scan_args(argc, argv, "21", &oid, &value, &critical); - StringValueCStr(oid); StringValue(value); if(NIL_P(critical)) critical = Qfalse; - nid = OBJ_ln2nid(RSTRING_PTR(oid)); - if(!nid) nid = OBJ_sn2nid(RSTRING_PTR(oid)); - if(!nid) ossl_raise(eX509ExtError, "unknown OID `%"PRIsVALUE"'", oid); + oid_cstr = StringValueCStr(oid); + nid = OBJ_ln2nid(oid_cstr); + if (nid != NID_undef) + oid_cstr = OBJ_nid2sn(nid); valstr = rb_str_new2(RTEST(critical) ? "critical," : ""); rb_str_append(valstr, value); @@ -228,7 +229,12 @@ ossl_x509extfactory_create_ext(int argc, VALUE *argv, VALUE self) rconf = rb_iv_get(self, "@config"); conf = NIL_P(rconf) ? NULL : GetConfig(rconf); X509V3_set_nconf(ctx, conf); - ext = X509V3_EXT_nconf_nid(conf, ctx, nid, RSTRING_PTR(valstr)); + +#if OSSL_OPENSSL_PREREQ(1, 1, 0) || OSSL_IS_LIBRESSL + ext = X509V3_EXT_nconf(conf, ctx, oid_cstr, RSTRING_PTR(valstr)); +#else + ext = X509V3_EXT_nconf(conf, ctx, (char *)oid_cstr, RSTRING_PTR(valstr)); +#endif X509V3_set_ctx_nodb(ctx); if (!ext){ ossl_raise(eX509ExtError, "%"PRIsVALUE" = %"PRIsVALUE, oid, valstr); diff --git a/test/openssl/test_x509ext.rb b/test/openssl/test_x509ext.rb index c04c06574..838780d32 100644 --- a/test/openssl/test_x509ext.rb +++ b/test/openssl/test_x509ext.rb @@ -78,6 +78,17 @@ def test_factory_create_extension_sn_ln assert_equal(@basic_constraints.to_der, bc_ln.to_der) end + def test_factory_create_extension_oid + ef = OpenSSL::X509::ExtensionFactory.new + ef.config = OpenSSL::Config.parse(<<~_end_of_cnf_) + [basic_constraints] + cA = BOOLEAN:TRUE + pathLenConstraint = INTEGER:2 + _end_of_cnf_ + bc_oid = ef.create_extension("2.5.29.19", "ASN1:SEQUENCE:basic_constraints", true) + assert_equal(@basic_constraints.to_der, bc_oid.to_der) + end + def test_dup ext = OpenSSL::X509::Extension.new(@basic_constraints.to_der) assert_equal(@basic_constraints.to_der, ext.to_der)