Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač
2024-05-09 21:49:41 +02:00
parent dcf937e170
commit 7649059a0d
474 changed files with 30496 additions and 30923 deletions

View File

@@ -338,7 +338,7 @@ func (e Extensions) Render() ([]pkix.Extension, error) {
return exts, nil
}
func parseExtensions(ext []pkix.Extension) (Extensions, error) {
func ParseExtensions(ext []pkix.Extension) (Extensions, error) {
out := Extensions{}
for _, e := range ext {

View File

@@ -39,8 +39,7 @@ import (
type CoseV001Schema struct {
// data
// Required: true
Data *CoseV001SchemaData `json:"data"`
Data *CoseV001SchemaData `json:"data,omitempty"`
// The COSE Sign1 Message
// Format: byte
@@ -71,9 +70,8 @@ func (m *CoseV001Schema) Validate(formats strfmt.Registry) error {
}
func (m *CoseV001Schema) validateData(formats strfmt.Registry) error {
if err := validate.Required("data", "body", m.Data); err != nil {
return err
if swag.IsZero(m.Data) { // not required
return nil
}
if m.Data != nil {
@@ -117,6 +115,10 @@ func (m *CoseV001Schema) contextValidateData(ctx context.Context, formats strfmt
if m.Data != nil {
if swag.IsZero(m.Data) { // not required
return nil
}
if err := m.Data.ContextValidate(ctx, formats); err != nil {
if ve, ok := err.(*errors.Validation); ok {
return ve.ValidateName("data")

View File

@@ -277,10 +277,10 @@ type HashedrekordV001SchemaDataHash struct {
// The hashing function used to compute the hash value
// Required: true
// Enum: [sha256]
// Enum: [sha256 sha384 sha512]
Algorithm *string `json:"algorithm"`
// The hash value for the content
// The hash value for the content, as represented by a lower case hexadecimal string
// Required: true
Value *string `json:"value"`
}
@@ -307,7 +307,7 @@ var hashedrekordV001SchemaDataHashTypeAlgorithmPropEnum []interface{}
func init() {
var res []string
if err := json.Unmarshal([]byte(`["sha256"]`), &res); err != nil {
if err := json.Unmarshal([]byte(`["sha256","sha384","sha512"]`), &res); err != nil {
panic(err)
}
for _, v := range res {
@@ -319,6 +319,12 @@ const (
// HashedrekordV001SchemaDataHashAlgorithmSha256 captures enum value "sha256"
HashedrekordV001SchemaDataHashAlgorithmSha256 string = "sha256"
// HashedrekordV001SchemaDataHashAlgorithmSha384 captures enum value "sha384"
HashedrekordV001SchemaDataHashAlgorithmSha384 string = "sha384"
// HashedrekordV001SchemaDataHashAlgorithmSha512 captures enum value "sha512"
HashedrekordV001SchemaDataHashAlgorithmSha512 string = "sha512"
)
// prop value enum

View File

@@ -95,7 +95,7 @@ type LogEntryAnon struct {
// Required: true
Body interface{} `json:"body"`
// integrated time
// The time the entry was added to the log as a Unix timestamp in seconds
// Required: true
IntegratedTime *int64 `json:"integratedTime"`

View File

@@ -23,13 +23,12 @@ import (
"fmt"
"strconv"
"strings"
"time"
"github.com/sigstore/sigstore/pkg/signature"
"github.com/sigstore/sigstore/pkg/signature/options"
)
// heavily borrowed from https://github.com/google/trillian-examples/blob/master/formats/log/checkpoint.go
// heavily borrowed from https://github.com/transparency-dev/formats/blob/main/log/checkpoint.go
type Checkpoint struct {
// Origin is the unique identifier/version string
@@ -145,27 +144,6 @@ func (r *SignedCheckpoint) UnmarshalText(data []byte) error {
return nil
}
func (r *SignedCheckpoint) SetTimestamp(timestamp uint64) {
var ts uint64
for i, val := range r.OtherContent {
if n, _ := fmt.Fscanf(strings.NewReader(val), "Timestamp: %d", &ts); n == 1 {
r.OtherContent = append(r.OtherContent[:i], r.OtherContent[i+1:]...)
}
}
r.OtherContent = append(r.OtherContent, fmt.Sprintf("Timestamp: %d", timestamp))
r.SignedNote = SignedNote{Note: string(r.Checkpoint.String())}
}
func (r *SignedCheckpoint) GetTimestamp() uint64 {
var ts uint64
for _, val := range r.OtherContent {
if n, _ := fmt.Fscanf(strings.NewReader(val), "Timestamp: %d", &ts); n == 1 {
break
}
}
return ts
}
// CreateAndSignCheckpoint creates a signed checkpoint as a commitment to the current root hash
func CreateAndSignCheckpoint(ctx context.Context, hostname string, treeID int64, treeSize uint64, rootHash []byte, signer signature.Signer) ([]byte, error) {
sth, err := CreateSignedCheckpoint(Checkpoint{
@@ -174,15 +152,14 @@ func CreateAndSignCheckpoint(ctx context.Context, hostname string, treeID int64,
Hash: rootHash,
})
if err != nil {
return nil, fmt.Errorf("error creating checkpoint: %v", err)
return nil, fmt.Errorf("error creating checkpoint: %w", err)
}
sth.SetTimestamp(uint64(time.Now().UnixNano()))
if _, err := sth.Sign(hostname, signer, options.WithContext(ctx)); err != nil {
return nil, fmt.Errorf("error signing checkpoint: %v", err)
return nil, fmt.Errorf("error signing checkpoint: %w", err)
}
scBytes, err := sth.SignedNote.MarshalText()
if err != nil {
return nil, fmt.Errorf("error marshalling checkpoint: %v", err)
return nil, fmt.Errorf("error marshalling checkpoint: %w", err)
}
return scBytes, nil
}

View File

@@ -15,6 +15,7 @@
package util
import (
"crypto"
"fmt"
"strings"
)
@@ -33,9 +34,46 @@ func PrefixSHA(sha string) string {
prefix = "sha1:"
case 64:
prefix = "sha256:"
case 96:
prefix = "sha384:"
case 128:
prefix = "sha512:"
}
return fmt.Sprintf("%v%v", prefix, sha)
}
func UnprefixSHA(sha string) (crypto.Hash, string) {
components := strings.Split(sha, ":")
if len(components) == 2 {
prefix := components[0]
sha = components[1]
switch prefix {
case "sha1":
return crypto.SHA1, sha
case "sha256":
return crypto.SHA256, sha
case "sha384":
return crypto.SHA384, sha
case "sha512":
return crypto.SHA512, sha
default:
return crypto.Hash(0), ""
}
}
switch len(sha) {
case 40:
return crypto.SHA1, sha
case 64:
return crypto.SHA256, sha
case 96:
return crypto.SHA384, sha
case 128:
return crypto.SHA512, sha
}
return crypto.Hash(0), ""
}

View File

@@ -20,9 +20,11 @@ import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"encoding/asn1"
"errors"
"fmt"
"io"
"math/big"
"github.com/sigstore/sigstore/pkg/signature/options"
)
@@ -190,8 +192,23 @@ func (e ECDSAVerifier) VerifySignature(signature, message io.Reader, opts ...Ver
return fmt.Errorf("invalid ECDSA public key for %s", e.publicKey.Params().Name)
}
if !ecdsa.VerifyASN1(e.publicKey, digest, sigBytes) {
return errors.New("invalid signature when validating ASN.1 encoded signature")
asnParseTest := struct {
R, S *big.Int
}{}
if _, err := asn1.Unmarshal(sigBytes, &asnParseTest); err == nil {
if !ecdsa.VerifyASN1(e.publicKey, digest, sigBytes) {
return errors.New("invalid signature when validating ASN.1 encoded signature")
}
} else {
// deal with IEEE P1363 encoding of signatures
if len(sigBytes) == 0 || len(sigBytes) > 132 || len(sigBytes)%2 != 0 {
return errors.New("ecdsa: Invalid IEEE_P1363 encoded bytes")
}
r := new(big.Int).SetBytes(sigBytes[:len(sigBytes)/2])
s := new(big.Int).SetBytes(sigBytes[len(sigBytes)/2:])
if !ecdsa.Verify(e.publicKey, digest, r, s) {
return errors.New("invalid signature when validating IEEE_P1363 encoded signature")
}
}
return nil