diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2017-09-03 18:59:33 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-03 18:59:33 +0900 |
commit | a91c6b054288aabeea441f57117f83c70b50abde (patch) | |
tree | d70bc4f625b415fb32cb39b070d53df09074abe3 | |
parent | e96d9c02c4d4788083360fa49d3afcba9ffef289 (diff) | |
parent | 3b6cdf121cf541c39df217b1e9068cabf537e475 (diff) | |
download | ruby-openssl-a91c6b054288aabeea441f57117f83c70b50abde.tar.gz |
Merge pull request #143 from rhenium/ky/x509name-to-utf-8
Add X509::Name#to_utf8 and #inspect
-rw-r--r-- | ext/openssl/ossl_x509name.c | 61 | ||||
-rw-r--r-- | test/test_x509name.rb | 39 |
2 files changed, 83 insertions, 17 deletions
diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index ccb2541f..b2063954 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -260,6 +260,23 @@ ossl_x509name_to_s_old(VALUE self) return str; } +static VALUE +x509name_print(VALUE self, unsigned long iflag) +{ + X509_NAME *name; + BIO *out; + + GetX509Name(self, name); + out = BIO_new(BIO_s_mem()); + if (!out) + ossl_raise(eX509NameError, NULL); + if (!X509_NAME_print_ex(out, name, 0, iflag)) { + BIO_free(out); + ossl_raise(eX509NameError, "X509_NAME_print_ex"); + } + return ossl_membio2str(out); +} + /* * call-seq: * name.to_s -> string @@ -279,27 +296,37 @@ ossl_x509name_to_s_old(VALUE self) static VALUE ossl_x509name_to_s(int argc, VALUE *argv, VALUE self) { - X509_NAME *name; - VALUE flag, str; - BIO *out; - unsigned long iflag; - - rb_scan_args(argc, argv, "01", &flag); - if (NIL_P(flag)) + rb_check_arity(argc, 0, 1); + /* name.to_s(nil) was allowed */ + if (!argc || NIL_P(argv[0])) return ossl_x509name_to_s_old(self); - else iflag = NUM2ULONG(flag); - if (!(out = BIO_new(BIO_s_mem()))) - ossl_raise(eX509NameError, NULL); - GetX509Name(self, name); - if (!X509_NAME_print_ex(out, name, 0, iflag)){ - BIO_free(out); - ossl_raise(eX509NameError, NULL); - } - str = ossl_membio2str(out); + else + return x509name_print(self, NUM2ULONG(argv[0])); +} +/* + * call-seq; + * name.to_utf8 -> string + * + * Returns an UTF-8 representation of the distinguished name, as specified + * in {RFC 2253}[https://www.ietf.org/rfc/rfc2253.txt]. + */ +static VALUE +ossl_x509name_to_utf8(VALUE self) +{ + VALUE str = x509name_print(self, XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB); + rb_enc_associate_index(str, rb_utf8_encindex()); return str; } +/* :nodoc: */ +static VALUE +ossl_x509name_inspect(VALUE self) +{ + return rb_enc_sprintf(rb_utf8_encoding(), "#<%"PRIsVALUE" %"PRIsVALUE">", + rb_obj_class(self), ossl_x509name_to_utf8(self)); +} + /* * call-seq: * name.to_a => [[name, data, type], ...] @@ -494,6 +521,8 @@ Init_ossl_x509name(void) rb_define_method(cX509Name, "initialize_copy", ossl_x509name_initialize_copy, 1); rb_define_method(cX509Name, "add_entry", ossl_x509name_add_entry, -1); rb_define_method(cX509Name, "to_s", ossl_x509name_to_s, -1); + rb_define_method(cX509Name, "to_utf8", ossl_x509name_to_utf8, 0); + rb_define_method(cX509Name, "inspect", ossl_x509name_inspect, 0); rb_define_method(cX509Name, "to_a", ossl_x509name_to_a, 0); rb_define_method(cX509Name, "cmp", ossl_x509name_cmp, 1); rb_define_alias(cX509Name, "<=>", "cmp"); diff --git a/test/test_x509name.rb b/test/test_x509name.rb index 2f77f20b..ce370415 100644 --- a/test/test_x509name.rb +++ b/test/test_x509name.rb @@ -1,4 +1,4 @@ -# coding: US-ASCII +# coding: ASCII-8BIT # frozen_string_literal: false require_relative 'utils' @@ -356,6 +356,43 @@ class OpenSSL::TestX509Name < OpenSSL::TestCase assert_equal("CN=unya,OU=b+OU=a,O=ruby-lang", dn.dup.to_s(OpenSSL::X509::Name::RFC2253)) end + def test_to_s + dn = [ + ["DC", "org"], + ["DC", "ruby-lang"], + ["CN", "フー, バー"], + ] + name = OpenSSL::X509::Name.new + dn.each { |x| name.add_entry(*x) } + + assert_equal "/DC=org/DC=ruby-lang/" \ + "CN=\\xE3\\x83\\x95\\xE3\\x83\\xBC, \\xE3\\x83\\x90\\xE3\\x83\\xBC", + name.to_s + # OpenSSL escapes characters with MSB by default + assert_equal \ + "CN=\\E3\\83\\95\\E3\\83\\BC\\, \\E3\\83\\90\\E3\\83\\BC," \ + "DC=ruby-lang,DC=org", + name.to_s(OpenSSL::X509::Name::RFC2253) + assert_equal "DC = org, DC = ruby-lang, " \ + "CN = \"\\E3\\83\\95\\E3\\83\\BC, \\E3\\83\\90\\E3\\83\\BC\"", + name.to_s(OpenSSL::X509::Name::ONELINE) + end + + def test_to_utf8 + dn = [ + ["DC", "org"], + ["DC", "ruby-lang"], + ["CN", "フー, バー"], + ] + name = OpenSSL::X509::Name.new + dn.each { |x| name.add_entry(*x) } + + str = name.to_utf8 + expected = "CN=フー\\, バー,DC=ruby-lang,DC=org".force_encoding("UTF-8") + assert_equal expected, str + assert_equal Encoding.find("UTF-8"), str.encoding + end + def test_equals2 n1 = OpenSSL::X509::Name.parse 'CN=a' n2 = OpenSSL::X509::Name.parse 'CN=a' |