diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2017-07-25 13:47:52 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2017-07-25 13:47:52 +0900 |
commit | 47bc35cb3effded52e9fabcd992386d8d52630bf (patch) | |
tree | 915bdb8c9bf6c4d54c096bcbab7e1713a9346527 | |
parent | 576eff66bece4c3e49d4041a3746c2a520627946 (diff) | |
download | ruby-openssl-ky/x509name-add-entry-options.tar.gz |
x509name: add 'loc' and 'set' kwargs to OpenSSL::X509::Name#add_entryky/x509name-add-entry-options
Add a way to specify these arguments for X509_NAME_add_entry_by_txt().
We currently always use -1 and 0 respectively, which will result in
appending a new single-valued RDN to the end.
Fixes: https://github.com/ruby/openssl/issues/94
-rw-r--r-- | ext/openssl/ossl_x509name.c | 29 | ||||
-rw-r--r-- | test/test_x509name.rb | 34 |
2 files changed, 56 insertions, 7 deletions
diff --git a/ext/openssl/ossl_x509name.c b/ext/openssl/ossl_x509name.c index 6a4a0ea1..ccb2541f 100644 --- a/ext/openssl/ossl_x509name.c +++ b/ext/openssl/ossl_x509name.c @@ -198,7 +198,7 @@ ossl_x509name_initialize_copy(VALUE self, VALUE other) /* * call-seq: - * name.add_entry(oid, value [, type]) => self + * name.add_entry(oid, value [, type], loc: -1, set: 0) => self * * Adds a new entry with the given _oid_ and _value_ to this name. The _oid_ * is an object identifier defined in ASN.1. Some common OIDs are: @@ -209,24 +209,39 @@ ossl_x509name_initialize_copy(VALUE self, VALUE other) * O:: Organization Name * OU:: Organizational Unit Name * ST:: State or Province Name + * + * The optional keyword parameters _loc_ and _set_ specify where to insert the + * new attribute. Refer to the manpage of X509_NAME_add_entry(3) for details. + * _loc_ defaults to -1 and _set_ defaults to 0. This appends a single-valued + * RDN to the end. */ static VALUE ossl_x509name_add_entry(int argc, VALUE *argv, VALUE self) { X509_NAME *name; - VALUE oid, value, type; + VALUE oid, value, type, opts, kwargs[2]; + static ID kwargs_ids[2]; const char *oid_name; + int loc = -1, set = 0; - rb_scan_args(argc, argv, "21", &oid, &value, &type); + if (!kwargs_ids[0]) { + kwargs_ids[0] = rb_intern_const("loc"); + kwargs_ids[1] = rb_intern_const("set"); + } + rb_scan_args(argc, argv, "21:", &oid, &value, &type, &opts); + rb_get_kwargs(opts, kwargs_ids, 0, 2, kwargs); oid_name = StringValueCStr(oid); StringValue(value); if(NIL_P(type)) type = rb_aref(OBJECT_TYPE_TEMPLATE, oid); + if (kwargs[0] != Qundef) + loc = NUM2INT(kwargs[0]); + if (kwargs[1] != Qundef) + set = NUM2INT(kwargs[1]); GetX509Name(self, name); if (!X509_NAME_add_entry_by_txt(name, oid_name, NUM2INT(type), - (const unsigned char *)RSTRING_PTR(value), RSTRING_LENINT(value), -1, 0)) { - ossl_raise(eX509NameError, NULL); - } - + (unsigned char *)RSTRING_PTR(value), + RSTRING_LENINT(value), loc, set)) + ossl_raise(eX509NameError, "X509_NAME_add_entry_by_txt"); return self; } diff --git a/test/test_x509name.rb b/test/test_x509name.rb index 83b1247d..b2196628 100644 --- a/test/test_x509name.rb +++ b/test/test_x509name.rb @@ -320,6 +320,40 @@ class OpenSSL::TestX509Name < OpenSSL::TestCase assert_equal("Namiki", ary[5][1]) end + def test_add_entry_placing + der = %w{ 30 2A + 31 12 + 30 10 06 03 55 04 0A 0C 09 72 75 62 79 2D 6C 61 6E 67 + 31 14 + 30 08 06 03 55 04 0B 0C 01 61 + 30 08 06 03 55 04 0B 0C 01 62 } + orig = OpenSSL::X509::Name.new([der.join].pack("H*")) + assert_equal("OU=b+OU=a,O=ruby-lang", orig.to_s(OpenSSL::X509::Name::RFC2253)) + # Skip for now; they do not work + # + # dn = orig.dup + # dn.add_entry("CN", "unya", loc: 0, set: 0) + # assert_equal("OU=b+OU=a,O=ruby-lang,CN=unya", dn.dup.to_s(OpenSSL::X509::Name::RFC2253)) + # dn = orig.dup + # dn.add_entry("CN", "unya", loc: 0, set: 1) + # assert_equal("OU=b+OU=a,O=ruby-lang+CN=unya", dn.dup.to_s(OpenSSL::X509::Name::RFC2253)) + dn = orig.dup + dn.add_entry("CN", "unya", loc: 1, set: -1) + assert_equal("OU=b+OU=a,O=ruby-lang+CN=unya", dn.dup.to_s(OpenSSL::X509::Name::RFC2253)) + # dn = orig.dup + # dn.add_entry("CN", "unya", loc: 1, set: 0) + # assert_equal("OU=b+OU=a,CN=unya,O=ruby-lang", dn.dup.to_s(OpenSSL::X509::Name::RFC2253)) + dn = orig.dup + dn.add_entry("CN", "unya", loc: 1, set: 1) + assert_equal("CN=unya+OU=b+OU=a,O=ruby-lang", dn.dup.to_s(OpenSSL::X509::Name::RFC2253)) + dn = orig.dup + dn.add_entry("CN", "unya", loc: -1, set: -1) + assert_equal("CN=unya+OU=b+OU=a,O=ruby-lang", dn.dup.to_s(OpenSSL::X509::Name::RFC2253)) + dn = orig.dup + dn.add_entry("CN", "unya", loc: -1, set: 0) + assert_equal("CN=unya,OU=b+OU=a,O=ruby-lang", dn.dup.to_s(OpenSSL::X509::Name::RFC2253)) + end + def test_equals2 n1 = OpenSSL::X509::Name.parse 'CN=a' n2 = OpenSSL::X509::Name.parse 'CN=a' |