Sha256: 495e5141f347e8075212d8ada03dc304b18089d334f12b1770306a87053c83ba

Contents?: true

Size: 1.9 KB

Versions: 2

Compression:

Stored size: 1.9 KB

Contents

# frozen_string_literal: true

module RASN1
  module Types

    # ASN.1 Object ID
    # @author Sylvain Daubert
    class ObjectId < Primitive
      # ObjectId tag value
      TAG = 6

      private

      def value_to_der
        ids = @value.split('.').map!(&:to_i)

        if ids[0] > 2
          raise ASN1Error, 'OBJECT ID #@name: first subidentifier should be less than 3'
        end
        if (ids[0] < 2) && (ids[1] > 39)
          raise ASN1Error, 'OBJECT ID #@name: second subidentifier should be less than 40'
        end

        ids[0, 2] = ids[0] * 40 + ids[1]
        ids.map! do |v|
          next v if v < 128

          ary = []
          while v.positive?
            ary.unshift((v & 0x7f) | 0x80)
            v >>= 7
          end
          ary[-1] &= 0x7f
          ary
        end
        ids.flatten.pack('C*')
      end

      def der_to_value(der, ber: false)
        bytes = der.unpack('C*')
        nr_bytes_to_remove = 1
        ids = if bytes[0] < 80
                [bytes[0] / 40, bytes[0] % 40]
              elsif bytes[0] < 128
                [2, bytes[0] - 80]
              else
                second_id = bytes[0] & 0x7f
                bytes[1..-1].each do |byte|
                  nr_bytes_to_remove += 1
                  second_id <<= 7
                  if byte < 128
                    second_id |= byte
                    break
                  else
                    second_id |= byte & 0x7f
                  end
                end
                [2, second_id - 80]
              end

        id = 0
        bytes.shift(nr_bytes_to_remove)
        bytes.each do |byte|
          if byte < 128
            if id.zero?
              ids << byte
            else
              ids << ((id << 7) | byte)
              id = 0
            end
          else
            id = (id << 7) | (byte & 0x7f)
          end
        end

        @value = ids.join('.')
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
rasn1-0.7.1 lib/rasn1/types/object_id.rb
rasn1-0.7.0 lib/rasn1/types/object_id.rb