Class: Sigstore::CLI

Inherits:
Thor
  • Object
show all
Defined in:
lib/sigstore/cli.rb,
lib/sigstore/cli/id_token.rb

Defined Under Namespace

Classes: IdToken, ShellWrapper, TUF

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeCLI

Returns a new instance of CLI.



37
38
39
40
41
# File 'lib/sigstore/cli.rb', line 37

def initialize(*)
  super
  Sigstore.logger.reopen ShellWrapper.new(shell)
  Sigstore.logger.level = options[:debug] ? Logger::DEBUG : Logger::INFO
end

Class Method Details

.exit_on_failure?Boolean

Returns:

  • (Boolean)


8
9
10
# File 'lib/sigstore/cli.rb', line 8

def self.exit_on_failure?
  true
end

.start(given_args = ARGV, config = {}) ⇒ Object



12
13
14
15
16
17
18
19
20
21
# File 'lib/sigstore/cli.rb', line 12

def self.start(given_args = ARGV, config = {})
  super
rescue Sigstore::Error => e
  raise if config[:debug] || ENV["THOR_DEBUG"] == "1"

  detailed_message = e.respond_to?(:detailed_message) ? e.detailed_message : e.message
  config[:shell].error(detailed_message)

  exit(false)
end

Instance Method Details

#display(*files) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/sigstore/cli.rb', line 110

def display(*files)
  files.each do |file|
    bundle_bytes = Gem.read_binary(file)
    bundle = SBundle.new Bundle::V1::Bundle.decode_json(bundle_bytes, registry: Sigstore::REGISTRY)

    say "--- Bundle #{file} ---"
    say "Media Type: #{bundle.media_type}"
    say bundle.leaf_certificate.to_text

    case bundle.content
    when :message_signature
      say "Signature over: #{bundle.message_signature.message_digest.algorithm} " \
          "#{Internal::Util.hex_encode bundle.message_signature.message_digest.digest}"
    when :dsse_envelope
      say bundle.dsse_envelope.payloadType
      say bundle.dsse_envelope.payload
    else raise Error::InvalidBundle, "expected either message_signature or dsse_envelope"
    end
  end
end

#sign(file) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/sigstore/cli.rb', line 88

def sign(file)
  self.options = options.merge(identity_token: IdToken.detect_credential).freeze if options[:identity_token].nil?
  unless options[:identity_token]
    raise Error::InvalidIdentityToken,
          "Failed to detect an ambient identity token, please provide one via --identity-token"
  end

  contents = File.binread(file)
  bundle = Sigstore::Signer.new(
    jwt: options[:identity_token],
    trusted_root:
  ).sign(contents)

  File.binwrite(options[:bundle], bundle.to_json) if options[:bundle]
  if options[:signature]
    File.binwrite(options[:signature], Internal::Util.base64_encode(bundle.message_signature.signature))
  end
  File.binwrite(options[:certificate], bundle.verification_material.certificate.raw_bytes) if options[:certificate]
end

#verify(*files) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/sigstore/cli.rb', line 57

def verify(*files)
  verifier, files_with_materials = collect_verification_state(files)
  policy = Sigstore::Policy::Identity.new(
    identity: options[:certificate_identity],
    issuer: options[:certificate_oidc_issuer]
  )

  verified = files_with_materials.all? do |file, input|
    result = verifier.verify(input:, policy:, offline: options[:offline])

    if result.verified?
      say "OK: #{file}"
      true
    else
      say "FAIL: #{file}"
      say "\t#{result.reason}"
      false
    end
  end
  exit(false) unless verified
end