* fix: standardize casing of initialisms * fix: rename intoto -> inToto and Intoto to InToto * fix: fix all linting errors
78 lines
2.2 KiB
Go
78 lines
2.2 KiB
Go
package attestation
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/docker/attest/internal/util"
|
|
"github.com/docker/attest/pkg/tlog"
|
|
intoto "github.com/in-toto/in-toto-golang/in_toto"
|
|
"github.com/secure-systems-lab/go-securesystemslib/dsse"
|
|
)
|
|
|
|
// SignDSSE signs a payload with a given signer and uploads the signature to the transparency log.
|
|
func SignDSSE(ctx context.Context, payload []byte, signer dsse.SignerVerifier, opts *SigningOptions) (*Envelope, error) {
|
|
payloadType := intoto.PayloadType
|
|
env := new(Envelope)
|
|
env.Payload = base64Encoding.EncodeToString(payload)
|
|
env.PayloadType = payloadType
|
|
encPayload := dsse.PAE(payloadType, payload)
|
|
|
|
// statement message digest
|
|
hash := util.SHA256(encPayload)
|
|
|
|
// sign message digest
|
|
sig, err := signer.Sign(ctx, hash)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error signing attestation: %w", err)
|
|
}
|
|
|
|
// get Key ID from signer
|
|
keyID, err := signer.KeyID()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting public key ID: %w", err)
|
|
}
|
|
|
|
dsseSig := &Signature{
|
|
KeyID: keyID,
|
|
Sig: base64Encoding.EncodeToString(sig),
|
|
}
|
|
if !opts.SkipTL {
|
|
ext, err := logSignature(ctx, tlog.GetTL(ctx), &sig, &encPayload, signer)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to log to rekor: %w", err)
|
|
}
|
|
dsseSig.Extension = ext
|
|
}
|
|
// add signature to dsse envelope
|
|
env.Signatures = []*Signature{dsseSig}
|
|
|
|
return env, nil
|
|
}
|
|
|
|
// returns a new envelope with the transparency log entry added to the signature extension.
|
|
func logSignature(ctx context.Context, t tlog.TL, sig *[]byte, encPayload *[]byte, signer dsse.SignerVerifier) (*Extension, error) {
|
|
// get Key ID from signer
|
|
keyID, err := signer.KeyID()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error getting public key ID: %w", err)
|
|
}
|
|
entry, err := t.UploadLogEntry(ctx, keyID, *encPayload, *sig, signer)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error uploading TL entry: %w", err)
|
|
}
|
|
entryObj, err := t.UnmarshalEntry(entry)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error unmarshaling tl entry: %w", err)
|
|
}
|
|
return &Extension{
|
|
Kind: DockerDSSEExtKind,
|
|
Ext: &DockerDSSEExtension{
|
|
TL: &DockerTLExtension{
|
|
Kind: RekorTLExtKind,
|
|
Data: entryObj, // transparency log entry metadata
|
|
},
|
|
},
|
|
}, nil
|
|
}
|