vendor: update buildkit to v0.28.0-rc1
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
+193
-13
@@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -96,6 +97,123 @@ func (s *SourceOp) Inputs() []Output {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ImageBlobInfo struct {
|
||||
constraintsWrapper
|
||||
fileinfoWrapper
|
||||
sessionID string
|
||||
storeID string
|
||||
}
|
||||
|
||||
type ImageBlobOption interface {
|
||||
SetImageBlobOption(*ImageBlobInfo)
|
||||
}
|
||||
|
||||
type FileInfoOption interface {
|
||||
HTTPOption
|
||||
ImageBlobOption
|
||||
}
|
||||
|
||||
func ImageBlob(ref string, opts ...ImageBlobOption) State {
|
||||
bi := &ImageBlobInfo{}
|
||||
for _, o := range opts {
|
||||
o.SetImageBlobOption(bi)
|
||||
}
|
||||
attrs := map[string]string{}
|
||||
|
||||
if bi.Filename != "" {
|
||||
attrs[pb.AttrHTTPFilename] = bi.Filename
|
||||
}
|
||||
if bi.Perm != 0 {
|
||||
attrs[pb.AttrHTTPPerm] = "0" + strconv.FormatInt(int64(bi.Perm), 8)
|
||||
}
|
||||
if bi.UID != 0 {
|
||||
attrs[pb.AttrHTTPUID] = strconv.Itoa(bi.UID)
|
||||
}
|
||||
if bi.GID != 0 {
|
||||
attrs[pb.AttrHTTPGID] = strconv.Itoa(bi.GID)
|
||||
}
|
||||
|
||||
addCap(&bi.Constraints, pb.CapSourceImageBlob)
|
||||
|
||||
var digested reference.Digested
|
||||
|
||||
r, err := reference.ParseNormalizedNamed(ref)
|
||||
if err == nil {
|
||||
if _, tagged := r.(reference.Tagged); tagged {
|
||||
err = errors.Errorf("tagged image reference not allowed for blob reference")
|
||||
} else if ref, ok := r.(reference.Digested); !ok {
|
||||
err = errors.Errorf("checksum required in blob reference")
|
||||
} else {
|
||||
digested = ref
|
||||
}
|
||||
}
|
||||
|
||||
repoName := "invalid"
|
||||
if digested != nil {
|
||||
repoName = digested.String()
|
||||
}
|
||||
|
||||
source := NewSource("docker-image+blob://"+repoName, attrs, bi.Constraints)
|
||||
if err != nil {
|
||||
source.err = err
|
||||
}
|
||||
return NewState(source.Output())
|
||||
}
|
||||
|
||||
// OCILayoutBlob returns a state that represents a single digest-addressed blob from an OCI layout store.
|
||||
func OCILayoutBlob(ref string, opts ...ImageBlobOption) State {
|
||||
bi := &ImageBlobInfo{}
|
||||
for _, o := range opts {
|
||||
o.SetImageBlobOption(bi)
|
||||
}
|
||||
attrs := map[string]string{}
|
||||
|
||||
if bi.Filename != "" {
|
||||
attrs[pb.AttrHTTPFilename] = bi.Filename
|
||||
}
|
||||
if bi.Perm != 0 {
|
||||
attrs[pb.AttrHTTPPerm] = "0" + strconv.FormatInt(int64(bi.Perm), 8)
|
||||
}
|
||||
if bi.UID != 0 {
|
||||
attrs[pb.AttrHTTPUID] = strconv.Itoa(bi.UID)
|
||||
}
|
||||
if bi.GID != 0 {
|
||||
attrs[pb.AttrHTTPGID] = strconv.Itoa(bi.GID)
|
||||
}
|
||||
if bi.sessionID != "" {
|
||||
attrs[pb.AttrOCILayoutSessionID] = bi.sessionID
|
||||
}
|
||||
if bi.storeID != "" {
|
||||
attrs[pb.AttrOCILayoutStoreID] = bi.storeID
|
||||
}
|
||||
|
||||
addCap(&bi.Constraints, pb.CapSourceImageBlob)
|
||||
|
||||
var digested reference.Digested
|
||||
|
||||
r, err := reference.ParseNormalizedNamed(ref)
|
||||
if err == nil {
|
||||
if _, tagged := r.(reference.Tagged); tagged {
|
||||
err = errors.Errorf("tagged image reference not allowed for blob reference")
|
||||
} else if ref, ok := r.(reference.Digested); !ok {
|
||||
err = errors.Errorf("checksum required in blob reference")
|
||||
} else {
|
||||
digested = ref
|
||||
}
|
||||
}
|
||||
|
||||
repoName := "invalid"
|
||||
if digested != nil {
|
||||
repoName = digested.String()
|
||||
}
|
||||
|
||||
source := NewSource("oci-layout+blob://"+repoName, attrs, bi.Constraints)
|
||||
if err != nil {
|
||||
source.err = err
|
||||
}
|
||||
return NewState(source.Output())
|
||||
}
|
||||
|
||||
// Image returns a state that represents a docker image in a registry.
|
||||
// Example:
|
||||
//
|
||||
@@ -197,6 +315,12 @@ func (fn imageOptionFunc) SetImageOption(ii *ImageInfo) {
|
||||
fn(ii)
|
||||
}
|
||||
|
||||
type imageBlobOptionFunc func(*ImageBlobInfo)
|
||||
|
||||
func (fn imageBlobOptionFunc) SetImageBlobOption(ib *ImageBlobInfo) {
|
||||
fn(ib)
|
||||
}
|
||||
|
||||
var MarkImageInternal = imageOptionFunc(func(ii *ImageInfo) {
|
||||
ii.RecordType = "internal"
|
||||
})
|
||||
@@ -623,6 +747,14 @@ func OCIStore(sessionID string, storeID string) OCILayoutOption {
|
||||
})
|
||||
}
|
||||
|
||||
// ImageBlobOCIStore returns an [ImageBlobOption] that configures the OCI layout session/store used by [OCILayoutBlob].
|
||||
func ImageBlobOCIStore(sessionID string, storeID string) ImageBlobOption {
|
||||
return imageBlobOptionFunc(func(ib *ImageBlobInfo) {
|
||||
ib.sessionID = sessionID
|
||||
ib.storeID = storeID
|
||||
})
|
||||
}
|
||||
|
||||
func OCILayerLimit(limit int) OCILayoutOption {
|
||||
return ociLayoutOptionFunc(func(oi *OCILayoutInfo) {
|
||||
oi.layerLimit = &limit
|
||||
@@ -705,21 +837,58 @@ func HTTP(url string, opts ...HTTPOption) State {
|
||||
hi.Header.setAttrs(attrs)
|
||||
addCap(&hi.Constraints, pb.CapSourceHTTPHeader)
|
||||
}
|
||||
if hi.Signature != nil {
|
||||
if len(hi.Signature.PubKey) > 0 {
|
||||
attrs[pb.AttrHTTPSignatureVerifyPubKey] = string(hi.Signature.PubKey)
|
||||
}
|
||||
if len(hi.Signature.Signature) > 0 {
|
||||
attrs[pb.AttrHTTPSignatureVerify] = string(hi.Signature.Signature)
|
||||
}
|
||||
addCap(&hi.Constraints, pb.CapSourceHTTPSignatureVerify)
|
||||
}
|
||||
|
||||
addCap(&hi.Constraints, pb.CapSourceHTTP)
|
||||
source := NewSource(url, attrs, hi.Constraints)
|
||||
return NewState(source.Output())
|
||||
}
|
||||
|
||||
type fileInfo struct {
|
||||
Filename string
|
||||
Perm int
|
||||
UID int
|
||||
GID int
|
||||
}
|
||||
|
||||
type fileinfoWrapper struct {
|
||||
fileInfo
|
||||
}
|
||||
|
||||
type fileInfoOptFunc func(f *fileInfo)
|
||||
|
||||
func (fn fileInfoOptFunc) SetHTTPOption(hi *HTTPInfo) {
|
||||
fn(&hi.fileInfo)
|
||||
}
|
||||
|
||||
func (fn fileInfoOptFunc) SetImageBlobOption(ib *ImageBlobInfo) {
|
||||
fn(&ib.fileInfo)
|
||||
}
|
||||
|
||||
// HTTPSignatureInfo configures detached-signature verification for HTTP
|
||||
// sources. The current implementation uses inline armored signatures.
|
||||
type HTTPSignatureInfo struct {
|
||||
PubKey []byte
|
||||
|
||||
// Signature is an inline detached armored OpenPGP signature.
|
||||
Signature []byte
|
||||
}
|
||||
|
||||
type HTTPInfo struct {
|
||||
constraintsWrapper
|
||||
fileinfoWrapper
|
||||
Checksum digest.Digest
|
||||
Filename string
|
||||
Perm int
|
||||
UID int
|
||||
GID int
|
||||
AuthHeaderSecret string
|
||||
Header *HTTPHeader
|
||||
Signature *HTTPSignatureInfo
|
||||
}
|
||||
|
||||
type HTTPOption interface {
|
||||
@@ -738,22 +907,33 @@ func Checksum(dgst digest.Digest) HTTPOption {
|
||||
})
|
||||
}
|
||||
|
||||
func Chmod(perm os.FileMode) HTTPOption {
|
||||
return httpOptionFunc(func(hi *HTTPInfo) {
|
||||
hi.Perm = int(perm) & 0777
|
||||
func Chmod(perm os.FileMode) FileInfoOption {
|
||||
return fileInfoOptFunc(func(fi *fileInfo) {
|
||||
fi.Perm = int(perm) & 0777
|
||||
})
|
||||
}
|
||||
|
||||
func Filename(name string) HTTPOption {
|
||||
return httpOptionFunc(func(hi *HTTPInfo) {
|
||||
hi.Filename = name
|
||||
func Filename(name string) FileInfoOption {
|
||||
return fileInfoOptFunc(func(fi *fileInfo) {
|
||||
fi.Filename = name
|
||||
})
|
||||
}
|
||||
|
||||
func Chown(uid, gid int) HTTPOption {
|
||||
func Chown(uid, gid int) FileInfoOption {
|
||||
return fileInfoOptFunc(func(fi *fileInfo) {
|
||||
fi.UID = uid
|
||||
fi.GID = gid
|
||||
})
|
||||
}
|
||||
|
||||
// VerifyPGPSignature returns an [HTTPOption] for detached OpenPGP signature
|
||||
// verification of the downloaded HTTP payload.
|
||||
func VerifyPGPSignature(info HTTPSignatureInfo) HTTPOption {
|
||||
return httpOptionFunc(func(hi *HTTPInfo) {
|
||||
hi.UID = uid
|
||||
hi.GID = gid
|
||||
hi.Signature = &HTTPSignatureInfo{
|
||||
PubKey: slices.Clone(info.PubKey),
|
||||
Signature: slices.Clone(info.Signature),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+27
-3
@@ -28,6 +28,7 @@ type Opt struct {
|
||||
ImageOpt *ResolveImageOpt
|
||||
OCILayoutOpt *ResolveOCILayoutOpt
|
||||
GitOpt *ResolveGitOpt
|
||||
HTTPOpt *ResolveHTTPOpt
|
||||
}
|
||||
|
||||
type MetaResponse struct {
|
||||
@@ -78,9 +79,32 @@ type ResolveGitResponse struct {
|
||||
}
|
||||
|
||||
type ResolveHTTPResponse struct {
|
||||
Digest digest.Digest
|
||||
Filename string
|
||||
LastModified *time.Time
|
||||
Digest digest.Digest
|
||||
Filename string
|
||||
LastModified *time.Time
|
||||
ChecksumResponse *ResolveHTTPChecksumResponse
|
||||
}
|
||||
|
||||
type ResolveHTTPOpt struct {
|
||||
ChecksumReq *ResolveHTTPChecksumRequest
|
||||
}
|
||||
|
||||
type ResolveHTTPChecksumAlgo int
|
||||
|
||||
const (
|
||||
ResolveHTTPChecksumAlgoSHA256 ResolveHTTPChecksumAlgo = iota
|
||||
ResolveHTTPChecksumAlgoSHA384
|
||||
ResolveHTTPChecksumAlgoSHA512
|
||||
)
|
||||
|
||||
type ResolveHTTPChecksumRequest struct {
|
||||
Algo ResolveHTTPChecksumAlgo
|
||||
Suffix []byte
|
||||
}
|
||||
|
||||
type ResolveHTTPChecksumResponse struct {
|
||||
Digest string
|
||||
Suffix []byte
|
||||
}
|
||||
|
||||
type ResolveOCILayoutOpt struct {
|
||||
|
||||
+6
@@ -526,6 +526,7 @@ type ConstraintsOpt interface {
|
||||
RunOption
|
||||
LocalOption
|
||||
HTTPOption
|
||||
ImageBlobOption
|
||||
ImageOption
|
||||
GitOption
|
||||
OCILayoutOption
|
||||
@@ -553,6 +554,10 @@ func (fn constraintsOptFunc) SetHTTPOption(hi *HTTPInfo) {
|
||||
hi.applyConstraints(fn)
|
||||
}
|
||||
|
||||
func (fn constraintsOptFunc) SetImageBlobOption(ii *ImageBlobInfo) {
|
||||
ii.applyConstraints(fn)
|
||||
}
|
||||
|
||||
func (fn constraintsOptFunc) SetImageOption(ii *ImageInfo) {
|
||||
ii.applyConstraints(fn)
|
||||
}
|
||||
@@ -736,6 +741,7 @@ var (
|
||||
LinuxS390x = Platform(ocispecs.Platform{OS: "linux", Architecture: "s390x"})
|
||||
LinuxPpc64 = Platform(ocispecs.Platform{OS: "linux", Architecture: "ppc64"})
|
||||
LinuxPpc64le = Platform(ocispecs.Platform{OS: "linux", Architecture: "ppc64le"})
|
||||
LinuxRiscv64 = Platform(ocispecs.Platform{OS: "linux", Architecture: "riscv64"})
|
||||
Darwin = Platform(ocispecs.Platform{OS: "darwin", Architecture: "amd64"})
|
||||
Windows = Platform(ocispecs.Platform{OS: "windows", Architecture: "amd64"})
|
||||
)
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ const (
|
||||
|
||||
const (
|
||||
defaultSBOMGenerator = "docker/buildkit-syft-scanner:stable-1"
|
||||
defaultSLSAVersion = string(provenancetypes.ProvenanceSLSA02)
|
||||
defaultSLSAVersion = string(provenancetypes.ProvenanceSLSA1)
|
||||
)
|
||||
|
||||
func Filter(v map[string]string) map[string]string {
|
||||
|
||||
+39
@@ -479,6 +479,9 @@ func (c *grpcClient) ResolveSourceMetadata(ctx context.Context, op *opspb.Source
|
||||
} else if v, ok := strings.CutPrefix(op.Identifier, "oci-layout://"); ok {
|
||||
ref = v
|
||||
} else {
|
||||
if opt.HTTPOpt != nil && opt.HTTPOpt.ChecksumReq != nil {
|
||||
return nil, errors.New("http checksum request requires source metadata resolver support")
|
||||
}
|
||||
return &sourceresolver.MetaResponse{Op: op}, nil
|
||||
}
|
||||
retRef, dgst, config, err := c.ResolveImageConfig(ctx, ref, opt)
|
||||
@@ -541,6 +544,18 @@ func (c *grpcClient) ResolveSourceMetadata(ctx context.Context, op *opspb.Source
|
||||
ReturnObject: opt.GitOpt.ReturnObject,
|
||||
}
|
||||
}
|
||||
if opt.HTTPOpt != nil && opt.HTTPOpt.ChecksumReq != nil {
|
||||
algo, err := toPBHTTPChecksumAlgo(opt.HTTPOpt.ChecksumReq.Algo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.HTTP = &pb.ResolveSourceHTTPRequest{
|
||||
ChecksumRequest: &pb.ChecksumRequest{
|
||||
Algo: algo,
|
||||
Suffix: slices.Clone(opt.HTTPOpt.ChecksumReq.Suffix),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := c.client.ResolveSourceMeta(ctx, req)
|
||||
if err != nil {
|
||||
@@ -576,10 +591,34 @@ func (c *grpcClient) ResolveSourceMetadata(ctx context.Context, op *opspb.Source
|
||||
tm := resp.HTTP.LastModified.AsTime()
|
||||
r.HTTP.LastModified = &tm
|
||||
}
|
||||
if resp.HTTP.ChecksumResponse != nil {
|
||||
r.HTTP.ChecksumResponse = &sourceresolver.ResolveHTTPChecksumResponse{
|
||||
Digest: resp.HTTP.ChecksumResponse.Digest,
|
||||
Suffix: slices.Clone(resp.HTTP.ChecksumResponse.Suffix),
|
||||
}
|
||||
}
|
||||
}
|
||||
if opt.HTTPOpt != nil && opt.HTTPOpt.ChecksumReq != nil {
|
||||
if resp.HTTP == nil || resp.HTTP.ChecksumResponse == nil {
|
||||
return nil, errors.New("http checksum request was sent but response did not include checksum response")
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func toPBHTTPChecksumAlgo(in sourceresolver.ResolveHTTPChecksumAlgo) (pb.ChecksumRequest_ChecksumAlgo, error) {
|
||||
switch in {
|
||||
case sourceresolver.ResolveHTTPChecksumAlgoSHA256:
|
||||
return pb.ChecksumRequest_CHECKSUM_ALGO_SHA256, nil
|
||||
case sourceresolver.ResolveHTTPChecksumAlgoSHA384:
|
||||
return pb.ChecksumRequest_CHECKSUM_ALGO_SHA384, nil
|
||||
case sourceresolver.ResolveHTTPChecksumAlgoSHA512:
|
||||
return pb.ChecksumRequest_CHECKSUM_ALGO_SHA512, nil
|
||||
default:
|
||||
return pb.ChecksumRequest_CHECKSUM_ALGO_SHA256, errors.Errorf("invalid http checksum algorithm: %d", in)
|
||||
}
|
||||
}
|
||||
|
||||
func imgResponseFromPB(resp *pb.ResolveSourceImageResponse) *sourceresolver.ResolveImageResponse {
|
||||
r := &sourceresolver.ResolveImageResponse{
|
||||
Digest: digest.Digest(resp.Digest),
|
||||
|
||||
+526
-291
File diff suppressed because it is too large
Load Diff
+21
@@ -142,6 +142,7 @@ message ResolveSourceMetaRequest {
|
||||
string ResolveMode = 4;
|
||||
ResolveSourceGitRequest Git = 5;
|
||||
ResolveSourceImageRequest Image = 6;
|
||||
ResolveSourceHTTPRequest HTTP = 7;
|
||||
repeated moby.buildkit.v1.sourcepolicy.Policy SourcePolicies = 8;
|
||||
}
|
||||
|
||||
@@ -189,6 +190,26 @@ message ResolveSourceHTTPResponse {
|
||||
string Checksum = 1;
|
||||
string Filename = 2;
|
||||
google.protobuf.Timestamp LastModified = 3;
|
||||
ChecksumResponse ChecksumResponse = 4;
|
||||
}
|
||||
|
||||
message ResolveSourceHTTPRequest {
|
||||
ChecksumRequest ChecksumRequest = 1;
|
||||
}
|
||||
|
||||
message ChecksumRequest {
|
||||
enum ChecksumAlgo {
|
||||
CHECKSUM_ALGO_SHA256 = 0;
|
||||
CHECKSUM_ALGO_SHA384 = 1;
|
||||
CHECKSUM_ALGO_SHA512 = 2;
|
||||
}
|
||||
ChecksumAlgo Algo = 1;
|
||||
bytes Suffix = 2;
|
||||
}
|
||||
|
||||
message ChecksumResponse {
|
||||
string Digest = 1;
|
||||
bytes Suffix = 2;
|
||||
}
|
||||
|
||||
message SolveRequest {
|
||||
|
||||
+724
@@ -387,6 +387,7 @@ func (m *ResolveSourceMetaRequest) CloneVT() *ResolveSourceMetaRequest {
|
||||
r.ResolveMode = m.ResolveMode
|
||||
r.Git = m.Git.CloneVT()
|
||||
r.Image = m.Image.CloneVT()
|
||||
r.HTTP = m.HTTP.CloneVT()
|
||||
if rhs := m.SourcePolicies; rhs != nil {
|
||||
tmpContainer := make([]*pb1.Policy, len(rhs))
|
||||
for k, v := range rhs {
|
||||
@@ -556,6 +557,7 @@ func (m *ResolveSourceHTTPResponse) CloneVT() *ResolveSourceHTTPResponse {
|
||||
r.Checksum = m.Checksum
|
||||
r.Filename = m.Filename
|
||||
r.LastModified = (*timestamp.Timestamp)((*timestamppb.Timestamp)(m.LastModified).CloneVT())
|
||||
r.ChecksumResponse = m.ChecksumResponse.CloneVT()
|
||||
if len(m.unknownFields) > 0 {
|
||||
r.unknownFields = make([]byte, len(m.unknownFields))
|
||||
copy(r.unknownFields, m.unknownFields)
|
||||
@@ -567,6 +569,67 @@ func (m *ResolveSourceHTTPResponse) CloneMessageVT() proto.Message {
|
||||
return m.CloneVT()
|
||||
}
|
||||
|
||||
func (m *ResolveSourceHTTPRequest) CloneVT() *ResolveSourceHTTPRequest {
|
||||
if m == nil {
|
||||
return (*ResolveSourceHTTPRequest)(nil)
|
||||
}
|
||||
r := new(ResolveSourceHTTPRequest)
|
||||
r.ChecksumRequest = m.ChecksumRequest.CloneVT()
|
||||
if len(m.unknownFields) > 0 {
|
||||
r.unknownFields = make([]byte, len(m.unknownFields))
|
||||
copy(r.unknownFields, m.unknownFields)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (m *ResolveSourceHTTPRequest) CloneMessageVT() proto.Message {
|
||||
return m.CloneVT()
|
||||
}
|
||||
|
||||
func (m *ChecksumRequest) CloneVT() *ChecksumRequest {
|
||||
if m == nil {
|
||||
return (*ChecksumRequest)(nil)
|
||||
}
|
||||
r := new(ChecksumRequest)
|
||||
r.Algo = m.Algo
|
||||
if rhs := m.Suffix; rhs != nil {
|
||||
tmpBytes := make([]byte, len(rhs))
|
||||
copy(tmpBytes, rhs)
|
||||
r.Suffix = tmpBytes
|
||||
}
|
||||
if len(m.unknownFields) > 0 {
|
||||
r.unknownFields = make([]byte, len(m.unknownFields))
|
||||
copy(r.unknownFields, m.unknownFields)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (m *ChecksumRequest) CloneMessageVT() proto.Message {
|
||||
return m.CloneVT()
|
||||
}
|
||||
|
||||
func (m *ChecksumResponse) CloneVT() *ChecksumResponse {
|
||||
if m == nil {
|
||||
return (*ChecksumResponse)(nil)
|
||||
}
|
||||
r := new(ChecksumResponse)
|
||||
r.Digest = m.Digest
|
||||
if rhs := m.Suffix; rhs != nil {
|
||||
tmpBytes := make([]byte, len(rhs))
|
||||
copy(tmpBytes, rhs)
|
||||
r.Suffix = tmpBytes
|
||||
}
|
||||
if len(m.unknownFields) > 0 {
|
||||
r.unknownFields = make([]byte, len(m.unknownFields))
|
||||
copy(r.unknownFields, m.unknownFields)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (m *ChecksumResponse) CloneMessageVT() proto.Message {
|
||||
return m.CloneVT()
|
||||
}
|
||||
|
||||
func (m *SolveRequest) CloneVT() *SolveRequest {
|
||||
if m == nil {
|
||||
return (*SolveRequest)(nil)
|
||||
@@ -1870,6 +1933,9 @@ func (this *ResolveSourceMetaRequest) EqualVT(that *ResolveSourceMetaRequest) bo
|
||||
if !this.Image.EqualVT(that.Image) {
|
||||
return false
|
||||
}
|
||||
if !this.HTTP.EqualVT(that.HTTP) {
|
||||
return false
|
||||
}
|
||||
if len(this.SourcePolicies) != len(that.SourcePolicies) {
|
||||
return false
|
||||
}
|
||||
@@ -2100,6 +2166,9 @@ func (this *ResolveSourceHTTPResponse) EqualVT(that *ResolveSourceHTTPResponse)
|
||||
if !(*timestamppb.Timestamp)(this.LastModified).EqualVT((*timestamppb.Timestamp)(that.LastModified)) {
|
||||
return false
|
||||
}
|
||||
if !this.ChecksumResponse.EqualVT(that.ChecksumResponse) {
|
||||
return false
|
||||
}
|
||||
return string(this.unknownFields) == string(that.unknownFields)
|
||||
}
|
||||
|
||||
@@ -2110,6 +2179,69 @@ func (this *ResolveSourceHTTPResponse) EqualMessageVT(thatMsg proto.Message) boo
|
||||
}
|
||||
return this.EqualVT(that)
|
||||
}
|
||||
func (this *ResolveSourceHTTPRequest) EqualVT(that *ResolveSourceHTTPRequest) bool {
|
||||
if this == that {
|
||||
return true
|
||||
} else if this == nil || that == nil {
|
||||
return false
|
||||
}
|
||||
if !this.ChecksumRequest.EqualVT(that.ChecksumRequest) {
|
||||
return false
|
||||
}
|
||||
return string(this.unknownFields) == string(that.unknownFields)
|
||||
}
|
||||
|
||||
func (this *ResolveSourceHTTPRequest) EqualMessageVT(thatMsg proto.Message) bool {
|
||||
that, ok := thatMsg.(*ResolveSourceHTTPRequest)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return this.EqualVT(that)
|
||||
}
|
||||
func (this *ChecksumRequest) EqualVT(that *ChecksumRequest) bool {
|
||||
if this == that {
|
||||
return true
|
||||
} else if this == nil || that == nil {
|
||||
return false
|
||||
}
|
||||
if this.Algo != that.Algo {
|
||||
return false
|
||||
}
|
||||
if string(this.Suffix) != string(that.Suffix) {
|
||||
return false
|
||||
}
|
||||
return string(this.unknownFields) == string(that.unknownFields)
|
||||
}
|
||||
|
||||
func (this *ChecksumRequest) EqualMessageVT(thatMsg proto.Message) bool {
|
||||
that, ok := thatMsg.(*ChecksumRequest)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return this.EqualVT(that)
|
||||
}
|
||||
func (this *ChecksumResponse) EqualVT(that *ChecksumResponse) bool {
|
||||
if this == that {
|
||||
return true
|
||||
} else if this == nil || that == nil {
|
||||
return false
|
||||
}
|
||||
if this.Digest != that.Digest {
|
||||
return false
|
||||
}
|
||||
if string(this.Suffix) != string(that.Suffix) {
|
||||
return false
|
||||
}
|
||||
return string(this.unknownFields) == string(that.unknownFields)
|
||||
}
|
||||
|
||||
func (this *ChecksumResponse) EqualMessageVT(thatMsg proto.Message) bool {
|
||||
that, ok := thatMsg.(*ChecksumResponse)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return this.EqualVT(that)
|
||||
}
|
||||
func (this *SolveRequest) EqualVT(that *SolveRequest) bool {
|
||||
if this == that {
|
||||
return true
|
||||
@@ -4090,6 +4222,16 @@ func (m *ResolveSourceMetaRequest) MarshalToSizedBufferVT(dAtA []byte) (int, err
|
||||
dAtA[i] = 0x42
|
||||
}
|
||||
}
|
||||
if m.HTTP != nil {
|
||||
size, err := m.HTTP.MarshalToSizedBufferVT(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(size))
|
||||
i--
|
||||
dAtA[i] = 0x3a
|
||||
}
|
||||
if m.Image != nil {
|
||||
size, err := m.Image.MarshalToSizedBufferVT(dAtA[:i])
|
||||
if err != nil {
|
||||
@@ -4565,6 +4707,16 @@ func (m *ResolveSourceHTTPResponse) MarshalToSizedBufferVT(dAtA []byte) (int, er
|
||||
i -= len(m.unknownFields)
|
||||
copy(dAtA[i:], m.unknownFields)
|
||||
}
|
||||
if m.ChecksumResponse != nil {
|
||||
size, err := m.ChecksumResponse.MarshalToSizedBufferVT(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(size))
|
||||
i--
|
||||
dAtA[i] = 0x22
|
||||
}
|
||||
if m.LastModified != nil {
|
||||
size, err := (*timestamppb.Timestamp)(m.LastModified).MarshalToSizedBufferVT(dAtA[:i])
|
||||
if err != nil {
|
||||
@@ -4592,6 +4744,141 @@ func (m *ResolveSourceHTTPResponse) MarshalToSizedBufferVT(dAtA []byte) (int, er
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *ResolveSourceHTTPRequest) MarshalVT() (dAtA []byte, err error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
size := m.SizeVT()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ResolveSourceHTTPRequest) MarshalToVT(dAtA []byte) (int, error) {
|
||||
size := m.SizeVT()
|
||||
return m.MarshalToSizedBufferVT(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *ResolveSourceHTTPRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
|
||||
if m == nil {
|
||||
return 0, nil
|
||||
}
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.unknownFields != nil {
|
||||
i -= len(m.unknownFields)
|
||||
copy(dAtA[i:], m.unknownFields)
|
||||
}
|
||||
if m.ChecksumRequest != nil {
|
||||
size, err := m.ChecksumRequest.MarshalToSizedBufferVT(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(size))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *ChecksumRequest) MarshalVT() (dAtA []byte, err error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
size := m.SizeVT()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ChecksumRequest) MarshalToVT(dAtA []byte) (int, error) {
|
||||
size := m.SizeVT()
|
||||
return m.MarshalToSizedBufferVT(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *ChecksumRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
|
||||
if m == nil {
|
||||
return 0, nil
|
||||
}
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.unknownFields != nil {
|
||||
i -= len(m.unknownFields)
|
||||
copy(dAtA[i:], m.unknownFields)
|
||||
}
|
||||
if len(m.Suffix) > 0 {
|
||||
i -= len(m.Suffix)
|
||||
copy(dAtA[i:], m.Suffix)
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Suffix)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if m.Algo != 0 {
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Algo))
|
||||
i--
|
||||
dAtA[i] = 0x8
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *ChecksumResponse) MarshalVT() (dAtA []byte, err error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
size := m.SizeVT()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *ChecksumResponse) MarshalToVT(dAtA []byte) (int, error) {
|
||||
size := m.SizeVT()
|
||||
return m.MarshalToSizedBufferVT(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *ChecksumResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
|
||||
if m == nil {
|
||||
return 0, nil
|
||||
}
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.unknownFields != nil {
|
||||
i -= len(m.unknownFields)
|
||||
copy(dAtA[i:], m.unknownFields)
|
||||
}
|
||||
if len(m.Suffix) > 0 {
|
||||
i -= len(m.Suffix)
|
||||
copy(dAtA[i:], m.Suffix)
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Suffix)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if len(m.Digest) > 0 {
|
||||
i -= len(m.Digest)
|
||||
copy(dAtA[i:], m.Digest)
|
||||
i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Digest)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *SolveRequest) MarshalVT() (dAtA []byte, err error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
@@ -6810,6 +7097,10 @@ func (m *ResolveSourceMetaRequest) SizeVT() (n int) {
|
||||
l = m.Image.SizeVT()
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
if m.HTTP != nil {
|
||||
l = m.HTTP.SizeVT()
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
if len(m.SourcePolicies) > 0 {
|
||||
for _, e := range m.SourcePolicies {
|
||||
l = e.SizeVT()
|
||||
@@ -6992,6 +7283,59 @@ func (m *ResolveSourceHTTPResponse) SizeVT() (n int) {
|
||||
l = (*timestamppb.Timestamp)(m.LastModified).SizeVT()
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
if m.ChecksumResponse != nil {
|
||||
l = m.ChecksumResponse.SizeVT()
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
n += len(m.unknownFields)
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ResolveSourceHTTPRequest) SizeVT() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.ChecksumRequest != nil {
|
||||
l = m.ChecksumRequest.SizeVT()
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
n += len(m.unknownFields)
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ChecksumRequest) SizeVT() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.Algo != 0 {
|
||||
n += 1 + protohelpers.SizeOfVarint(uint64(m.Algo))
|
||||
}
|
||||
l = len(m.Suffix)
|
||||
if l > 0 {
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
n += len(m.unknownFields)
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *ChecksumResponse) SizeVT() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.Digest)
|
||||
if l > 0 {
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
l = len(m.Suffix)
|
||||
if l > 0 {
|
||||
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
|
||||
}
|
||||
n += len(m.unknownFields)
|
||||
return n
|
||||
}
|
||||
@@ -10316,6 +10660,42 @@ func (m *ResolveSourceMetaRequest) UnmarshalVT(dAtA []byte) error {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 7:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field HTTP", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.HTTP == nil {
|
||||
m.HTTP = &ResolveSourceHTTPRequest{}
|
||||
}
|
||||
if err := m.HTTP.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 8:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field SourcePolicies", wireType)
|
||||
@@ -11566,6 +11946,350 @@ func (m *ResolveSourceHTTPResponse) UnmarshalVT(dAtA []byte) error {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ChecksumResponse", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.ChecksumResponse == nil {
|
||||
m.ChecksumResponse = &ChecksumResponse{}
|
||||
}
|
||||
if err := m.ChecksumResponse.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ResolveSourceHTTPRequest) UnmarshalVT(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ResolveSourceHTTPRequest: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ResolveSourceHTTPRequest: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field ChecksumRequest", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
msglen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if msglen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + msglen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
if m.ChecksumRequest == nil {
|
||||
m.ChecksumRequest = &ChecksumRequest{}
|
||||
}
|
||||
if err := m.ChecksumRequest.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ChecksumRequest) UnmarshalVT(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ChecksumRequest: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ChecksumRequest: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Algo", wireType)
|
||||
}
|
||||
m.Algo = 0
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
m.Algo |= ChecksumRequest_ChecksumAlgo(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Suffix", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Suffix = append(m.Suffix[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Suffix == nil {
|
||||
m.Suffix = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *ChecksumResponse) UnmarshalVT(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: ChecksumResponse: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: ChecksumResponse: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Digest", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Digest = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Suffix", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return protohelpers.ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return protohelpers.ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.Suffix = append(m.Suffix[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.Suffix == nil {
|
||||
m.Suffix = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := protohelpers.Skip(dAtA[iNdEx:])
|
||||
|
||||
+11
-4
@@ -62,6 +62,12 @@ type ImageSource struct {
|
||||
Local bool
|
||||
}
|
||||
|
||||
type ImageBlobSource struct {
|
||||
Ref string
|
||||
Digest digest.Digest
|
||||
Local bool
|
||||
}
|
||||
|
||||
type GitSource struct {
|
||||
URL string
|
||||
Commit string
|
||||
@@ -87,10 +93,11 @@ type SSH struct {
|
||||
}
|
||||
|
||||
type Sources struct {
|
||||
Images []ImageSource
|
||||
Git []GitSource
|
||||
HTTP []HTTPSource
|
||||
Local []LocalSource
|
||||
Images []ImageSource
|
||||
ImageBlobs []ImageBlobSource
|
||||
Git []GitSource
|
||||
HTTP []HTTPSource
|
||||
Local []LocalSource
|
||||
}
|
||||
|
||||
func (ps *ProvenanceSLSA) Validate() error {
|
||||
|
||||
+2
@@ -32,6 +32,8 @@ const AttrHTTPUID = "http.uid"
|
||||
const AttrHTTPGID = "http.gid"
|
||||
const AttrHTTPAuthHeaderSecret = "http.authheadersecret"
|
||||
const AttrHTTPHeaderPrefix = "http.header."
|
||||
const AttrHTTPSignatureVerifyPubKey = "http.sig.pubkey"
|
||||
const AttrHTTPSignatureVerify = "http.sig.signature"
|
||||
|
||||
const AttrImageResolveMode = "image.resolvemode"
|
||||
const AttrImageResolveModeDefault = "default"
|
||||
|
||||
+17
-2
@@ -40,8 +40,11 @@ const (
|
||||
CapSourceHTTPChecksum apicaps.CapID = "source.http.checksum"
|
||||
CapSourceHTTPPerm apicaps.CapID = "source.http.perm"
|
||||
// NOTE the historical typo
|
||||
CapSourceHTTPUIDGID apicaps.CapID = "soruce.http.uidgid"
|
||||
CapSourceHTTPHeader apicaps.CapID = "source.http.header"
|
||||
CapSourceHTTPUIDGID apicaps.CapID = "soruce.http.uidgid"
|
||||
CapSourceHTTPHeader apicaps.CapID = "source.http.header"
|
||||
CapSourceHTTPSignatureVerify apicaps.CapID = "source.http.signatureverify"
|
||||
|
||||
CapSourceImageBlob apicaps.CapID = "source.imageblob"
|
||||
|
||||
CapSourceOCILayout apicaps.CapID = "source.ocilayout"
|
||||
|
||||
@@ -288,6 +291,18 @@ func init() {
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapSourceHTTPSignatureVerify,
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapSourceImageBlob,
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapSourceOCILayout,
|
||||
Enabled: true,
|
||||
|
||||
+8
-6
@@ -1,10 +1,12 @@
|
||||
package srctypes
|
||||
|
||||
const (
|
||||
DockerImageScheme = "docker-image"
|
||||
GitScheme = "git"
|
||||
LocalScheme = "local"
|
||||
HTTPScheme = "http"
|
||||
HTTPSScheme = "https"
|
||||
OCIScheme = "oci-layout"
|
||||
DockerImageScheme = "docker-image"
|
||||
DockerImageBlobScheme = "docker-image+blob"
|
||||
GitScheme = "git"
|
||||
LocalScheme = "local"
|
||||
HTTPScheme = "http"
|
||||
HTTPSScheme = "https"
|
||||
OCIScheme = "oci-layout"
|
||||
OCIBlobScheme = "oci-layout+blob"
|
||||
)
|
||||
|
||||
+16
@@ -19,6 +19,7 @@ import (
|
||||
type Buffer interface {
|
||||
content.Provider
|
||||
content.Ingester
|
||||
content.IngestManager
|
||||
content.Manager
|
||||
}
|
||||
|
||||
@@ -119,6 +120,21 @@ func (b *buffer) Writer(ctx context.Context, opts ...content.WriterOpt) (content
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (b *buffer) Status(ctx context.Context, ref string) (content.Status, error) {
|
||||
return content.Status{}, cerrdefs.ErrNotFound
|
||||
}
|
||||
|
||||
func (b *buffer) ListStatuses(ctx context.Context, filters ...string) ([]content.Status, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (b *buffer) Abort(ctx context.Context, ref string) error {
|
||||
b.mu.Lock()
|
||||
delete(b.refs, ref)
|
||||
b.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *buffer) ReaderAt(ctx context.Context, desc ocispecs.Descriptor) (content.ReaderAt, error) {
|
||||
r, err := b.getBytesReader(desc.Digest)
|
||||
if err != nil {
|
||||
|
||||
+18
@@ -52,11 +52,28 @@ func (p *ReferrersProviderBuffer) ReaderAt(ctx context.Context, desc ocispecs.De
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if st, err := cw.Status(); err == nil {
|
||||
if st.Offset > 0 {
|
||||
if err := cw.Truncate(0); err != nil {
|
||||
cw.Close()
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
abort := func() {
|
||||
_ = p.cache.Abort(ctx, desc.Digest.String())
|
||||
}
|
||||
defer func() {
|
||||
if abort != nil {
|
||||
abort()
|
||||
}
|
||||
}()
|
||||
ra, err := p.p.ReaderAt(ctx, desc)
|
||||
if err != nil {
|
||||
cw.Close()
|
||||
return nil, err
|
||||
}
|
||||
defer ra.Close()
|
||||
if err := content.CopyReaderAt(cw, ra, ra.Size()); err != nil {
|
||||
cw.Close()
|
||||
return nil, err
|
||||
@@ -65,6 +82,7 @@ func (p *ReferrersProviderBuffer) ReaderAt(ctx context.Context, desc ocispecs.De
|
||||
cw.Close()
|
||||
return nil, err
|
||||
}
|
||||
abort = nil
|
||||
ra, err = p.cache.ReaderAt(ctx, desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+23
-172
@@ -2,39 +2,23 @@ package gitsign
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"encoding/pem"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ProtonMail/go-crypto/openpgp"
|
||||
"github.com/ProtonMail/go-crypto/openpgp/armor"
|
||||
"github.com/ProtonMail/go-crypto/openpgp/packet"
|
||||
"github.com/hiddeco/sshsig"
|
||||
"github.com/moby/buildkit/util/gitutil/gitobject"
|
||||
"github.com/moby/buildkit/util/pgpsign"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
type sigType int
|
||||
|
||||
const (
|
||||
sigTypePGP sigType = iota
|
||||
sigTypeSSH
|
||||
)
|
||||
|
||||
type Signature struct {
|
||||
PGPSignature *packet.Signature
|
||||
SSHSignature *sshsig.Signature
|
||||
}
|
||||
|
||||
type VerifyPolicy struct {
|
||||
RejectExpiredKeys bool
|
||||
}
|
||||
|
||||
func VerifySignature(obj *gitobject.GitObject, pubKeyData []byte, policy *VerifyPolicy) error {
|
||||
func VerifySignature(obj *gitobject.GitObject, pubKeyData []byte, policy *pgpsign.VerifyPolicy) error {
|
||||
if len(obj.Signature) == 0 {
|
||||
return errors.New("git object is not signed")
|
||||
}
|
||||
@@ -44,58 +28,20 @@ func VerifySignature(obj *gitobject.GitObject, pubKeyData []byte, policy *Verify
|
||||
return err
|
||||
}
|
||||
if s.PGPSignature != nil {
|
||||
return verifyPGPSignature(obj, s.PGPSignature, pubKeyData, policy)
|
||||
return verifyPGPSignature(obj, pubKeyData, policy)
|
||||
} else if s.SSHSignature != nil {
|
||||
return verifySSHSignature(obj, s.SSHSignature, pubKeyData)
|
||||
}
|
||||
return errors.New("no valid signature found")
|
||||
}
|
||||
|
||||
func verifyPGPSignature(obj *gitobject.GitObject, sig *packet.Signature, pubKeyData []byte, policy *VerifyPolicy) error {
|
||||
sigBlock, _, err := parseSignatureBlock([]byte(obj.Signature))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ents, err := openpgp.ReadArmoredKeyRing(bytes.NewReader(pubKeyData))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to read armored public key")
|
||||
}
|
||||
|
||||
// add addition algorithm constraints
|
||||
if err := checkAlgoPolicy(sig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config := &packet.Config{}
|
||||
if policy == nil || !policy.RejectExpiredKeys {
|
||||
config.Time = func() time.Time {
|
||||
return sig.CreationTime
|
||||
}
|
||||
}
|
||||
|
||||
signer, err := openpgp.CheckDetachedSignature(
|
||||
ents,
|
||||
func verifyPGPSignature(obj *gitobject.GitObject, pubKeyData []byte, policy *pgpsign.VerifyPolicy) error {
|
||||
return pgpsign.VerifyArmoredDetachedSignature(
|
||||
bytes.NewReader([]byte(obj.SignedData)),
|
||||
bytes.NewReader(sigBlock),
|
||||
config,
|
||||
[]byte(obj.Signature),
|
||||
pubKeyData,
|
||||
policy,
|
||||
)
|
||||
if err != nil {
|
||||
if sig.IssuerKeyId != nil {
|
||||
return errors.Wrapf(err, "signature by %X", *sig.IssuerKeyId)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkEntityUsableForSigning(signer, time.Now(), policy); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkCreationTime(sig.CreationTime, time.Now()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifySSHSignature(obj *gitobject.GitObject, sig *sshsig.Signature, pubKeyData []byte) error {
|
||||
@@ -125,130 +71,35 @@ func verifySSHSignature(obj *gitobject.GitObject, sig *sshsig.Signature, pubKeyD
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkEntityUsableForSigning(e *openpgp.Entity, now time.Time, policy *VerifyPolicy) error {
|
||||
if e == nil || e.PrimaryKey == nil {
|
||||
return errors.New("nil entity or key")
|
||||
}
|
||||
|
||||
// Expiry
|
||||
if policy != nil && policy.RejectExpiredKeys {
|
||||
if id := e.PrimaryIdentity(); id != nil && id.SelfSignature != nil {
|
||||
if exp := id.SelfSignature.KeyLifetimeSecs; exp != nil && *exp > 0 {
|
||||
expiry := e.PrimaryKey.CreationTime.Add(time.Duration(*exp) * time.Second)
|
||||
if now.After(expiry) {
|
||||
return errors.Errorf("key expired at %v", expiry)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Revocation
|
||||
if err := checkEntityRevocation(e); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// RSA bit length (optional)
|
||||
if rsaPub, ok := e.PrimaryKey.PublicKey.(*rsa.PublicKey); ok {
|
||||
if rsaPub.N.BitLen() < 2048 {
|
||||
return errors.Errorf("RSA key too short: %d bits", rsaPub.N.BitLen())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkEntityRevocation(e *openpgp.Entity) error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
for _, r := range e.Revocations {
|
||||
if r == nil || r.SigType != packet.SigTypeKeyRevocation {
|
||||
continue
|
||||
}
|
||||
if err := e.PrimaryKey.VerifyRevocationSignature(r); err != nil {
|
||||
continue // ignore malformed or unverified revocations
|
||||
}
|
||||
if r.RevocationReasonText != "" {
|
||||
return errors.Errorf("key revoked: %s", r.RevocationReasonText)
|
||||
}
|
||||
return errors.New("key revoked")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseSignatureBlock(data []byte) ([]byte, sigType, error) {
|
||||
func parseSignatureBlock(data []byte) ([]byte, error) {
|
||||
if strings.HasPrefix(string(data), "-----BEGIN SSH SIGNATURE-----") {
|
||||
block, _ := pem.Decode(data)
|
||||
if block == nil || block.Type != "SSH SIGNATURE" {
|
||||
return nil, 0, errors.New("failed to decode ssh signature PEM block")
|
||||
return nil, errors.New("failed to decode ssh signature PEM block")
|
||||
}
|
||||
return block.Bytes, sigTypeSSH, nil
|
||||
} else if strings.HasPrefix(string(data), "-----BEGIN PGP SIGNATURE-----") {
|
||||
block, err := armor.Decode(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return nil, 0, errors.Wrap(err, "failed to decode armored signature")
|
||||
}
|
||||
dt, err := io.ReadAll(block.Body)
|
||||
if err != nil {
|
||||
return nil, 0, errors.Wrap(err, "failed to read armored signature body")
|
||||
}
|
||||
return dt, sigTypePGP, nil
|
||||
return block.Bytes, nil
|
||||
}
|
||||
return nil, 0, errors.Errorf("invalid signature format")
|
||||
return nil, errors.Errorf("invalid signature format")
|
||||
}
|
||||
|
||||
func ParseSignature(data []byte) (*Signature, error) {
|
||||
sigBlock, typ, err := parseSignatureBlock(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if strings.HasPrefix(string(data), "-----BEGIN PGP SIGNATURE-----") {
|
||||
sig, _, err := pgpsign.ParseArmoredDetachedSignature(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Signature{PGPSignature: sig}, nil
|
||||
}
|
||||
switch typ {
|
||||
case sigTypePGP:
|
||||
pr := packet.NewReader(bytes.NewReader(sigBlock))
|
||||
for {
|
||||
p, err := pr.Next()
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to read next packet")
|
||||
}
|
||||
sig, ok := p.(*packet.Signature)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
return &Signature{PGPSignature: sig}, nil
|
||||
if strings.HasPrefix(string(data), "-----BEGIN SSH SIGNATURE-----") {
|
||||
sigBlock, err := parseSignatureBlock(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case sigTypeSSH:
|
||||
sig, err := sshsig.ParseSignature(sigBlock)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parse ssh signature")
|
||||
}
|
||||
return &Signature{SSHSignature: sig}, nil
|
||||
}
|
||||
|
||||
return nil, errors.Errorf("no signature packet found")
|
||||
}
|
||||
|
||||
func checkAlgoPolicy(sig *packet.Signature) error {
|
||||
switch sig.Hash {
|
||||
case crypto.SHA256, crypto.SHA384, crypto.SHA512:
|
||||
// ok
|
||||
default:
|
||||
return errors.Errorf("rejecting weak/unknown hash: %v", sig.Hash)
|
||||
}
|
||||
// Pubkey policy
|
||||
switch sig.PubKeyAlgo {
|
||||
case packet.PubKeyAlgoEdDSA, packet.PubKeyAlgoECDSA, packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSASignOnly:
|
||||
default:
|
||||
return errors.Errorf("rejecting unsupported pubkey algorithm: %v", sig.PubKeyAlgo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkCreationTime(sigTime, now time.Time) error {
|
||||
if sigTime.After(now.Add(5 * time.Minute)) {
|
||||
return errors.Errorf("signature creation time is in the future: %v", sigTime)
|
||||
}
|
||||
return nil
|
||||
return nil, errors.Errorf("invalid signature format")
|
||||
}
|
||||
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
package pgpsign
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/ProtonMail/go-crypto/openpgp"
|
||||
"github.com/ProtonMail/go-crypto/openpgp/armor"
|
||||
"github.com/ProtonMail/go-crypto/openpgp/packet"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// VerifyPolicy defines validation policy for OpenPGP signature verification.
|
||||
type VerifyPolicy struct {
|
||||
RejectExpiredKeys bool
|
||||
}
|
||||
|
||||
// ParseArmoredDetachedSignature parses a detached armored OpenPGP signature and
|
||||
// returns the first signature packet and the decoded binary signature payload.
|
||||
func ParseArmoredDetachedSignature(data []byte) (*packet.Signature, []byte, error) {
|
||||
block, err := armor.Decode(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to decode armored signature")
|
||||
}
|
||||
sigBlock, err := io.ReadAll(block.Body)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to read armored signature body")
|
||||
}
|
||||
|
||||
pr := packet.NewReader(bytes.NewReader(sigBlock))
|
||||
for {
|
||||
p, err := pr.Next()
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "failed to read next packet")
|
||||
}
|
||||
sig, ok := p.(*packet.Signature)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
return sig, sigBlock, nil
|
||||
}
|
||||
return nil, nil, errors.New("no signature packet found")
|
||||
}
|
||||
|
||||
// ReadAllArmoredKeyRings parses one or more concatenated armored OpenPGP key
|
||||
// blocks and returns a combined entity list.
|
||||
func ReadAllArmoredKeyRings(pubKeyData []byte) (openpgp.EntityList, error) {
|
||||
var ents openpgp.EntityList
|
||||
r := bytes.NewReader(pubKeyData)
|
||||
|
||||
for {
|
||||
block, err := armor.Decode(r)
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to decode armored public key")
|
||||
}
|
||||
|
||||
if block.Type != openpgp.PublicKeyType && block.Type != openpgp.PrivateKeyType {
|
||||
return nil, errors.Errorf("expected public or private key block, got: %s", block.Type)
|
||||
}
|
||||
|
||||
el, err := openpgp.ReadKeyRing(block.Body)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to read armored public key")
|
||||
}
|
||||
ents = append(ents, el...)
|
||||
}
|
||||
|
||||
if len(ents) == 0 {
|
||||
return nil, errors.New("failed to read armored public key: no armored data found")
|
||||
}
|
||||
|
||||
return ents, nil
|
||||
}
|
||||
|
||||
// VerifyArmoredDetachedSignature verifies an armored detached OpenPGP
|
||||
// signature against signedData using one or more armored public key blocks.
|
||||
func VerifyArmoredDetachedSignature(signedData io.Reader, signatureData, pubKeyData []byte, policy *VerifyPolicy) error {
|
||||
sig, sigBlock, err := ParseArmoredDetachedSignature(signatureData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ents, err := ReadAllArmoredKeyRings(pubKeyData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkAlgoPolicy(sig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config := &packet.Config{}
|
||||
if policy == nil || !policy.RejectExpiredKeys {
|
||||
config.Time = func() time.Time {
|
||||
return sig.CreationTime
|
||||
}
|
||||
}
|
||||
|
||||
signer, err := openpgp.CheckDetachedSignature(
|
||||
ents,
|
||||
signedData,
|
||||
bytes.NewReader(sigBlock),
|
||||
config,
|
||||
)
|
||||
if err != nil {
|
||||
if sig.IssuerKeyId != nil {
|
||||
return errors.Wrapf(err, "signature by %X", *sig.IssuerKeyId)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
if err := checkEntityUsableForSigning(signer, now, policy); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkCreationTime(sig.CreationTime, now); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifySignatureWithDigest verifies a parsed signature against a digest of
|
||||
// the signed payload plus OpenPGP hash suffix (payload || suffix) using the
|
||||
// provided keyring.
|
||||
func VerifySignatureWithDigest(sig *packet.Signature, keyring openpgp.EntityList, dgst digest.Digest) error {
|
||||
if sig == nil {
|
||||
return errors.New("nil signature")
|
||||
}
|
||||
|
||||
expectedAlgo, err := signatureDigestAlgorithm(sig.Hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if dgst.Algorithm() != expectedAlgo {
|
||||
return errors.Errorf("digest algorithm mismatch: %s != %s", dgst.Algorithm(), expectedAlgo)
|
||||
}
|
||||
|
||||
sum, err := hex.DecodeString(dgst.Encoded())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "invalid digest hex")
|
||||
}
|
||||
|
||||
h := &staticHash{sum: sum, algo: sig.Hash}
|
||||
if len(sum) != h.Size() {
|
||||
return errors.Errorf("digest size mismatch: got %d, expected %d", len(sum), h.Size())
|
||||
}
|
||||
for _, e := range keyring {
|
||||
if e.PrimaryKey != nil && e.PrimaryKey.VerifySignature(h, sig) == nil {
|
||||
return nil
|
||||
}
|
||||
for _, sub := range e.Subkeys {
|
||||
if sub.PublicKey != nil && sub.PublicKey.VerifySignature(h, sig) == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return errors.New("failed to verify signature with checksum digest")
|
||||
}
|
||||
|
||||
func signatureDigestAlgorithm(h crypto.Hash) (digest.Algorithm, error) {
|
||||
switch h {
|
||||
case crypto.SHA256:
|
||||
return digest.SHA256, nil
|
||||
case crypto.SHA384:
|
||||
return digest.SHA384, nil
|
||||
case crypto.SHA512:
|
||||
return digest.SHA512, nil
|
||||
default:
|
||||
return "", errors.Errorf("unsupported signature hash algorithm %v", h)
|
||||
}
|
||||
}
|
||||
|
||||
type staticHash struct {
|
||||
sum []byte
|
||||
algo crypto.Hash
|
||||
}
|
||||
|
||||
func (s *staticHash) Write(p []byte) (n int, err error) {
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (s *staticHash) Sum(b []byte) []byte {
|
||||
return append(b, s.sum...)
|
||||
}
|
||||
|
||||
func (s *staticHash) Reset() {}
|
||||
|
||||
func (s *staticHash) Size() int {
|
||||
switch s.algo {
|
||||
case crypto.SHA256:
|
||||
return sha256.Size
|
||||
case crypto.SHA384:
|
||||
return sha512.Size384
|
||||
case crypto.SHA512:
|
||||
return sha512.Size
|
||||
default:
|
||||
return len(s.sum)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *staticHash) BlockSize() int {
|
||||
switch s.algo {
|
||||
case crypto.SHA256:
|
||||
return sha256.BlockSize
|
||||
case crypto.SHA384, crypto.SHA512:
|
||||
return sha512.BlockSize
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func checkAlgoPolicy(sig *packet.Signature) error {
|
||||
switch sig.Hash {
|
||||
case crypto.SHA256, crypto.SHA384, crypto.SHA512:
|
||||
// ok
|
||||
default:
|
||||
return errors.Errorf("rejecting weak/unknown hash: %v", sig.Hash)
|
||||
}
|
||||
|
||||
switch sig.PubKeyAlgo {
|
||||
case packet.PubKeyAlgoEdDSA, packet.PubKeyAlgoECDSA, packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSASignOnly:
|
||||
default:
|
||||
return errors.Errorf("rejecting unsupported pubkey algorithm: %v", sig.PubKeyAlgo)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkEntityUsableForSigning(e *openpgp.Entity, now time.Time, policy *VerifyPolicy) error {
|
||||
if e == nil || e.PrimaryKey == nil {
|
||||
return errors.New("nil entity or key")
|
||||
}
|
||||
|
||||
if policy != nil && policy.RejectExpiredKeys {
|
||||
if id := e.PrimaryIdentity(); id != nil && id.SelfSignature != nil {
|
||||
if exp := id.SelfSignature.KeyLifetimeSecs; exp != nil && *exp > 0 {
|
||||
expiry := e.PrimaryKey.CreationTime.Add(time.Duration(*exp) * time.Second)
|
||||
if now.After(expiry) {
|
||||
return errors.Errorf("key expired at %v", expiry)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := checkEntityRevocation(e); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rsaPub, ok := e.PrimaryKey.PublicKey.(*rsa.PublicKey); ok {
|
||||
if rsaPub.N.BitLen() < 2048 {
|
||||
return errors.Errorf("RSA key too short: %d bits", rsaPub.N.BitLen())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkEntityRevocation(e *openpgp.Entity) error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
for _, r := range e.Revocations {
|
||||
if r == nil || r.SigType != packet.SigTypeKeyRevocation {
|
||||
continue
|
||||
}
|
||||
if err := e.PrimaryKey.VerifyRevocationSignature(r); err != nil {
|
||||
continue
|
||||
}
|
||||
if r.RevocationReasonText != "" {
|
||||
return errors.Errorf("key revoked: %s", r.RevocationReasonText)
|
||||
}
|
||||
return errors.New("key revoked")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkCreationTime(sigTime, now time.Time) error {
|
||||
if sigTime.After(now.Add(5 * time.Minute)) {
|
||||
return errors.Errorf("signature creation time is in the future: %v", sigTime)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+1
-2
@@ -1,2 +1 @@
|
||||
bin
|
||||
vendor
|
||||
bin
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
.PHONY: all
|
||||
all:
|
||||
|
||||
.PHONY: vendor
|
||||
vendor:
|
||||
$(eval $@_TMP_OUT := $(shell mktemp -d -t policy-helpers-output.XXXXXXXXXX))
|
||||
docker buildx bake --set "*.output=type=local,dest=$($@_TMP_OUT)" vendor
|
||||
rm -rf ./vendor
|
||||
cp -R "$($@_TMP_OUT)"/* ./
|
||||
rm -rf "$($@_TMP_OUT)"/*
|
||||
+31
-2
@@ -2,7 +2,7 @@ variable "ROOT_SIGNING_VERSION" {
|
||||
type = string
|
||||
# default = "8842feefbb65effea46ff4a0f2b6aad91e685fe9" # expired root
|
||||
# default = "9d8b5c5e3bed603c80b57fcc316b7a1af688c57e" # expired timestamp
|
||||
default = "b72505e865a7c68bd75e03272fa66512bcb41bb1"
|
||||
default = "a72700d5c80d43a209d31325fee46facc6f0cf31"
|
||||
description = "The git commit hash of sigstore/root-signing to use for embedded roots."
|
||||
}
|
||||
|
||||
@@ -12,6 +12,12 @@ variable "DOCKER_HARDENED_IMAGES_KEYRING_VERSION" {
|
||||
description = "The git branch or commit hash of docker/hardened-images-keyring to use for DHI verification."
|
||||
}
|
||||
|
||||
target "_common" {
|
||||
args = {
|
||||
BUILDKIT_CONTEXT_KEEP_GIT_DIR = 1
|
||||
}
|
||||
}
|
||||
|
||||
target "tuf-root" {
|
||||
target = "tuf-root"
|
||||
output = [{
|
||||
@@ -34,7 +40,7 @@ target "validate-tuf-root" {
|
||||
}
|
||||
|
||||
group "validate-all" {
|
||||
targets = ["lint", "lint-gopls", "validate-dockerfile", "validate-generated-files"]
|
||||
targets = ["lint", "lint-gopls", "validate-vendor", "validate-dockerfile", "validate-generated-files"]
|
||||
}
|
||||
|
||||
group "validate-generated-files" {
|
||||
@@ -49,11 +55,19 @@ target "lint" {
|
||||
}
|
||||
}
|
||||
|
||||
target "validate-vendor" {
|
||||
inherits = ["_common"]
|
||||
dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
|
||||
target = "validate"
|
||||
output = ["type=cacheonly"]
|
||||
}
|
||||
|
||||
target "validate-dockerfile" {
|
||||
matrix = {
|
||||
dockerfile = [
|
||||
"Dockerfile",
|
||||
"./hack/dockerfiles/lint.Dockerfile",
|
||||
"./hack/dockerfiles/vendor.Dockerfile"
|
||||
]
|
||||
}
|
||||
name = "validate-dockerfile-${md5(dockerfile)}"
|
||||
@@ -66,6 +80,21 @@ target "lint-gopls" {
|
||||
target = "gopls-analyze"
|
||||
}
|
||||
|
||||
target "vendor" {
|
||||
inherits = ["_common"]
|
||||
dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
|
||||
target = "update"
|
||||
output = ["."]
|
||||
}
|
||||
|
||||
target "mod-outdated" {
|
||||
inherits = ["_common"]
|
||||
dockerfile = "./hack/dockerfiles/vendor.Dockerfile"
|
||||
target = "outdated"
|
||||
no-cache-filter = ["outdated"]
|
||||
output = ["type=cacheonly"]
|
||||
}
|
||||
|
||||
target "binary" {
|
||||
target = "binary"
|
||||
platforms = [ "local" ]
|
||||
|
||||
+7
-11
@@ -1,34 +1,30 @@
|
||||
{
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "6f260089d5923daf20166ca657c543af618346ab971884a99962b01988bbe0c3",
|
||||
"sig": ""
|
||||
},
|
||||
{
|
||||
"keyid": "e71a54d543835ba86adad9460379c7641fb8726d164ea766801a1c522aba7ea2",
|
||||
"sig": "3045022100bbddd464f8066ceb88ba787375c12cd6330680e08c2910703e6538c71cc79ad202205190b06e4537fe961b3ef81fe68edcd0089c19f919afed423b9aafd700641153"
|
||||
"sig": "3046022100e04c9706299be5d8c2b14fb50bcd5b9c241f10597153dfe22f943efe896b5150022100cfd7b9f06a5900784e312d02b8e336edbb3b2fab61ac14550b3112b4f9e33df4"
|
||||
},
|
||||
{
|
||||
"keyid": "22f4caec6d8e6f9555af66b3d4c3cb06a3bb23fdc7e39c916c61f462e6f52b06",
|
||||
"sig": "3044022069306cd5257f732a740c1afe60a8e433c5de58eafeadbe99c336c9c71d198cf802200d773953ae7dbc48d3e5bad9a6f64bafff196b7e2ad4a52a19519367d47dc042"
|
||||
"sig": ""
|
||||
},
|
||||
{
|
||||
"keyid": "61643838125b440b40db6942f5cb5a31c0dc04368316eb2aaa58b95904a58222",
|
||||
"sig": "304402204d21a2ec80df66e61f6fe2912951dc47df836036f8c0ab10816d375e71dbf79e0220547adce1afdf04e6794efa203dd5264c6f7e0ef78e57fe934b0d26cb994eec76"
|
||||
"sig": "3045022100cc308ae7d390fa782ee3376ddfaa929835016e86dad81f69e2de7ec1e174432e02205fb19906a31cce146c29624443c0d0c2f33ee80dac39d72114f939607cc22937"
|
||||
},
|
||||
{
|
||||
"keyid": "a687e5bf4fab82b0ee58d46e05c9535145a2c9afb458f43d42b45ca0fdce2a70",
|
||||
"sig": "3045022060826496557144eb1649893ed5f6f4ea54536feb0ca82f8b89ae641be39743e5022100ad7118b5e9d4837326206e412fc6da2999925d110328a7c166b06c624336c93f"
|
||||
"sig": "304502203f8aff7a30e05a8c3d904b671ab1a6e4e8a6f508b7cfa0c780e72976bee7a227022100f64c9b765526f34d9ea16339cf238893e1c3368b4f0910a61a1af27dda01ebb9"
|
||||
},
|
||||
{
|
||||
"keyid": "183e64f37670dc13ca0d28995a3053f3740954ddce44321a41e46534cf44e632",
|
||||
"sig": "3046022100d8179439c2e73eb0c1733abee7faf832dcaea7263edcb4919891c3a247f05923022100e1a437e0797e803f9b72dc9d2d92155b0a2270c24efdd5f4b3a5d8f0b0f431a7"
|
||||
"sig": "304502202363ca249aefa6d5f61c408a32cdd079b034a7888ddf2136dc4515ed4a728418022100b04eca42bc510ccbbf5d30783aaa936b1f137ca7a017ee9d90d3710432da0427"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "root",
|
||||
"consistent_snapshot": true,
|
||||
"expires": "2026-01-22T13:05:59Z",
|
||||
"expires": "2026-06-22T13:27:01Z",
|
||||
"keys": {
|
||||
"0c87432c3bf09fd99189fdc32fa5eaedf4e4a5fac7bab73fa04a2e0fc64af6f5": {
|
||||
"keyid_hash_algorithms": [
|
||||
@@ -138,7 +134,7 @@
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0",
|
||||
"version": 13,
|
||||
"version": 14,
|
||||
"x-tuf-on-ci-expiry-period": 197,
|
||||
"x-tuf-on-ci-signing-period": 46
|
||||
}
|
||||
|
||||
+4
-4
@@ -2,15 +2,15 @@
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "0c87432c3bf09fd99189fdc32fa5eaedf4e4a5fac7bab73fa04a2e0fc64af6f5",
|
||||
"sig": "3044022043cdc6f2ee47ee7b4486ab92ce58424ef0b7b351a47853ea68316b67133a4a69022037c5cd433cc2cde76558c579c59a14dd9fc0bc85c496feaa17d90896cd4145fb"
|
||||
"sig": "3046022100a42f44341870864aa7e4f94af642ed68e09890aa109d76947276e24f13c315f2022100c3efb5500a4b67cb03a0fe708db32d8f5f151aad4bbacfd6679437e8c5fa5f9f"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "snapshot",
|
||||
"expires": "2035-10-08T16:46:31Z",
|
||||
"expires": "2035-11-24T12:02:06Z",
|
||||
"meta": {
|
||||
"registry.npmjs.org.json": {
|
||||
"version": 6
|
||||
"version": 7
|
||||
},
|
||||
"rekor.json": {
|
||||
"hashes": {
|
||||
@@ -49,6 +49,6 @@
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0",
|
||||
"version": 162
|
||||
"version": 163
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -2,18 +2,18 @@
|
||||
"signatures": [
|
||||
{
|
||||
"keyid": "0c87432c3bf09fd99189fdc32fa5eaedf4e4a5fac7bab73fa04a2e0fc64af6f5",
|
||||
"sig": "3046022100baf8a66a62531e9db32df4a1475099798cc6126add00193c8b641ed3dfb83b2c022100eedbc40511f1f72459b95188995917ad564992a2258436a96d27885c063b7de1"
|
||||
"sig": "3046022100d7ef32458ba07441f1d840bae2d7cf5740ec01462499439e02f8ad9b5c53777f0221009c56763e60f8311a45c148f4276163c9f2b241ce0da65202f92f5de4ce2e4445"
|
||||
}
|
||||
],
|
||||
"signed": {
|
||||
"_type": "timestamp",
|
||||
"expires": "2025-11-02T01:55:53Z",
|
||||
"expires": "2026-02-12T13:42:54Z",
|
||||
"meta": {
|
||||
"snapshot.json": {
|
||||
"version": 162
|
||||
"version": 163
|
||||
}
|
||||
},
|
||||
"spec_version": "1.0",
|
||||
"version": 498
|
||||
"version": 587
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user