File: rsa_token.rb

package info (click to toggle)
gitlab 17.6.5-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 629,368 kB
  • sloc: ruby: 1,915,304; javascript: 557,307; sql: 60,639; xml: 6,509; sh: 4,567; makefile: 1,239; python: 406
file content (52 lines) | stat: -rw-r--r-- 1,001 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
# frozen_string_literal: true

module JSONWebToken
  class RSAToken < Token
    ALGORITHM = 'RS256'

    attr_reader :key_file

    def initialize(key_file)
      super()
      @key_file = key_file
    end

    def encoded
      self.class.encode(payload, key, kid)
    end

    def self.encode(payload, key, kid)
      headers = { kid: kid, typ: 'JWT' }
      JWT.encode(payload, key, ALGORITHM, headers)
    end

    def self.decode(token, key)
      JWT.decode(token, key, true, { algorithm: ALGORITHM })
    end

    private

    def key_data
      @key_data ||= File.read(key_file)
    end

    def key
      @key ||= OpenSSL::PKey::RSA.new(key_data)
    end

    def public_key
      key.public_key
    end

    def kid
      # calculate sha256 from DER encoded ASN1
      kid = Digest::SHA256.digest(public_key.to_der)

      # we encode only 30 bytes with base32
      kid = Base32.encode(kid[0..29])

      # insert colon every 4 characters
      kid.scan(/.{4}/).join(':')
    end
  end
end