Class: Sigstore::Rekor::Checkpoint::SignedNote

Inherits:
Struct
  • Object
show all
Defined in:
lib/sigstore/rekor/checkpoint.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#noteObject

Returns the value of attribute note

Returns:

  • (Object)

    the current value of note



33
34
35
# File 'lib/sigstore/rekor/checkpoint.rb', line 33

def note
  @note
end

#signaturesObject

Returns the value of attribute signatures

Returns:

  • (Object)

    the current value of signatures



33
34
35
# File 'lib/sigstore/rekor/checkpoint.rb', line 33

def signatures
  @signatures
end

Class Method Details

.from_text(text) ⇒ Object



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
# File 'lib/sigstore/rekor/checkpoint.rb', line 36

def self.from_text(text)
  separator = "\n\n"

  raise Error::InvalidCheckpoint, "Note must include double newline separator" unless text.include?(separator)

  note, signatures = text.split(separator, 2)
  raise Error::InvalidCheckpoint, "must contain at least one signature" if signatures.empty?
  raise Error::InvalidCheckpoint, "signatures must end with a newline" unless signatures.end_with?("\n")

  note << "\n"

  sig_parser = %r{^\u2014 (?<name>[^[[:space:]]+]+) (?<signature>[0-9A-Za-z+/=-]+)\n}

  signatures = signatures.lines.map! do |line|
    raise Error::InvalidCertificate, "Invalid signature line: #{line.inspect}" unless sig_parser =~ line

    name = Regexp.last_match[:name]
    signature = Regexp.last_match[:signature]

    signature_bytes = signature.unpack1("m0")
    raise Error::InvalidCheckpoint, "too few bytes in signature" if signature_bytes.bytesize < 5

    sig_hash = signature_bytes.slice!(0, 4).unpack1("a4")

    Signature.new(name:, sig_hash:, signature: signature_bytes)
  end

  new(note:, signatures:)
end

Instance Method Details

#verify(rekor_keyring, key_id) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sigstore/rekor/checkpoint.rb', line 66

def verify(rekor_keyring, key_id)
  data = note.encode("utf-8")
  signatures.each do |signature|
    sig_hash = key_id[0, 4]
    if signature.sig_hash != sig_hash
      raise Error::InvalidCheckpoint,
            "sig_hash hint #{signature.sig_hash.inspect} does not match key_id #{sig_hash.inspect}"
    end

    rekor_keyring.verify(key_id: key_id.unpack1("H*"), signature: signature.signature, data:)
  end
end