base.rb 1.91 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Acme::Client::JWK::Base
  THUMBPRINT_DIGEST = OpenSSL::Digest::SHA256

  # Initialize a new JWK.
  #
  # Returns nothing.
  def initialize
    raise NotImplementedError
  end

  # Generate a JWS JSON web signature.
  #
  # header  - A Hash of extra header fields to include.
  # payload - A Hash of payload data.
  #
  # Returns a JSON String.
  def jws(header: {}, payload: {})
18
    header = jws_header(header)
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
    encoded_header = Acme::Client::Util.urlsafe_base64(header.to_json)
    encoded_payload = Acme::Client::Util.urlsafe_base64(payload.to_json)

    signature_data = "#{encoded_header}.#{encoded_payload}"
    signature = sign(signature_data)
    encoded_signature = Acme::Client::Util.urlsafe_base64(signature)

    {
      protected: encoded_header,
      payload: encoded_payload,
      signature: encoded_signature
    }.to_json
  end

  # Serialize this JWK as JSON.
  #
  # Returns a JSON string.
  def to_json
    to_h.to_json
  end

  # Get this JWK as a Hash for JSON serialization.
  #
  # Returns a Hash.
  def to_h
    raise NotImplementedError
  end

  # JWK thumbprint as used for key authorization.
  #
  # Returns a String.
  def thumbprint
    Acme::Client::Util.urlsafe_base64(THUMBPRINT_DIGEST.digest(to_json))
  end

  # Header fields for a JSON web signature.
  #
  # typ: - Value for the `typ` field. Default 'JWT'.
  #
  # Returns a Hash.
59
60
  def jws_header(header)
    jws = {
61
      typ: 'JWT',
62
63
64
65
      alg: jwa_alg
    }.merge(header)
    jws[:jwk] = to_h if header[:kid].nil?
    jws
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
  end

  # The name of the algorithm as needed for the `alg` member of a JWS object.
  #
  # Returns a String.
  def jwa_alg
    raise NotImplementedError
  end

  # Sign a message with the private key.
  #
  # message - A String message to sign.
  #
  # Returns a String signature.
  # rubocop:disable Lint/UnusedMethodArgument
  def sign(message)
    raise NotImplementedError
  end
  # rubocop:enable Lint/UnusedMethodArgument
end