sigstore 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sigstore/internal/json.rb +24 -13
- data/lib/sigstore/internal/x509.rb +3 -1
- data/lib/sigstore/models.rb +19 -5
- data/lib/sigstore/policy.rb +5 -3
- data/lib/sigstore/signer.rb +2 -2
- data/lib/sigstore/tuf/updater.rb +2 -0
- data/lib/sigstore/tuf.rb +1 -1
- data/lib/sigstore/verifier.rb +12 -3
- data/lib/sigstore/version.rb +1 -1
- data/lib/sigstore.rb +3 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c3e5197bbb3241e4291d84bbb83a86c5dbc68cc954f774dbbef9ea8279be207
|
4
|
+
data.tar.gz: 2bf3d8b1c10807dc993a1275ad788128f9483b718c87da5b21f79588ce533ed1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c23dd685934043f14460c655650eb25280e7984789bd2fa5b3c70afdb1ab0a8cfd591eaf07d3e894fbec5bbffd087c4cd4f3ad9d1c9d04da9f18f47aa670bd4e
|
7
|
+
data.tar.gz: 2ad3857c1e1c85fe04007d471d4c68c19bf5080bfbd0c492860a60717f88af987fb66498c2d51ab267e763eba3357da72c95149592f352594625152a8d920015
|
@@ -18,33 +18,44 @@ module Sigstore::Internal
|
|
18
18
|
module JSON
|
19
19
|
# Implements https://wiki.laptop.org/go/Canonical_JSON
|
20
20
|
#
|
21
|
-
|
22
|
-
# serializing into a buffer instead of concatenating strings.
|
23
|
-
def self.canonical_generate(data)
|
21
|
+
def self.canonical_generate(data, buffer = +"")
|
24
22
|
case data
|
25
23
|
when NilClass
|
26
|
-
"null"
|
24
|
+
buffer << "null"
|
27
25
|
when TrueClass
|
28
|
-
"true"
|
26
|
+
buffer << "true"
|
29
27
|
when FalseClass
|
30
|
-
"false"
|
28
|
+
buffer << "false"
|
31
29
|
when Integer
|
32
|
-
data.to_s
|
30
|
+
buffer << data.to_s
|
33
31
|
when String
|
34
|
-
"
|
32
|
+
buffer << '"' << data.gsub(/(["\\])/, '\\\\\1') << '"'
|
35
33
|
when Array
|
36
|
-
|
37
|
-
|
34
|
+
buffer << "["
|
35
|
+
data.each_with_index do |v, i|
|
36
|
+
buffer << "," unless i.zero?
|
37
|
+
canonical_generate(v, buffer)
|
38
|
+
end
|
39
|
+
buffer << "]"
|
38
40
|
when Hash
|
39
41
|
contents = data.sort_by do |k, _|
|
40
42
|
raise ArgumentError, "Non-string key in hash" unless k.is_a?(String)
|
41
43
|
|
42
44
|
k.encode("utf-16").codepoints
|
43
45
|
end
|
44
|
-
|
45
|
-
|
46
|
+
buffer << "{"
|
47
|
+
comma = false
|
48
|
+
contents.each do |k, v|
|
49
|
+
if comma
|
50
|
+
buffer << ","
|
51
|
+
else
|
52
|
+
comma = true
|
53
|
+
end
|
54
|
+
canonical_generate(k, buffer)
|
55
|
+
buffer << ":"
|
56
|
+
canonical_generate(v, buffer)
|
46
57
|
end
|
47
|
-
"
|
58
|
+
buffer << "}"
|
48
59
|
else
|
49
60
|
raise ArgumentError, "Unsupported data type: #{data.class}"
|
50
61
|
end
|
@@ -38,6 +38,8 @@ module Sigstore
|
|
38
38
|
|
39
39
|
def self.read(certificate_bytes)
|
40
40
|
new(OpenSSL::X509::Certificate.new(certificate_bytes))
|
41
|
+
rescue OpenSSL::X509::CertificateError => e
|
42
|
+
raise Error::InvalidCertificate, e.message
|
41
43
|
end
|
42
44
|
|
43
45
|
def tbs_certificate_der
|
@@ -104,7 +106,7 @@ module Sigstore
|
|
104
106
|
|
105
107
|
key_usage = extension(Extension::KeyUsage) ||
|
106
108
|
raise(Error::InvalidCertificate,
|
107
|
-
"no keyUsage in #{
|
109
|
+
"no keyUsage in #{openssl.extensions.map(&:to_h)}")
|
108
110
|
|
109
111
|
unless key_usage.digital_signature
|
110
112
|
raise Error::InvalidCertificate,
|
data/lib/sigstore/models.rb
CHANGED
@@ -80,6 +80,12 @@ module Sigstore
|
|
80
80
|
|
81
81
|
def initialize(*)
|
82
82
|
super
|
83
|
+
|
84
|
+
unless bundle.is_a?(Bundle::V1::Bundle)
|
85
|
+
raise ArgumentError,
|
86
|
+
"bundle must be a #{Bundle::V1::Bundle}, is #{bundle.class}"
|
87
|
+
end
|
88
|
+
|
83
89
|
@trusted_root = TrustedRoot.new(artifact_trust_root)
|
84
90
|
@sbundle = SBundle.new(bundle)
|
85
91
|
if sbundle.message_signature? && !artifact
|
@@ -138,13 +144,19 @@ module Sigstore
|
|
138
144
|
expected_hashed_rekord_tlog_entry(hashed_input)
|
139
145
|
when :dsse_envelope
|
140
146
|
rekor_entry = verification_material.tlog_entries.first
|
141
|
-
|
147
|
+
canonicalized_body = begin
|
148
|
+
JSON.parse(rekor_entry.canonicalized_body)
|
149
|
+
rescue JSON::ParserError
|
150
|
+
raise Error::InvalidBundle, "expected canonicalized_body to be JSON"
|
151
|
+
end
|
152
|
+
|
153
|
+
case kind_version = canonicalized_body.values_at("kind", "apiVersion")
|
142
154
|
when %w[dsse 0.0.1]
|
143
155
|
expected_dsse_0_0_1_tlog_entry
|
144
156
|
when %w[intoto 0.0.2]
|
145
157
|
expected_intoto_0_0_2_tlog_entry
|
146
158
|
else
|
147
|
-
raise Error::InvalidRekorEntry, "Unhandled rekor entry kind/version: #{
|
159
|
+
raise Error::InvalidRekorEntry, "Unhandled rekor entry kind/version: #{kind_version.inspect}"
|
148
160
|
end
|
149
161
|
else
|
150
162
|
raise Error::InvalidBundle, "expected either message_signature or dsse_envelope"
|
@@ -154,6 +166,8 @@ module Sigstore
|
|
154
166
|
private
|
155
167
|
|
156
168
|
def validate_version!
|
169
|
+
raise Error::InvalidBundle, "bundle requires verification material" unless verification_material
|
170
|
+
|
157
171
|
case bundle_type
|
158
172
|
when BundleType::BUNDLE_0_1
|
159
173
|
unless verification_material.tlog_entries.all?(&:inclusion_promise)
|
@@ -169,7 +183,7 @@ module Sigstore
|
|
169
183
|
raise Error::InvalidBundle,
|
170
184
|
"must contain an inclusion proof"
|
171
185
|
end
|
172
|
-
unless verification_material.tlog_entries.all? { |t| t.inclusion_proof.checkpoint
|
186
|
+
unless verification_material.tlog_entries.all? { |t| t.inclusion_proof.checkpoint&.envelope }
|
173
187
|
raise Error::InvalidBundle,
|
174
188
|
"inclusion proof must contain a checkpoint"
|
175
189
|
end
|
@@ -192,9 +206,9 @@ module Sigstore
|
|
192
206
|
when :certificate
|
193
207
|
@leaf_certificate = Internal::X509::Certificate.read(verification_material.certificate.raw_bytes)
|
194
208
|
else
|
195
|
-
raise Error::InvalidBundle, "Unsupported bundle content: #{content}"
|
209
|
+
raise Error::InvalidBundle, "Unsupported bundle content: #{content.inspect}"
|
196
210
|
end
|
197
|
-
raise Error::InvalidBundle, "
|
211
|
+
raise Error::InvalidBundle, "expected certificate to be leaf" unless @leaf_certificate.leaf?
|
198
212
|
end
|
199
213
|
|
200
214
|
def expected_hashed_rekord_tlog_entry(hashed_input)
|
data/lib/sigstore/policy.rb
CHANGED
@@ -51,14 +51,16 @@ module Sigstore
|
|
51
51
|
OID = "1.3.6.1.4.1.57264.1.1"
|
52
52
|
end
|
53
53
|
|
54
|
-
class
|
55
|
-
OID = "1.3.6.1.4.1.57264.1.8"
|
56
|
-
|
54
|
+
class SingleX509ExtDerEncodedPolicy < SingleX509ExtPolicy
|
57
55
|
def ext_value(ext)
|
58
56
|
OpenSSL::ASN1.decode(ext.value_der).value
|
59
57
|
end
|
60
58
|
end
|
61
59
|
|
60
|
+
class OIDCIssuerV2 < SingleX509ExtDerEncodedPolicy
|
61
|
+
OID = "1.3.6.1.4.1.57264.1.8"
|
62
|
+
end
|
63
|
+
|
62
64
|
class AnyOf
|
63
65
|
def initialize(*policies)
|
64
66
|
@policies = policies
|
data/lib/sigstore/signer.rb
CHANGED
@@ -97,9 +97,9 @@ module Sigstore
|
|
97
97
|
|
98
98
|
{
|
99
99
|
credentials: {
|
100
|
-
|
100
|
+
oidcIdentityToken: @identity_token.raw_token
|
101
101
|
},
|
102
|
-
|
102
|
+
certificateSigningRequest: Internal::Util.base64_encode(csr.to_pem)
|
103
103
|
}
|
104
104
|
end
|
105
105
|
|
data/lib/sigstore/tuf/updater.rb
CHANGED
data/lib/sigstore/tuf.rb
CHANGED
data/lib/sigstore/verifier.rb
CHANGED
@@ -118,7 +118,7 @@ module Sigstore
|
|
118
118
|
|
119
119
|
unless store_ctx.verify
|
120
120
|
return VerificationFailure.new(
|
121
|
-
"failed to validate
|
121
|
+
"failed to validate certificate from fulcio cert chain: #{store_ctx.error_string}"
|
122
122
|
)
|
123
123
|
end
|
124
124
|
|
@@ -183,7 +183,12 @@ module Sigstore
|
|
183
183
|
|
184
184
|
case bundle.dsse_envelope.payloadType
|
185
185
|
when "application/vnd.in-toto+json"
|
186
|
-
|
186
|
+
in_toto = begin
|
187
|
+
JSON.parse(bundle.dsse_envelope.payload)
|
188
|
+
rescue JSON::ParserError
|
189
|
+
raise Error::InvalidBundle, "invalid JSON for in-toto statement in DSSE payload"
|
190
|
+
end
|
191
|
+
verify_in_toto(input, in_toto)
|
187
192
|
else
|
188
193
|
raise Sigstore::Error::Unimplemented,
|
189
194
|
"unsupported DSSE payload type: #{bundle.dsse_envelope.payloadType.inspect}"
|
@@ -432,7 +437,11 @@ module Sigstore
|
|
432
437
|
|
433
438
|
logger.debug { "Found rekor entry: #{entry}" }
|
434
439
|
|
435
|
-
actual_body =
|
440
|
+
actual_body = begin
|
441
|
+
JSON.parse(entry.canonicalized_body)
|
442
|
+
rescue JSON::ParserError
|
443
|
+
raise Error::InvalidRekorEntry, "invalid JSON in rekor entry canonicalized_body"
|
444
|
+
end
|
436
445
|
if bundle.dsse_envelope?
|
437
446
|
# since the hash is over the uncanonicalized envelope, we need to remove it
|
438
447
|
#
|
data/lib/sigstore/version.rb
CHANGED
data/lib/sigstore.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sigstore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The Sigstore Authors
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-11-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: net-http
|
@@ -121,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
121
|
- !ruby/object:Gem::Version
|
122
122
|
version: '0'
|
123
123
|
requirements: []
|
124
|
-
rubygems_version: 3.5.
|
124
|
+
rubygems_version: 3.5.22
|
125
125
|
signing_key:
|
126
126
|
specification_version: 4
|
127
127
|
summary: A pure-ruby implementation of sigstore signature verification
|