File: dsig.rb

package info (click to toggle)
ruby-ttfunk 1.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,472 kB
  • sloc: ruby: 7,954; makefile: 7
file content (93 lines) | stat: -rw-r--r-- 2,313 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# frozen_string_literal: true

module TTFunk
  class Table
    # Digital Signature (`DSIG`) table.
    class Dsig < Table
      # Signature record.
      class SignatureRecord
        # Format of the signature.
        # @return [Integer]
        attr_reader :format

        # Length of signature in bytes.
        # @return [Integer]
        attr_reader :length

        # Offset to the signature block from the beginning of the table.
        # @return [Integer]
        attr_reader :offset

        # Signature PKCS#7 packet.
        # @return [String]
        attr_reader :signature

        # @param format [Integer]
        # @param length [Integer]
        # @param offset [Integer]
        # @param signature [String]
        def initialize(format, length, offset, signature)
          @format = format
          @length = length
          @offset = offset
          @signature = signature
        end
      end

      # Version umber of this table.
      # @return [Integer]
      attr_reader :version

      # Permission flags.
      # @return [Integer]
      attr_reader :flags

      # Signature records.
      # @return [Array<SignatureRecord>]
      attr_reader :signatures

      # Table tag.
      TAG = 'DSIG'

      # Encode table.
      #
      # **Note**: all signatures will be lost. This encodes an empty table
      # regardless whether the supplied table contains any signtaures or not.
      #
      # @param dsig [TTFunk::Table::Dsig]
      # @return [String]
      def self.encode(dsig)
        return unless dsig

        # Don't attempt to re-sign or anything - just use dummy values.
        # Since we're subsetting that should be permissible.
        [dsig.version, 0, 0].pack('Nnn')
      end

      # Table tag.
      #
      # @return [String]
      def tag
        TAG
      end

      private

      def parse!
        @version, num_signatures, @flags = read(8, 'Nnn')

        @signatures =
          Array.new(num_signatures) {
            format, length, sig_offset = read(12, 'N3')
            signature =
              parse_from(offset + sig_offset) {
                _, _, sig_length = read(8, 'nnN')
                read(sig_length, 'C*')
              }

            SignatureRecord.new(format, length, sig_offset, signature)
          }
      end
    end
  end
end