Files
attest/tlog/tl.go

89 lines
2.7 KiB
Go
Raw Normal View History

2024-10-17 13:40:17 -05:00
/*
Copyright Docker attest authors
2024-10-17 13:40:17 -05:00
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
2024-04-19 09:08:31 -05:00
package tlog
import (
"context"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"fmt"
"math/big"
"time"
"github.com/docker/attest/signerverifier"
2024-04-19 09:08:31 -05:00
"github.com/secure-systems-lab/go-securesystemslib/dsse"
)
const (
DefaultRekorURL = "https://rekor.sigstore.dev"
)
type TransparencyLog interface {
UploadEntry(ctx context.Context, subject string, payload, signature []byte, signer dsse.SignerVerifier) (*DockerTLExtension, error)
VerifyEntry(ctx context.Context, entry *DockerTLExtension, payload, publicKey []byte) (time.Time, error)
2024-04-19 09:08:31 -05:00
}
type Payload struct {
2024-04-19 09:08:31 -05:00
Algorithm string
Hash string
Signature string
PublicKey string
}
type DockerTLExtension struct {
Kind string `json:"kind"`
Data any `json:"data"`
2024-04-19 09:08:31 -05:00
}
// CreateX509Cert generates a self-signed x509 cert for TL submission.
2024-04-19 09:08:31 -05:00
func CreateX509Cert(subject string, signer dsse.SignerVerifier) ([]byte, error) {
// encode ephemeral public key
ecPub, err := x509.MarshalPKIXPublicKey(signer.Public())
if err != nil {
return nil, fmt.Errorf("error marshaling public key: %w", err)
2024-04-19 09:08:31 -05:00
}
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: subject},
RawSubjectPublicKeyInfo: ecPub,
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour), // valid for 1 year
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageCodeSigning},
BasicConstraintsValid: true,
DNSNames: []string{subject},
IsCA: false,
}
// dsse.SignerVerifier doesn't implement cypto.Signer exactly
csigner, err := signerverifier.AsCryptoSigner(signer)
if err != nil {
return nil, fmt.Errorf("error converting signer to crypto.Signer: %w", err)
2024-04-19 09:08:31 -05:00
}
// create a self-signed X.509 certificate
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, signer.Public(), csigner)
2024-04-19 09:08:31 -05:00
if err != nil {
return nil, fmt.Errorf("error creating X.509 certificate: %w", err)
}
certBlock := &pem.Block{Type: "CERTIFICATE", Bytes: certDER}
return pem.EncodeToMemory(certBlock), nil
}