rasn1 0.13.0 → 0.13.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50b3f9ddc3a11279f36c21d14768a908b0fe4f22ff75d650791a7a58ac47eaa7
4
- data.tar.gz: d229ea04a626e34d8411e3787101ace2c55e3cef7178b617073ed6b65fefb867
3
+ metadata.gz: e7f6fe2fadbdb5b72ec51995e911ac9adc7efbf497708ca581c2870ed3622b31
4
+ data.tar.gz: 6b68a59752a7ee439a7401b51415070b51ef3241f65864d263c1da9bfcdb2290
5
5
  SHA512:
6
- metadata.gz: 37ea433265c6229a89d896e47918c242b2edc48c24ffa585873e3706dfc3eaf73628b76c91bad3e15e1d969a5caf52237c92336aefdba2668f63f9468e7e2004
7
- data.tar.gz: 0035453de20ea4873999ec18eb3065afa9f1fdddc2927f446ecd2b1851a3a0d1bef32b5bbc2d9029f804a57cd71fefbf95dae4cd4babae5f8491f1e9ea8057ad
6
+ metadata.gz: d67a67c02d381d92ca93552834cdfc5bce175dc31794020c1d39b3fcea6301a50393f1c964c94d04ef7e14b5593275e5f72873bc89097118ce1abe0c6e4c582a
7
+ data.tar.gz: 5f2a8486a6ec2709ab3ecae6b664a4a731394ee5ada28f8c5908734aaf20b3e485eb6f4f0d74dc25d238191875732e02299eda3ad5d765dd870b39bf880c3e3a
data/LICENSE CHANGED
@@ -1,6 +1,7 @@
1
1
  MIT License
2
2
 
3
3
  Copyright (c) 2017 Sylvain Daubert
4
+ Copyright (c) 2024 LemonTree55
4
5
 
5
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
7
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/rasn1.svg)](https://badge.fury.io/rb/rasn1)
2
- [![Action status](https://github.com/sdaubert/rasn1/workflows/ci/badge.svg?branch=master)](https://github.com/sdaubert/rasn1/actions?query=workflow%3Aci)
2
+ [![Action status](https://github.com/lemontree55/rasn1/workflows/ci/badge.svg?branch=master)](https://github.com/lemontree55/rasn1/actions?query=workflow%3Aci)
3
3
 
4
4
  # Rasn1
5
5
 
data/lib/rasn1/model.rb CHANGED
@@ -68,7 +68,7 @@ module RASN1
68
68
  Elem = Struct.new(:name, :proc_or_class, :content) do
69
69
  # @param [String,Symbol] name
70
70
  # @param [Proc,Class] proc_or_class
71
- # @param [Hash,nil] content
71
+ # @param [Array,nil] content
72
72
  def initialize(name, proc_or_class, content)
73
73
  if content.is_a?(Array)
74
74
  duplicate_names = find_all_duplicate_names(content.map(&:name) + [name])
@@ -278,7 +278,7 @@ module RASN1
278
278
  # @return [Elem]
279
279
  # @see Types::SetOf#initialize
280
280
  %w[sequence set].each do |type|
281
- define_type_accel_of(type, Types.const_get("#{type.capitalize}Of"))
281
+ define_type_accel_of(type, Types.const_get(:"#{type.capitalize}Of"))
282
282
  end
283
283
 
284
284
  # @!method boolean(name, options)
@@ -461,6 +461,7 @@ module RASN1
461
461
  root.value
462
462
  else
463
463
  elt = by_name(name)
464
+ return nil if elt.nil?
464
465
 
465
466
  unless args.empty?
466
467
  args.each do |arg|
@@ -504,14 +505,15 @@ module RASN1
504
505
 
505
506
  # Give a (nested) element from its name
506
507
  # @param [String, Symbol] name
507
- # @return [Model, Types::Base]
508
+ # @return [Model, Types::Base, nil]
508
509
  def by_name(name)
509
510
  elt = self[name]
510
511
  return elt unless elt.nil?
511
512
 
512
513
  @elements.each_key do |subelt_name|
513
- if self[subelt_name].is_a?(Model)
514
- elt = self[subelt_name][name]
514
+ subelt = self[subelt_name]
515
+ if subelt.is_a?(Model)
516
+ elt = subelt[name]
515
517
  return elt unless elt.nil?
516
518
  end
517
519
  end
@@ -541,7 +543,12 @@ module RASN1
541
543
  class_element = self.class.class_eval { @root }
542
544
  @root_name = class_element.name
543
545
  @elements = {}
544
- @elements[@root_name] = get_type(class_element.proc_or_class, self.class.options || {})
546
+ @elements[@root_name] = case class_element
547
+ when WrapElem
548
+ generate_wrapper(class_element)
549
+ else
550
+ get_type(class_element.proc_or_class, self.class.options || {})
551
+ end
545
552
  class_element
546
553
  end
547
554
 
@@ -577,17 +584,18 @@ module RASN1
577
584
 
578
585
  def initialize_elements(obj, args)
579
586
  args.each do |name, value|
580
- next unless obj[name]
587
+ subobj = obj[name]
588
+ next unless subobj
581
589
 
582
590
  case value
583
591
  when Hash
584
- raise ArgumentError, "element #{name}: may only pass a Hash for Model elements" unless obj[name].is_a?(Model)
592
+ raise ArgumentError, "element #{name}: may only pass a Hash for Model elements" unless subobj.is_a?(Model)
585
593
 
586
- initialize_elements obj[name], value
594
+ initialize_elements(subobj, value)
587
595
  when Array
588
- initialize_element_from_array(obj[name], value)
596
+ initialize_element_from_array(subobj, value)
589
597
  else
590
- obj[name].value = value
598
+ subobj.value = value
591
599
  end
592
600
  end
593
601
  end
@@ -656,12 +664,13 @@ module RASN1
656
664
  end
657
665
 
658
666
  def wrapper_to_h(wrap)
659
- case wrap.element
667
+ el = wrap.element
668
+ case el
660
669
  when Model
661
- hsh = wrap.element.to_h
670
+ hsh = el.to_h
662
671
  hsh[hsh.keys.first]
663
672
  else
664
- private_to_h(wrap.element)
673
+ private_to_h(el)
665
674
  end
666
675
  end
667
676
  end
data/lib/rasn1/tracer.rb CHANGED
@@ -75,8 +75,8 @@ module RASN1
75
75
  # @private
76
76
  # Unpatch {#do_parse} to remove tracing ability
77
77
  def stop_tracing
78
- alias_method :do_parse, :do_parse_without_tracing # rubocop:disable Lint/DuplicateMethods
79
- alias_method :do_parse_explicit, :do_parse_explicit_without_tracing # rubocop:disable Lint/DuplicateMethods
78
+ alias_method :do_parse, :do_parse_without_tracing
79
+ alias_method :do_parse_explicit, :do_parse_explicit_without_tracing
80
80
  end
81
81
  end
82
82
 
@@ -108,7 +108,7 @@ module RASN1
108
108
  # @private
109
109
  # Unpatch {#parse!} to remove tracing ability
110
110
  def stop_tracing
111
- alias_method :parse!, :parse_without_tracing # rubocop:disable Lint/DuplicateMethods
111
+ alias_method :parse!, :parse_without_tracing
112
112
  end
113
113
  end
114
114
 
@@ -133,7 +133,7 @@ module RASN1
133
133
  # @private
134
134
  # Unpatch {#der_to_value!} to remove tracing ability
135
135
  def stop_tracing
136
- alias_method :der_to_value, :der_to_value_without_tracing # rubocop:disable Lint/DuplicateMethods
136
+ alias_method :der_to_value, :der_to_value_without_tracing
137
137
  end
138
138
  end
139
139
 
@@ -158,7 +158,7 @@ module RASN1
158
158
  # @private
159
159
  # Unpatch {#der_to_value!} to remove tracing ability
160
160
  def stop_tracing
161
- alias_method :der_to_value, :der_to_value_without_tracing # rubocop:disable Lint/DuplicateMethods
161
+ alias_method :der_to_value, :der_to_value_without_tracing
162
162
  end
163
163
  end
164
164
 
@@ -61,7 +61,7 @@ module RASN1
61
61
  private
62
62
 
63
63
  def common_inspect(level)
64
- lvl = level >= 0 ? level : 0
64
+ lvl = [0, level].max
65
65
  str = ' ' * lvl
66
66
  str << "#{@name} " unless @name.nil?
67
67
  str << asn1_class.to_s.upcase << ' ' unless asn1_class == :universal
@@ -82,9 +82,10 @@ module RASN1
82
82
  total_length += id_size
83
83
 
84
84
  @no_value = false
85
- @value = der[0, total_length]
85
+ real_value = der[0, total_length].to_s
86
+ @value = real_value
86
87
 
87
- [total_length, @value]
88
+ [total_length, real_value]
88
89
  end
89
90
 
90
91
  def trace_any
@@ -374,7 +374,7 @@ module RASN1
374
374
  end
375
375
 
376
376
  def common_inspect(level)
377
- lvl = level >= 0 ? level : 0
377
+ lvl = [level, 0].max
378
378
  str = ' ' * lvl
379
379
  str << "#{@name} " unless @name.nil?
380
380
  str << asn1_class_to_s
@@ -427,7 +427,7 @@ module RASN1
427
427
  when nil
428
428
  @asn1_class = :universal
429
429
  when Symbol
430
- raise ClassError unless CLASSES.key? asn1_class
430
+ raise ClassError unless CLASSES.key?(asn1_class)
431
431
 
432
432
  @asn1_class = asn1_class
433
433
  else
@@ -621,7 +621,7 @@ module RASN1
621
621
  def find_type(id)
622
622
  Types.constants.map { |c| Types.const_get(c) }
623
623
  .select { |klass| klass < Primitive || klass < Constructed }
624
- .find { |klass| klass::ID == id }
624
+ .find { |klass| id == klass::ID }
625
625
  end
626
626
 
627
627
  def bin2hex(str)
@@ -9,12 +9,8 @@ module RASN1
9
9
  module Constrained
10
10
  # Define class/module methods for {Constrained} module
11
11
  module ClassMethods
12
- # Setter for constraint
13
- # @param [Proc,nil] constraint
14
- # @return [Proc,nil]
15
- def constraint=(constraint)
16
- @constraint = constraint
17
- end
12
+ # @return [Proc] proc to check constraints
13
+ attr_accessor :constraint
18
14
 
19
15
  # Check if a constraint is really defined
20
16
  # @return [Boolean]
@@ -31,15 +27,7 @@ module RASN1
31
27
  end
32
28
  end
33
29
 
34
- class << self
35
- # @return [Proc] proc to check constraints
36
- attr_reader :constraint
37
-
38
- # Extend +base+ with {ClassMethods}
39
- def included(base)
40
- base.extend ClassMethods
41
- end
42
- end
30
+ extend ClassMethods
43
31
 
44
32
  # Redefined +#value=+ to check constraint before assigning +val+
45
33
  # @see Types::Base#value=
@@ -71,26 +71,25 @@ module RASN1
71
71
  end
72
72
 
73
73
  def value_when_fraction_empty(date_hour)
74
+ # Ruby 3.0: special handle for timezone
75
+ # From 3.1: "Z" and "-0100" are supported
76
+ # Below 3.1: should be "-01:00" or "+00:00"
74
77
  tz = if date_hour[-1] == 'Z'
75
78
  date_hour.slice!(-1, 1)
76
79
  '+00:00' # Ruby 3.0: to remove after end-of support of ruby 3.0
77
80
  elsif date_hour.match?(/[+-]\d+$/)
78
81
  # Ruby 3.0
79
82
  # date_hour.slice!(-5, 5)
80
- zone = date_hour.slice!(-5, 5)
81
- zone[0, 3] << ':' << zone[3, 2]
83
+ zone = date_hour.slice!(-5, 5).to_s
84
+ "#{zone[0, 3]}:#{zone[3, 2]}"
82
85
  end
83
86
  year = date_hour.slice!(0, 4).to_i
84
- others = date_hour.scan(/../).map(&:to_i)
85
- # Ruby 3.0
86
- # From 3.1: "Z" and "-0100" are supported
87
- # Below 3.1: should be "-01:00" or "+00:00"
88
- unless tz.nil?
89
- others += [0] * (5 - others.size)
90
- others << tz
91
- end
92
- @value = Time.new(year, *others)
93
- # From 3.1: replace all this code by: Time.new(year, *others, in: tz)
87
+ month = date_hour.slice!(0, 2).to_i
88
+ day = date_hour.slice!(0, 2).to_i
89
+ hour = date_hour.slice!(0, 2).to_i
90
+ minute = date_hour.slice!(0, 2).to_i
91
+ second = date_hour.slice!(0, 2).to_i
92
+ @value = Time.new(year, month, day, hour, minute, second, tz)
94
93
  end
95
94
 
96
95
  def value_when_fraction_ends_with_z(date_hour, fraction)
@@ -45,10 +45,12 @@ module RASN1
45
45
  # Integer value
46
46
  # @return [Integer]
47
47
  def to_i
48
- if @enum.empty?
49
- value? ? @value : @default || 0
48
+ val = value? ? @value : @default
49
+ case val
50
+ when String, Symbol
51
+ @enum[val]
50
52
  else
51
- @enum[value? ? @value : @default] || 0
53
+ val || 0
52
54
  end
53
55
  end
54
56
 
@@ -135,10 +137,12 @@ module RASN1
135
137
  end
136
138
 
137
139
  def der_to_value(der, ber: false)
138
- @value = der_to_int_value(der, ber: ber)
139
- return if @enum.empty?
140
-
141
- @value = int_to_enum(@value)
140
+ int_value = der_to_int_value(der, ber: ber)
141
+ @value = if @enum.empty?
142
+ int_value
143
+ else
144
+ int_to_enum(int_value)
145
+ end
142
146
  end
143
147
 
144
148
  def explicit_type
@@ -11,18 +11,21 @@ module RASN1
11
11
  private
12
12
 
13
13
  def value_to_der
14
- ids = @value.to_s.split('.').map!(&:to_i)
14
+ ids = @value.to_s.split('.').map(&:to_i)
15
15
 
16
16
  raise ASN1Error, "OBJECT ID #{@name}: first subidentifier should be less than 3" if ids[0] > 2
17
17
  raise ASN1Error, "OBJECT ID #{@name}: second subidentifier should be less than 40" if (ids[0] < 2) && (ids[1] > 39)
18
18
 
19
19
  ids[0, 2] = ids[0] * 40 + ids[1]
20
- ids.map! do |v|
21
- next v if v < 128
22
-
23
- unsigned_to_chained_octets(v)
20
+ octets = []
21
+ ids.each do |v|
22
+ if v < 128
23
+ octets << v
24
+ else
25
+ octets.concat(unsigned_to_chained_octets(v))
26
+ end
24
27
  end
25
- ids.flatten.pack('C*')
28
+ octets.pack('C*')
26
29
  end
27
30
 
28
31
  def der_to_value(der, ber: false) # rubocop:disable Lint/UnusedMethodArgument
@@ -144,11 +144,7 @@ module RASN1
144
144
  nb_bytes = 0
145
145
 
146
146
  while nb_bytes < der.length
147
- type = if composed_of_type? && !@of_type.is_a?(Class)
148
- @of_type.dup
149
- else
150
- of_type_class.new
151
- end
147
+ type = of_type_class.new
152
148
  nb_bytes += type.parse!(der[nb_bytes, der.length])
153
149
  @value << type
154
150
  end
data/lib/rasn1/types.rb CHANGED
@@ -32,18 +32,20 @@ module RASN1
32
32
  # ID and size of identifier octets
33
33
  def self.decode_identifier_octets(der)
34
34
  first_octet = der.unpack1('C').to_i
35
- asn1_class = Types::Base::CLASSES.key(first_octet & Types::Base::CLASS_MASK)
35
+ asn1_class = Types::Base::CLASSES.key(first_octet & Types::Base::CLASS_MASK) || :universal
36
36
  pc = (first_octet & Types::Constructed::ASN1_PC).positive? ? :constructed : :primitive
37
37
  id = first_octet & Types::Base::MULTI_OCTETS_ID
38
38
 
39
39
  size = if id == Types::Base::MULTI_OCTETS_ID
40
40
  id = 0
41
- der.bytes.each_with_index do |octet, i|
42
- next if i.zero?
41
+ count = 1
42
+ der[1..-1].to_s.bytes.each do |octet|
43
+ count += 1
43
44
 
44
45
  id = (id << 7) | (octet & 0x7f)
45
- break i + 1 if (octet & 0x80).zero?
46
+ break if (octet & 0x80).zero?
46
47
  end
48
+ count
47
49
  else
48
50
  1
49
51
  end
@@ -98,11 +100,11 @@ module RASN1
98
100
  # (value >= 0) && (value < 2**32)
99
101
  # end
100
102
  def self.define_type(name, from:, in_module: self, &block)
101
- constraint = block.nil? ? nil : block.to_proc
103
+ constraint = block&.to_proc
102
104
 
103
- new_klass = Class.new(from) do
104
- include Constrained
105
- end
105
+ new_klass = Class.new(from)
106
+ new_klass.include(Constrained)
107
+ new_klass.extend(Constrained::ClassMethods)
106
108
  new_klass.constraint = constraint
107
109
 
108
110
  in_module.const_set(name, new_klass)
data/lib/rasn1/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RASN1
4
- VERSION = '0.13.0'
4
+ VERSION = '0.13.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rasn1
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.13.1
5
5
  platform: ruby
6
6
  authors:
7
- - Sylvain Daubert
7
+ - LemonTree55
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-03 00:00:00.000000000 Z
11
+ date: 2024-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: strptime
@@ -28,7 +28,7 @@ description: |
28
28
  RASN1 is a pure ruby ASN.1 library. It may encode and decode DER and BER
29
29
  encodings.
30
30
  email:
31
- - sylvain.daubert@laposte.net
31
+ - lenontree@proton.me
32
32
  executables: []
33
33
  extensions: []
34
34
  extra_rdoc_files:
@@ -70,13 +70,13 @@ files:
70
70
  - lib/rasn1/types/visible_string.rb
71
71
  - lib/rasn1/version.rb
72
72
  - lib/rasn1/wrapper.rb
73
- homepage: https://github.com/sdaubert/rasn1
73
+ homepage: https://github.com/lemontree55/rasn1
74
74
  licenses:
75
75
  - MIT
76
76
  metadata:
77
- homepage_uri: https://github.com/sdaubert/rasn1
78
- source_code_uri: https://github.com/sdaubert/rasn1
79
- bug_tracker_uri: https://github.com/sdaubert/rasn1/issues
77
+ homepage_uri: https://github.com/lemontree55/rasn1
78
+ source_code_uri: https://github.com/lemontree55/rasn1
79
+ bug_tracker_uri: https://github.com/lemontree55/rasn1/issues
80
80
  documentation_uri: https://www.rubydoc.info/gems/rasn1
81
81
  post_install_message:
82
82
  rdoc_options: