Skip to content

Commit 7fd0ecc

Browse files
Mikhail Swiftcolek42
authored andcommitted
fix: verification of attestations from rekor
Few different issues here * Intermediates from rekor need to be base64 decoded before using them. * Trusted time stamps were only being considered while parsing entries from rekor but not while verifying envelopes in witness.Verify. To get around this I added an option to attach a trusted time to a specific DSSE signature which makes sure this gets used when verifying the envelopes. Signed-off-by: Mikhail Swift <mikhail@testifysec.com>
1 parent 75f7868 commit 7fd0ecc

3 files changed

Lines changed: 52 additions & 15 deletions

File tree

pkg/cryptoutil/x509.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func (v *X509Verifier) BelongsToRoot(root *x509.Certificate) error {
6868
_, err := v.cert.Verify(x509.VerifyOptions{
6969
Roots: rootPool,
7070
Intermediates: intermediatePool,
71+
CurrentTime: v.trustedTime,
7172
})
7273

7374
return err

pkg/dsse/dsse.go

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ type Signature struct {
5050
Signature []byte `json:"sig"`
5151
Certificate []byte `json:"certificate,omitempty"`
5252
Intermediates [][]byte `json:"intermediates,omitempty"`
53+
54+
trustedTime time.Time
5355
}
5456

5557
// preauthEncode wraps the data to be signed or verified and it's type in the DSSE protocol's
@@ -112,7 +114,6 @@ type verificationOptions struct {
112114
roots []*x509.Certificate
113115
intermediates []*x509.Certificate
114116
verifiers []cryptoutil.Verifier
115-
trustedTime time.Time
116117
}
117118

118119
func WithRoots(roots []*x509.Certificate) VerificationOption {
@@ -133,12 +134,6 @@ func WithVerifiers(verifiers []cryptoutil.Verifier) VerificationOption {
133134
}
134135
}
135136

136-
func WithTrustedTime(time time.Time) VerificationOption {
137-
return func(vo *verificationOptions) {
138-
vo.trustedTime = time
139-
}
140-
}
141-
142137
func (e Envelope) Verify(opts ...VerificationOption) ([]cryptoutil.Verifier, error) {
143138
options := &verificationOptions{}
144139
for _, opt := range opts {
@@ -170,7 +165,7 @@ func (e Envelope) Verify(opts ...VerificationOption) ([]cryptoutil.Verifier, err
170165
}
171166

172167
sigIntermediates = append(sigIntermediates, options.intermediates...)
173-
verifier, err := cryptoutil.NewX509Verifier(cert, sigIntermediates, options.roots, options.trustedTime)
168+
verifier, err := cryptoutil.NewX509Verifier(cert, sigIntermediates, options.roots, sig.trustedTime)
174169
if err != nil {
175170
return nil, err
176171
}
@@ -213,3 +208,42 @@ func TryParseCertificate(data []byte) (*x509.Certificate, error) {
213208

214209
return cert, nil
215210
}
211+
212+
type SignatureOption func(so *signatureOptions)
213+
214+
type signatureOptions struct {
215+
cert []byte
216+
intermediates [][]byte
217+
trustedTime time.Time
218+
}
219+
220+
func SignatureWithCertificate(certBytes []byte) SignatureOption {
221+
return func(so *signatureOptions) {
222+
so.cert = certBytes
223+
}
224+
}
225+
226+
func SignatureWithIntermediates(intermediates [][]byte) SignatureOption {
227+
return func(so *signatureOptions) {
228+
so.intermediates = intermediates
229+
}
230+
}
231+
func SignatureWithTrustedTime(trustedTime time.Time) SignatureOption {
232+
return func(so *signatureOptions) {
233+
so.trustedTime = trustedTime
234+
}
235+
}
236+
func NewSignature(keyID string, sig []byte, opts ...SignatureOption) Signature {
237+
so := signatureOptions{}
238+
for _, opt := range opts {
239+
opt(&so)
240+
}
241+
242+
return Signature{
243+
KeyID: keyID,
244+
Signature: sig,
245+
Certificate: so.cert,
246+
Intermediates: so.intermediates,
247+
trustedTime: so.trustedTime,
248+
}
249+
}

pkg/rekor/rekor.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,21 +161,23 @@ func ParseEnvelopeFromEntry(entry *models.LogEntryAnon) (dsse.Envelope, error) {
161161
return env, fmt.Errorf("failed to decode signature: %w", err)
162162
}
163163

164-
verifier, err := cryptoutil.NewVerifierFromReader(bytes.NewReader(sig.PublicKey), cryptoutil.VerifyWithTrustedTime(time.Unix(*entry.IntegratedTime, 0)))
164+
trustedTime := time.Unix(*entry.IntegratedTime, 0)
165+
verifier, err := cryptoutil.NewVerifierFromReader(bytes.NewReader(sig.PublicKey), cryptoutil.VerifyWithTrustedTime(trustedTime))
165166
if err != nil {
166167
return env, fmt.Errorf("failed to create verifier from public key on rekor entry: %w", err)
167168
}
168169

169-
envSig := dsse.Signature{
170-
Signature: decodedSig,
171-
KeyID: sig.Keyid,
172-
}
173-
170+
envSig := dsse.NewSignature(sig.Keyid, decodedSig, dsse.SignatureWithTrustedTime(trustedTime))
174171
_, ok := verifier.(*cryptoutil.X509Verifier)
175172
if ok {
176173
envSig.Certificate = sig.PublicKey
177174
for _, intermediate := range sig.Intermediates {
178-
envSig.Intermediates = append(envSig.Intermediates, intermediate)
175+
decoded, err := base64.StdEncoding.DecodeString(string(intermediate))
176+
if err != nil {
177+
continue
178+
}
179+
180+
envSig.Intermediates = append(envSig.Intermediates, decoded)
179181
}
180182
}
181183

0 commit comments

Comments
 (0)