diff options
author | HoneyryderChuck <[email protected]> | 2024-04-16 18:07:56 +0100 |
---|---|---|
committer | git <[email protected]> | 2024-06-27 16:00:55 +0000 |
commit | 9c5e9d29f0c9b025577cb72b421b9682bfadcd37 () | |
tree | 9bfaa0a9de073d7fcc4ba3e8359a598adaf4b855 | |
parent | c6a0d03649c686a537c1f513a1e32205ac6a6512 (diff) |
[ruby/openssl] rewriting most of the asn1 init code in ruby
to have as much of the lib in ruby as possible https://.com/ruby/openssl/commit/8305051728
-rw-r--r-- | ext/openssl/lib/openssl.rb | 1 | ||||
-rw-r--r-- | ext/openssl/lib/openssl/asn1.rb | 188 | ||||
-rw-r--r-- | ext/openssl/ossl_asn1.c | 238 | ||||
-rw-r--r-- | ext/openssl/ossl_asn1.h | 2 |
4 files changed, 213 insertions, 216 deletions
@@ -13,6 +13,7 @@ require 'openssl.so' require_relative 'openssl/bn' require_relative 'openssl/pkey' require_relative 'openssl/cipher' require_relative 'openssl/digest' @@ -0,0 +1,188 @@ @@ -11,7 +11,6 @@ static VALUE ossl_asn1_decode0(unsigned char **pp, long length, long *offset, int depth, int yield, long *num_read); -static VALUE ossl_asn1_initialize(int argc, VALUE *argv, VALUE self); /* * DATE conversion @@ -158,10 +157,6 @@ asn1integer_to_num_i(VALUE arg) #define ossl_asn1_get_tag_class(o) rb_attr_get((o),sivTAG_CLASS) #define ossl_asn1_get_indefinite_length(o) rb_attr_get((o),sivINDEFINITE_LENGTH) -#define ossl_asn1_set_value(o,v) rb_ivar_set((o),sivVALUE,(v)) -#define ossl_asn1_set_tag(o,v) rb_ivar_set((o),sivTAG,(v)) -#define ossl_asn1_set_tagging(o,v) rb_ivar_set((o),sivTAGGING,(v)) -#define ossl_asn1_set_tag_class(o,v) rb_ivar_set((o),sivTAG_CLASS,(v)) #define ossl_asn1_set_indefinite_length(o,v) rb_ivar_set((o),sivINDEFINITE_LENGTH,(v)) VALUE mASN1; @@ -189,7 +184,6 @@ VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ static VALUE sym_IMPLICIT, sym_EXPLICIT; static VALUE sym_UNIVERSAL, sym_APPLICATION, sym_CONTEXT_SPECIFIC, sym_PRIVATE; static ID sivVALUE, sivTAG, sivTAG_CLASS, sivTAGGING, sivINDEFINITE_LENGTH, sivUNUSED_BITS; -static ID id_each; /* * Ruby to ASN1 converters @@ -638,35 +632,6 @@ ossl_asn1_class2sym(int tc) return sym_UNIVERSAL; } -/* - * call-seq: - * OpenSSL::ASN1::ASN1Data.new(value, tag, tag_class) => ASN1Data - * - * _value_: Please have a look at Constructive and Primitive to see how Ruby - * types are mapped to ASN.1 types and vice versa. - * - * _tag_: An Integer indicating the tag number. - * - * _tag_class_: A Symbol indicating the tag class. Please cf. ASN1 for - * possible values. - * - * == Example - * asn1_int = OpenSSL::ASN1Data.new(42, 2, :UNIVERSAL) # => Same as OpenSSL::ASN1::Integer.new(42) - * tagged_int = OpenSSL::ASN1Data.new(42, 0, :CONTEXT_SPECIFIC) # implicitly 0-tagged INTEGER - */ -static VALUE -ossl_asn1data_initialize(VALUE self, VALUE value, VALUE tag, VALUE tag_class) -{ - if(!SYMBOL_P(tag_class)) - ossl_raise(eASN1Error, "invalid tag class"); - ossl_asn1_set_tag(self, tag); - ossl_asn1_set_value(self, value); - ossl_asn1_set_tag_class(self, tag_class); - ossl_asn1_set_indefinite_length(self, Qfalse); - - return self; -} - static VALUE to_der_internal(VALUE self, int constructed, int indef_len, VALUE body) { @@ -795,20 +760,19 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag, if (tc == sym_UNIVERSAL && tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass) { VALUE klass = *ossl_asn1_info[tag].klass; - VALUE args[4]; - args[0] = value; - args[1] = INT2NUM(tag); - args[2] = Qnil; - args[3] = tc; - asn1data = rb_obj_alloc(klass); - ossl_asn1_initialize(4, args, asn1data); if(tag == V_ASN1_BIT_STRING){ rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag)); } } else { - asn1data = rb_obj_alloc(cASN1Data); - ossl_asn1data_initialize(asn1data, value, INT2NUM(tag), tc); } return asn1data; @@ -842,20 +806,20 @@ int_ossl_asn1_decode0_cons(unsigned char **pp, long max_len, long length, } if (tc == sym_UNIVERSAL) { - VALUE args[4]; - if (tag == V_ASN1_SEQUENCE || tag == V_ASN1_SET) - asn1data = rb_obj_alloc(*ossl_asn1_info[tag].klass); - else - asn1data = rb_obj_alloc(cASN1Constructive); - args[0] = ary; - args[1] = INT2NUM(tag); - args[2] = Qnil; - args[3] = tc; - ossl_asn1_initialize(4, args, asn1data); } else { - asn1data = rb_obj_alloc(cASN1Data); - ossl_asn1data_initialize(asn1data, ary, INT2NUM(tag), tc); } if (indefinite) @@ -1048,83 +1012,6 @@ ossl_asn1_decode_all(VALUE self, VALUE obj) return ary; } -/* - * call-seq: - * OpenSSL::ASN1::Primitive.new(value [, tag, tagging, tag_class ]) => Primitive - * - * _value_: is mandatory. - * - * _tag_: optional, may be specified for tagged values. If no _tag_ is - * specified, the UNIVERSAL tag corresponding to the Primitive sub-class - * is used by default. - * - * _tagging_: may be used as an encoding hint to encode a value either - * explicitly or implicitly, see ASN1 for possible values. - * - * _tag_class_: if _tag_ and _tagging_ are +nil+ then this is set to - * +:UNIVERSAL+ by default. If either _tag_ or _tagging_ are set then - * +:CONTEXT_SPECIFIC+ is used as the default. For possible values please - * cf. ASN1. - * - * == Example - * int = OpenSSL::ASN1::Integer.new(42) - * zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :IMPLICIT) - * private_explicit_zero_tagged_int = OpenSSL::ASN1::Integer.new(42, 0, :EXPLICIT, :PRIVATE) - */ -static VALUE -ossl_asn1_initialize(int argc, VALUE *argv, VALUE self) -{ - VALUE value, tag, tagging, tag_class; - int default_tag; - - rb_scan_args(argc, argv, "13", &value, &tag, &tagging, &tag_class); - default_tag = ossl_asn1_default_tag(self); - - if (default_tag == -1 || argc > 1) { - if(NIL_P(tag)) - ossl_raise(eASN1Error, "must specify tag number"); - if(!NIL_P(tagging) && !SYMBOL_P(tagging)) - ossl_raise(eASN1Error, "invalid tagging method"); - if(NIL_P(tag_class)) { - if (NIL_P(tagging)) - tag_class = sym_UNIVERSAL; - else - tag_class = sym_CONTEXT_SPECIFIC; - } - if(!SYMBOL_P(tag_class)) - ossl_raise(eASN1Error, "invalid tag class"); - } - else{ - tag = INT2NUM(default_tag); - tagging = Qnil; - tag_class = sym_UNIVERSAL; - } - ossl_asn1_set_tag(self, tag); - ossl_asn1_set_value(self, value); - ossl_asn1_set_tagging(self, tagging); - ossl_asn1_set_tag_class(self, tag_class); - ossl_asn1_set_indefinite_length(self, Qfalse); - if (default_tag == V_ASN1_BIT_STRING) - rb_ivar_set(self, sivUNUSED_BITS, INT2FIX(0)); - - return self; -} - -static VALUE -ossl_asn1eoc_initialize(VALUE self) { - VALUE tag, tagging, tag_class, value; - tag = INT2FIX(0); - tagging = Qnil; - tag_class = sym_UNIVERSAL; - value = rb_str_new("", 0); - ossl_asn1_set_tag(self, tag); - ossl_asn1_set_value(self, value); - ossl_asn1_set_tagging(self, tagging); - ossl_asn1_set_tag_class(self, tag_class); - ossl_asn1_set_indefinite_length(self, Qfalse); - return self; -} - static VALUE ossl_asn1eoc_to_der(VALUE self) { @@ -1218,27 +1105,6 @@ ossl_asn1cons_to_der(VALUE self) /* * call-seq: - * asn1_ary.each { |asn1| block } => asn1_ary - * - * Calls the given block once for each element in self, passing that element - * as parameter _asn1_. If no block is given, an enumerator is returned - * instead. - * - * == Example - * asn1_ary.each do |asn1| - * puts asn1 - * end - */ -static VALUE -ossl_asn1cons_each(VALUE self) -{ - rb_block_call(ossl_asn1_get_value(self), id_each, 0, 0, 0, 0); - - return self; -} - -/* - * call-seq: * OpenSSL::ASN1::ObjectId.register(object_id, short_name, long_name) * * This adds a new ObjectId to the internal tables. Where _object_id_ is the @@ -1371,7 +1237,7 @@ ossl_asn1obj_get_oid(VALUE self) #define OSSL_ASN1_IMPL_FACTORY_METHOD(klass) \ static VALUE ossl_asn1_##klass(int argc, VALUE *argv, VALUE self)\ -{ return rb_funcall3(cASN1##klass, rb_intern("new"), argc, argv); } OSSL_ASN1_IMPL_FACTORY_METHOD(Boolean) OSSL_ASN1_IMPL_FACTORY_METHOD(Integer) @@ -1657,42 +1523,6 @@ Init_ossl_asn1(void) * puts int2.value # => 1 */ cASN1Data = rb_define_class_under(mASN1, "ASN1Data", rb_cObject); - /* - * Carries the value of a ASN.1 type. - * Please confer Constructive and Primitive for the mappings between - * ASN.1 data types and Ruby classes. - */ - rb_attr(cASN1Data, rb_intern("value"), 1, 1, 0); - /* - * An Integer representing the tag number of this ASN1Data. Never +nil+. - */ - rb_attr(cASN1Data, rb_intern("tag"), 1, 1, 0); - /* - * A Symbol representing the tag class of this ASN1Data. Never +nil+. - * See ASN1Data for possible values. - */ - rb_attr(cASN1Data, rb_intern("tag_class"), 1, 1, 0); - /* - * Never +nil+. A boolean value indicating whether the encoding uses - * indefinite length (in the case of parsing) or whether an indefinite - * length form shall be used (in the encoding case). - * In DER, every value uses definite length form. But in scenarios where - * large amounts of data need to be transferred it might be desirable to - * have some kind of support available. - * For example, huge OCTET STRINGs are preferably sent in smaller-sized - * chunks, each at a time. - * This is possible in BER by setting the length bytes of an encoding - * to zero and by this indicating that the following value will be - * sent in chunks. Indefinite length encodings are always constructed. - * The end of such a stream of chunks is indicated by sending a EOC - * (End of Content) tag. SETs and SEQUENCEs may use an indefinite length - * encoding, but also primitive types such as e.g. OCTET STRINGS or - * BIT STRINGS may leverage this functionality (cf. ITU-T X.690). - */ - rb_attr(cASN1Data, rb_intern("indefinite_length"), 1, 1, 0); - rb_define_alias(cASN1Data, "infinite_length", "indefinite_length"); - rb_define_alias(cASN1Data, "infinite_length=", "indefinite_length="); - rb_define_method(cASN1Data, "initialize", ossl_asn1data_initialize, 3); rb_define_method(cASN1Data, "to_der", ossl_asn1data_to_der, 0); /* Document-class: OpenSSL::ASN1::Primitive @@ -1760,16 +1590,6 @@ Init_ossl_asn1(void) * prim_zero_tagged_explicit = <class>.new(value, 0, :EXPLICIT) */ cASN1Primitive = rb_define_class_under(mASN1, "Primitive", cASN1Data); - /* - * May be used as a hint for encoding a value either implicitly or - * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+. - * _tagging_ is not set when a ASN.1 structure is parsed using - * OpenSSL::ASN1.decode. - */ - rb_attr(cASN1Primitive, rb_intern("tagging"), 1, 1, Qtrue); - rb_undef_method(cASN1Primitive, "indefinite_length="); - rb_undef_method(cASN1Primitive, "infinite_length="); - rb_define_method(cASN1Primitive, "initialize", ossl_asn1_initialize, -1); rb_define_method(cASN1Primitive, "to_der", ossl_asn1prim_to_der, 0); /* Document-class: OpenSSL::ASN1::Constructive @@ -1800,17 +1620,7 @@ Init_ossl_asn1(void) * set = OpenSSL::ASN1::Set.new( [ int, str ] ) */ cASN1Constructive = rb_define_class_under(mASN1,"Constructive", cASN1Data); - rb_include_module(cASN1Constructive, rb_mEnumerable); - /* - * May be used as a hint for encoding a value either implicitly or - * explicitly by setting it either to +:IMPLICIT+ or to +:EXPLICIT+. - * _tagging_ is not set when a ASN.1 structure is parsed using - * OpenSSL::ASN1.decode. - */ - rb_attr(cASN1Constructive, rb_intern("tagging"), 1, 1, Qtrue); - rb_define_method(cASN1Constructive, "initialize", ossl_asn1_initialize, -1); rb_define_method(cASN1Constructive, "to_der", ossl_asn1cons_to_der, 0); - rb_define_method(cASN1Constructive, "each", ossl_asn1cons_each, 0); #define OSSL_ASN1_DEFINE_CLASS(name, super) \ do{\ @@ -1859,13 +1669,10 @@ do{\ rb_define_alias(cASN1ObjectId, "short_name", "sn"); rb_define_alias(cASN1ObjectId, "long_name", "ln"); rb_define_method(cASN1ObjectId, "==", ossl_asn1obj_eq, 1); - rb_attr(cASN1BitString, rb_intern("unused_bits"), 1, 1, 0); - rb_define_method(cASN1EndOfContent, "initialize", ossl_asn1eoc_initialize, 0); rb_define_method(cASN1EndOfContent, "to_der", ossl_asn1eoc_to_der, 0); class_tag_map = rb_hash_new(); - rb_gc_register_mark_object(class_tag_map); rb_hash_aset(class_tag_map, cASN1EndOfContent, INT2NUM(V_ASN1_EOC)); rb_hash_aset(class_tag_map, cASN1Boolean, INT2NUM(V_ASN1_BOOLEAN)); rb_hash_aset(class_tag_map, cASN1Integer, INT2NUM(V_ASN1_INTEGER)); @@ -1889,6 +1696,5 @@ do{\ rb_hash_aset(class_tag_map, cASN1GeneralString, INT2NUM(V_ASN1_GENERALSTRING)); rb_hash_aset(class_tag_map, cASN1UniversalString, INT2NUM(V_ASN1_UNIVERSALSTRING)); rb_hash_aset(class_tag_map, cASN1BMPString, INT2NUM(V_ASN1_BMPSTRING)); - - id_each = rb_intern_const("each"); } @@ -55,6 +55,8 @@ extern VALUE cASN1ObjectId; /* OBJECT IDENTIFIER */ extern VALUE cASN1UTCTime, cASN1GeneralizedTime; /* TIME */ extern VALUE cASN1Sequence, cASN1Set; /* CONSTRUCTIVE */ ASN1_TYPE *ossl_asn1_get_asn1type(VALUE); void Init_ossl_asn1(void); |