generated from sigstore/sigstore-project-template
-
Notifications
You must be signed in to change notification settings - Fork 58
/
oid.go
123 lines (112 loc) · 4.03 KB
/
oid.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2023 The Sigstore Authors
//
// 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.
package oid
import (
"context"
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"encoding/base64"
"encoding/hex"
"fmt"
"github.com/github/smimesign/ietf-cms/protocol"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
rekorpb "github.com/sigstore/protobuf-specs/gen/pb-go/rekor/v1"
"github.com/sigstore/rekor/pkg/generated/models"
"github.com/sigstore/rekor/pkg/types"
"github.com/sigstore/rekor/pkg/types/hashedrekord"
hashedrekord_v001 "github.com/sigstore/rekor/pkg/types/hashedrekord/v0.0.1"
"github.com/sigstore/sigstore/pkg/cryptoutils"
"google.golang.org/protobuf/proto"
)
var (
// OIDRekorTransparencyLogEntry is the OID for a serialized Rekor TransparencyLogEntry proto.
// See https://github.com/sigstore/rekor/pull/1390
OIDRekorTransparencyLogEntry = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 57264, 3, 1}
)
// ToLogEntry reconstructs a Rekor HashedRekord from Git commit signature PKCS7 components.
func ToLogEntry(ctx context.Context, message []byte, sig []byte, cert *x509.Certificate, attrs protocol.Attributes) (*models.LogEntryAnon, error) {
var b []byte
if err := unmarshalAttribute(attrs, OIDRekorTransparencyLogEntry, &b); err != nil {
return nil, fmt.Errorf("error unmarshalling attribute: %w", err)
}
pb := new(rekorpb.TransparencyLogEntry)
if err := proto.Unmarshal(b, pb); err != nil {
return nil, fmt.Errorf("error unmarshalling TransparencyLogEntry attribute: %w", err)
}
out := logEntryAnonFromProto(pb)
// Recompute HashedRekord body.
hash := sha256.Sum256(message)
certPEM, err := cryptoutils.MarshalCertificateToPEM(cert)
if err != nil {
return nil, fmt.Errorf("error marshalling cert: %w", err)
}
re := &hashedrekord_v001.V001Entry{
HashedRekordObj: models.HashedrekordV001Schema{
Data: &models.HashedrekordV001SchemaData{
Hash: &models.HashedrekordV001SchemaDataHash{
Algorithm: swag.String("sha256"),
Value: swag.String(hex.EncodeToString(hash[:])),
},
},
Signature: &models.HashedrekordV001SchemaSignature{
Content: strfmt.Base64(sig),
PublicKey: &models.HashedrekordV001SchemaSignaturePublicKey{
Content: strfmt.Base64(certPEM),
},
},
},
}
body, err := types.CanonicalizeEntry(ctx, re)
if err != nil {
return nil, fmt.Errorf("error canonicalizing entry: %w", err)
}
out.Body = base64.StdEncoding.EncodeToString(body)
return out, nil
}
func unmarshalAttribute(attrs protocol.Attributes, oid asn1.ObjectIdentifier, target any) error {
rv, err := attrs.GetOnlyAttributeValueBytes(oid)
if err != nil {
return fmt.Errorf("get oid: %w", err)
}
if _, err := asn1.Unmarshal(rv.FullBytes, target); err != nil {
return fmt.Errorf("asn1.unmarshal(%v): %w", oid, err)
}
return nil
}
// ToAttributes takes a Rekor log entry and extracts fields into Attributes suitable to be included in the signature's
// unauthenticated attributes.
func ToAttributes(tlog *models.LogEntryAnon) (protocol.Attributes, error) {
pb, err := logEntryAnonToProto(tlog, &rekorpb.KindVersion{
Kind: hashedrekord.KIND,
Version: hashedrekord_v001.APIVERSION,
})
if err != nil {
return nil, err
}
// Clear out body - we store this data elsewhere so including is in the serialized log entry is redundant.
pb.CanonicalizedBody = nil
out, err := proto.Marshal(pb)
if err != nil {
return nil, err
}
attrs := protocol.Attributes{}
attr, err := protocol.NewAttribute(OIDRekorTransparencyLogEntry, out)
if err != nil {
return nil, err
}
attrs = append(attrs, attr)
return attrs, nil
}