1
6 package in_toto
7
8 import (
9 "crypto/x509"
10 "errors"
11 "fmt"
12 "io"
13 "os"
14 "path"
15 "path/filepath"
16 "reflect"
17 "regexp"
18 "strings"
19 "time"
20 )
21
22
23 var ErrInspectionRunDirIsSymlink = errors.New("runDir is a symlink. This is a security risk")
24
25 var ErrNotLayout = errors.New("verification workflow passed a non-layout")
26
27
45 func RunInspections(layout Layout, runDir string, lineNormalization bool, useDSSE bool) (map[string]Metadata, error) {
46 inspectionMetadata := make(map[string]Metadata)
47
48 for _, inspection := range layout.Inspect {
49
50 paths := []string{"."}
51 if runDir != "" {
52 paths = []string{runDir}
53 }
54
55 linkEnv, err := InTotoRun(inspection.Name, runDir, paths, paths,
56 inspection.Run, Key{}, []string{"sha256"}, nil, nil, lineNormalization, false, useDSSE)
57
58 if err != nil {
59 return nil, err
60 }
61
62 retVal := linkEnv.GetPayload().(Link).ByProducts["return-value"]
63 if retVal != float64(0) {
64 return nil, fmt.Errorf("inspection command '%s' of inspection '%s'"+
65 " returned a non-zero value: %d", inspection.Run, inspection.Name,
66 retVal)
67 }
68
69
70 linkName := fmt.Sprintf(LinkNameFormatShort, inspection.Name)
71 if err := linkEnv.Dump(linkName); err != nil {
72 fmt.Printf("JSON serialization or writing failed: %s", err)
73 }
74
75 inspectionMetadata[inspection.Name] = linkEnv
76 }
77 return inspectionMetadata, nil
78 }
79
80
81
82 func verifyMatchRule(ruleData map[string]string,
83 srcArtifacts map[string]interface{}, srcArtifactQueue Set,
84 itemsMetadata map[string]Metadata) Set {
85 consumed := NewSet()
86
87 dstLinkEnv, exists := itemsMetadata[ruleData["dstName"]]
88 if !exists {
89
90
91 return consumed
92 }
93
94
95 var dstArtifacts map[string]interface{}
96 switch ruleData["dstType"] {
97 case "materials":
98 dstArtifacts = dstLinkEnv.GetPayload().(Link).Materials
99 case "products":
100 dstArtifacts = dstLinkEnv.GetPayload().(Link).Products
101 }
102
103
104 if ruleData["pattern"] != "" {
105 ruleData["pattern"] = path.Clean(ruleData["pattern"])
106 }
107 for k := range srcArtifacts {
108 if path.Clean(k) != k {
109 srcArtifacts[path.Clean(k)] = srcArtifacts[k]
110 delete(srcArtifacts, k)
111 }
112 }
113 for k := range dstArtifacts {
114 if path.Clean(k) != k {
115 dstArtifacts[path.Clean(k)] = dstArtifacts[k]
116 delete(dstArtifacts, k)
117 }
118 }
119
120
121
122 for _, prefix := range []string{"srcPrefix", "dstPrefix"} {
123 if ruleData[prefix] != "" {
124 ruleData[prefix] = path.Clean(ruleData[prefix])
125 if !strings.HasSuffix(ruleData[prefix], "/") {
126 ruleData[prefix] += "/"
127 }
128 }
129 }
130
131 for srcPath := range srcArtifactQueue {
132
133
134 srcBasePath := strings.TrimPrefix(srcPath, ruleData["srcPrefix"])
135
136
137 matched, err := match(ruleData["pattern"], srcBasePath)
138 if err != nil || !matched {
139 continue
140 }
141
142
143
144 dstPath := path.Clean(path.Join(ruleData["dstPrefix"], srcBasePath))
145
146
147 dstArtifact, exists := dstArtifacts[dstPath]
148
149 if !exists {
150 continue
151 }
152
153
154 if !reflect.DeepEqual(srcArtifacts[srcPath], dstArtifact) {
155 continue
156 }
157
158
159
160
161 consumed.Add(srcPath)
162 }
163 return consumed
164 }
165
166
183 func VerifyArtifacts(items []interface{},
184 itemsMetadata map[string]Metadata) error {
185
186 for _, itemI := range items {
187
188
189 var itemName string
190 var expectedMaterials [][]string
191 var expectedProducts [][]string
192
193 switch item := itemI.(type) {
194 case Step:
195 itemName = item.Name
196 expectedMaterials = item.ExpectedMaterials
197 expectedProducts = item.ExpectedProducts
198
199 case Inspection:
200 itemName = item.Name
201 expectedMaterials = item.ExpectedMaterials
202 expectedProducts = item.ExpectedProducts
203
204 default:
205 return fmt.Errorf("VerifyArtifacts received an item of invalid type,"+
206 " elements of passed slice 'items' must be one of 'Step' or"+
207 " 'Inspection', got: '%s'", reflect.TypeOf(item))
208 }
209
210
211 srcLinkEnv, exists := itemsMetadata[itemName]
212 if !exists {
213 return fmt.Errorf("VerifyArtifacts could not find metadata"+
214 " for item '%s', got: '%s'", itemName, itemsMetadata)
215 }
216
217
218
219 materials := srcLinkEnv.GetPayload().(Link).Materials
220 products := srcLinkEnv.GetPayload().(Link).Products
221
222
223
224
225 materialPaths := NewSet()
226 for _, p := range InterfaceKeyStrings(materials) {
227 materialPaths.Add(path.Clean(p))
228 }
229 productPaths := NewSet()
230 for _, p := range InterfaceKeyStrings(products) {
231 productPaths.Add(path.Clean(p))
232 }
233
234
235
236
237 created := productPaths.Difference(materialPaths)
238 deleted := materialPaths.Difference(productPaths)
239 remained := materialPaths.Intersection(productPaths)
240 modified := NewSet()
241 for name := range remained {
242 if !reflect.DeepEqual(materials[name], products[name]) {
243 modified.Add(name)
244 }
245 }
246
247
248
249 verificationDataList := []map[string]interface{}{
250 {
251 "srcType": "materials",
252 "rules": expectedMaterials,
253 "artifacts": materials,
254 "artifactPaths": materialPaths,
255 },
256 {
257 "srcType": "products",
258 "rules": expectedProducts,
259 "artifacts": products,
260 "artifactPaths": productPaths,
261 },
262 }
263
264
265
266
267
268 for _, verificationData := range verificationDataList {
269
270
271
272 rules := verificationData["rules"].([][]string)
273 artifacts := verificationData["artifacts"].(map[string]interface{})
274
275
276
277
278
279
280
281 queue := verificationData["artifactPaths"].(Set)
282
283
284
285
286
287
288 for _, rule := range rules {
289
290
291 ruleData, err := UnpackRule(rule)
292 if err != nil {
293 return err
294 }
295
296
297
298 filtered := queue.Filter(path.Clean(ruleData["pattern"]))
299
300 var consumed Set
301 switch ruleData["type"] {
302 case "match":
303
304 consumed = verifyMatchRule(ruleData, artifacts, queue, itemsMetadata)
305
306 case "allow":
307
308 consumed = filtered
309
310 case "create":
311
312 consumed = filtered.Intersection(created)
313
314 case "delete":
315
316 consumed = filtered.Intersection(deleted)
317
318 case "modify":
319
320 consumed = filtered.Intersection(modified)
321
322 case "disallow":
323
324 if len(filtered) > 0 {
325 return fmt.Errorf("artifact verification failed for %s '%s',"+
326 " %s %s disallowed by rule %s",
327 reflect.TypeOf(itemI).Name(), itemName,
328 verificationData["srcType"], filtered.Slice(), rule)
329 }
330 case "require":
331
332
333 if !queue.Has(ruleData["pattern"]) {
334 return fmt.Errorf("artifact verification failed for %s in REQUIRE '%s',"+
335 " because %s is not in %s", verificationData["srcType"],
336 ruleData["pattern"], ruleData["pattern"], queue.Slice())
337 }
338 }
339
340 queue = queue.Difference(consumed)
341
342
343 }
344 }
345 }
346 return nil
347 }
348
349
367 func ReduceStepsMetadata(layout Layout,
368 stepsMetadata map[string]map[string]Metadata) (map[string]Metadata,
369 error) {
370 stepsMetadataReduced := make(map[string]Metadata)
371
372 for _, step := range layout.Steps {
373 linksPerStep, ok := stepsMetadata[step.Name]
374
375 if !ok || len(linksPerStep) < 1 {
376 panic("Could not reduce metadata for step '" + step.Name +
377 "', no link metadata found.")
378 }
379
380
381
382 var referenceKeyID string
383 var referenceLinkEnv Metadata
384 for keyID, linkEnv := range linksPerStep {
385 referenceLinkEnv = linkEnv
386 referenceKeyID = keyID
387 break
388 }
389
390
391 if len(linksPerStep) == 1 {
392 stepsMetadataReduced[step.Name] = referenceLinkEnv
393
394
395 } else {
396
397
398
399
400 for keyID, linkEnv := range linksPerStep {
401 if !reflect.DeepEqual(linkEnv.GetPayload().(Link).Materials,
402 referenceLinkEnv.GetPayload().(Link).Materials) ||
403 !reflect.DeepEqual(linkEnv.GetPayload().(Link).Products,
404 referenceLinkEnv.GetPayload().(Link).Products) {
405 return nil, fmt.Errorf("link '%s' and '%s' have different"+
406 " artifacts",
407 fmt.Sprintf(LinkNameFormat, step.Name, referenceKeyID),
408 fmt.Sprintf(LinkNameFormat, step.Name, keyID))
409 }
410 }
411
412 stepsMetadataReduced[step.Name] = referenceLinkEnv
413 }
414 }
415 return stepsMetadataReduced, nil
416 }
417
418
424 func VerifyStepCommandAlignment(layout Layout,
425 stepsMetadata map[string]map[string]Metadata) {
426 for _, step := range layout.Steps {
427 linksPerStep, ok := stepsMetadata[step.Name]
428
429 if !ok || len(linksPerStep) < 1 {
430 panic("Could not verify command alignment for step '" + step.Name +
431 "', no link metadata found.")
432 }
433
434 for signerKeyID, linkEnv := range linksPerStep {
435 expectedCommandS := strings.Join(step.ExpectedCommand, " ")
436 executedCommandS := strings.Join(linkEnv.GetPayload().(Link).Command, " ")
437
438 if expectedCommandS != executedCommandS {
439 linkName := fmt.Sprintf(LinkNameFormat, step.Name, signerKeyID)
440 fmt.Printf("WARNING: Expected command for step '%s' (%s) and command"+
441 " reported by '%s' (%s) differ.\n",
442 step.Name, expectedCommandS, linkName, executedCommandS)
443 }
444 }
445 }
446 }
447
448
454 func LoadLayoutCertificates(layout Layout, intermediatePems [][]byte) (*x509.CertPool, *x509.CertPool, error) {
455 rootPool := x509.NewCertPool()
456 for _, certPem := range layout.RootCas {
457 ok := rootPool.AppendCertsFromPEM([]byte(certPem.KeyVal.Certificate))
458 if !ok {
459 return nil, nil, fmt.Errorf("failed to load root certificates for layout")
460 }
461 }
462
463 intermediatePool := x509.NewCertPool()
464 for _, intermediatePem := range layout.IntermediateCas {
465 ok := intermediatePool.AppendCertsFromPEM([]byte(intermediatePem.KeyVal.Certificate))
466 if !ok {
467 return nil, nil, fmt.Errorf("failed to load intermediate certificates for layout")
468 }
469 }
470
471 for _, intermediatePem := range intermediatePems {
472 ok := intermediatePool.AppendCertsFromPEM(intermediatePem)
473 if !ok {
474 return nil, nil, fmt.Errorf("failed to load provided intermediate certificates")
475 }
476 }
477
478 return rootPool, intermediatePool, nil
479 }
480
481
505 func VerifyLinkSignatureThesholds(layout Layout,
506 stepsMetadata map[string]map[string]Metadata, rootCertPool, intermediateCertPool *x509.CertPool) (
507 map[string]map[string]Metadata, error) {
508
509
510 stepsMetadataVerified := make(map[string]map[string]Metadata)
511
512
513
514 for _, step := range layout.Steps {
515 var stepErr error
516
517
518
519 linksPerStepVerified := make(map[string]Metadata)
520
521
522 linksPerStep, ok := stepsMetadata[step.Name]
523 if !ok || len(linksPerStep) < 1 {
524 stepErr = fmt.Errorf("no links found")
525 }
526
527
528
529
530
531 isAuthorizedSignature := false
532 for signerKeyID, linkEnv := range linksPerStep {
533 for _, authorizedKeyID := range step.PubKeys {
534 if signerKeyID == authorizedKeyID {
535 if verifierKey, ok := layout.Keys[authorizedKeyID]; ok {
536 if err := linkEnv.VerifySignature(verifierKey); err == nil {
537 linksPerStepVerified[signerKeyID] = linkEnv
538 isAuthorizedSignature = true
539 break
540 }
541 }
542 }
543 }
544
545
546
547 if !isAuthorizedSignature {
548 sig, err := linkEnv.GetSignatureForKeyID(signerKeyID)
549 if err != nil {
550 stepErr = err
551 continue
552 }
553
554 cert, err := sig.GetCertificate()
555 if err != nil {
556 stepErr = err
557 continue
558 }
559
560
561 err = step.CheckCertConstraints(cert, layout.RootCAIDs(), rootCertPool, intermediateCertPool)
562 if err != nil {
563 stepErr = err
564 continue
565 }
566
567 err = linkEnv.VerifySignature(cert)
568 if err != nil {
569 stepErr = err
570 continue
571 }
572
573 linksPerStepVerified[signerKeyID] = linkEnv
574 }
575 }
576
577
578 stepsMetadataVerified[step.Name] = linksPerStepVerified
579
580 if len(linksPerStepVerified) < step.Threshold {
581 linksPerStep := stepsMetadata[step.Name]
582 return nil, fmt.Errorf("step '%s' requires '%d' link metadata file(s)."+
583 " '%d' out of '%d' available link(s) have a valid signature from an"+
584 " authorized signer: %v", step.Name, step.Threshold,
585 len(linksPerStepVerified), len(linksPerStep), stepErr)
586 }
587 }
588 return stepsMetadataVerified, nil
589 }
590
591
618 func LoadLinksForLayout(layout Layout, linkDir string) (map[string]map[string]Metadata, error) {
619 stepsMetadata := make(map[string]map[string]Metadata)
620
621 for _, step := range layout.Steps {
622 linksPerStep := make(map[string]Metadata)
623
624
625 linkFiles, err := filepath.Glob(path.Join(linkDir, fmt.Sprintf(LinkGlobFormat, step.Name)))
626 if err != nil {
627 return nil, err
628 }
629
630 for _, linkPath := range linkFiles {
631 linkEnv, err := LoadMetadata(linkPath)
632 if err != nil {
633 continue
634 }
635
636
637
638 signerShortKeyID := strings.TrimSuffix(strings.TrimPrefix(filepath.Base(linkPath), step.Name+"."), ".link")
639 for _, sig := range linkEnv.Sigs() {
640 if strings.HasPrefix(sig.KeyID, signerShortKeyID) {
641 linksPerStep[sig.KeyID] = linkEnv
642 break
643 }
644 }
645 }
646
647 if len(linksPerStep) < step.Threshold {
648 return nil, fmt.Errorf("step '%s' requires '%d' link metadata file(s),"+
649 " found '%d'", step.Name, step.Threshold, len(linksPerStep))
650 }
651
652 stepsMetadata[step.Name] = linksPerStep
653 }
654
655 return stepsMetadata, nil
656 }
657
658
662 func VerifyLayoutExpiration(layout Layout) error {
663 expires, err := time.Parse(ISO8601DateSchema, layout.Expires)
664 if err != nil {
665 return err
666 }
667
668 if time.Until(expires) < 0 {
669 return fmt.Errorf("layout has expired on '%s'", expires)
670 }
671 return nil
672 }
673
674
681 func VerifyLayoutSignatures(layoutEnv Metadata,
682 layoutKeys map[string]Key) error {
683 if len(layoutKeys) < 1 {
684 return fmt.Errorf("layout verification requires at least one key")
685 }
686
687 for _, key := range layoutKeys {
688 if err := layoutEnv.VerifySignature(key); err != nil {
689 return err
690 }
691 }
692 return nil
693 }
694
695
704 func GetSummaryLink(layout Layout, stepsMetadataReduced map[string]Metadata,
705 stepName string, useDSSE bool) (Metadata, error) {
706 var summaryLink Link
707 if len(layout.Steps) > 0 {
708 firstStepLink := stepsMetadataReduced[layout.Steps[0].Name]
709 lastStepLink := stepsMetadataReduced[layout.Steps[len(layout.Steps)-1].Name]
710
711 summaryLink.Materials = firstStepLink.GetPayload().(Link).Materials
712 summaryLink.Name = stepName
713 summaryLink.Type = firstStepLink.GetPayload().(Link).Type
714
715 summaryLink.Products = lastStepLink.GetPayload().(Link).Products
716 summaryLink.ByProducts = lastStepLink.GetPayload().(Link).ByProducts
717
718
719
720 summaryLink.Command = lastStepLink.GetPayload().(Link).Command
721 }
722
723 if useDSSE {
724 env := &Envelope{}
725 if err := env.SetPayload(summaryLink); err != nil {
726 return nil, err
727 }
728
729 return env, nil
730 }
731
732 return &Metablock{Signed: summaryLink}, nil
733 }
734
735
740 func VerifySublayouts(layout Layout,
741 stepsMetadataVerified map[string]map[string]Metadata,
742 superLayoutLinkPath string, intermediatePems [][]byte, lineNormalization bool) (map[string]map[string]Metadata, error) {
743 for stepName, linkData := range stepsMetadataVerified {
744 for keyID, metadata := range linkData {
745 if _, ok := metadata.GetPayload().(Layout); ok {
746 layoutKeys := make(map[string]Key)
747 layoutKeys[keyID] = layout.Keys[keyID]
748
749 sublayoutLinkDir := fmt.Sprintf(SublayoutLinkDirFormat,
750 stepName, keyID)
751 sublayoutLinkPath := filepath.Join(superLayoutLinkPath,
752 sublayoutLinkDir)
753 summaryLink, err := InTotoVerify(metadata, layoutKeys,
754 sublayoutLinkPath, stepName, make(map[string]string), intermediatePems, lineNormalization)
755 if err != nil {
756 return nil, err
757 }
758 linkData[keyID] = summaryLink
759 }
760
761 }
762 }
763 return stepsMetadataVerified, nil
764 }
765
766
767
768 func substituteParamatersInSlice(replacer *strings.Replacer, slice []string) []string {
769 newSlice := make([]string, 0)
770 for _, item := range slice {
771 newSlice = append(newSlice, replacer.Replace(item))
772 }
773 return newSlice
774 }
775
776 func substituteParametersInSliceOfSlices(replacer *strings.Replacer,
777 slice [][]string) [][]string {
778 newSlice := make([][]string, 0)
779 for _, item := range slice {
780 newSlice = append(newSlice, substituteParamatersInSlice(replacer,
781 item))
782 }
783 return newSlice
784 }
785
786
796 func SubstituteParameters(layout Layout,
797 parameterDictionary map[string]string) (Layout, error) {
798
799 if len(parameterDictionary) == 0 {
800 return layout, nil
801 }
802
803 parameters := make([]string, 0)
804
805 re := regexp.MustCompile("^[a-zA-Z0-9_-]+$")
806
807 for parameter, value := range parameterDictionary {
808 parameterFormatCheck := re.MatchString(parameter)
809 if !parameterFormatCheck {
810 return layout, fmt.Errorf("invalid format for parameter")
811 }
812
813 parameters = append(parameters, "{"+parameter+"}")
814 parameters = append(parameters, value)
815 }
816
817 replacer := strings.NewReplacer(parameters...)
818
819 for i := range layout.Steps {
820 layout.Steps[i].ExpectedMaterials = substituteParametersInSliceOfSlices(
821 replacer, layout.Steps[i].ExpectedMaterials)
822 layout.Steps[i].ExpectedProducts = substituteParametersInSliceOfSlices(
823 replacer, layout.Steps[i].ExpectedProducts)
824 layout.Steps[i].ExpectedCommand = substituteParamatersInSlice(replacer,
825 layout.Steps[i].ExpectedCommand)
826 }
827
828 for i := range layout.Inspect {
829 layout.Inspect[i].ExpectedMaterials =
830 substituteParametersInSliceOfSlices(replacer,
831 layout.Inspect[i].ExpectedMaterials)
832 layout.Inspect[i].ExpectedProducts =
833 substituteParametersInSliceOfSlices(replacer,
834 layout.Inspect[i].ExpectedProducts)
835 layout.Inspect[i].Run = substituteParamatersInSlice(replacer,
836 layout.Inspect[i].Run)
837 }
838
839 return layout, nil
840 }
841
842
871 func InTotoVerify(layoutEnv Metadata, layoutKeys map[string]Key,
872 linkDir string, stepName string, parameterDictionary map[string]string, intermediatePems [][]byte, lineNormalization bool) (
873 Metadata, error) {
874
875
876 if err := VerifyLayoutSignatures(layoutEnv, layoutKeys); err != nil {
877 return nil, err
878 }
879
880 useDSSE := false
881 if _, ok := layoutEnv.(*Envelope); ok {
882 useDSSE = true
883 }
884
885
886 layout, ok := layoutEnv.GetPayload().(Layout)
887 if !ok {
888 return nil, ErrNotLayout
889 }
890
891
892 if err := VerifyLayoutExpiration(layout); err != nil {
893 return nil, err
894 }
895
896
897 layout, err := SubstituteParameters(layout, parameterDictionary)
898 if err != nil {
899 return nil, err
900 }
901
902 rootCertPool, intermediateCertPool, err := LoadLayoutCertificates(layout, intermediatePems)
903 if err != nil {
904 return nil, err
905 }
906
907
908 stepsMetadata, err := LoadLinksForLayout(layout, linkDir)
909 if err != nil {
910 return nil, err
911 }
912
913
914 stepsMetadataVerified, err := VerifyLinkSignatureThesholds(layout,
915 stepsMetadata, rootCertPool, intermediateCertPool)
916 if err != nil {
917 return nil, err
918 }
919
920
921 stepsSublayoutVerified, err := VerifySublayouts(layout,
922 stepsMetadataVerified, linkDir, intermediatePems, lineNormalization)
923 if err != nil {
924 return nil, err
925 }
926
927
928 VerifyStepCommandAlignment(layout, stepsSublayoutVerified)
929
930
931
932
933
934 stepsMetadataReduced, err := ReduceStepsMetadata(layout,
935 stepsSublayoutVerified)
936 if err != nil {
937 return nil, err
938 }
939
940
941 if err = VerifyArtifacts(layout.stepsAsInterfaceSlice(),
942 stepsMetadataReduced); err != nil {
943 return nil, err
944 }
945
946 inspectionMetadata, err := RunInspections(layout, "", lineNormalization, useDSSE)
947 if err != nil {
948 return nil, err
949 }
950
951
952
953 for k, v := range stepsMetadataReduced {
954 inspectionMetadata[k] = v
955 }
956
957 if err = VerifyArtifacts(layout.inspectAsInterfaceSlice(),
958 inspectionMetadata); err != nil {
959 return nil, err
960 }
961
962 summaryLink, err := GetSummaryLink(layout, stepsMetadataReduced, stepName, useDSSE)
963 if err != nil {
964 return nil, err
965 }
966
967 return summaryLink, nil
968 }
969
970
974 func InTotoVerifyWithDirectory(layoutEnv Metadata, layoutKeys map[string]Key,
975 linkDir string, runDir string, stepName string, parameterDictionary map[string]string, intermediatePems [][]byte, lineNormalization bool) (
976 Metadata, error) {
977
978
979
980 info, err := os.Stat(runDir)
981 if err != nil {
982 return nil, err
983 }
984
985
986 if info.Mode()&os.ModeSymlink == os.ModeSymlink {
987 return nil, ErrInspectionRunDirIsSymlink
988 }
989
990
991 err = isWritable(runDir)
992 if err != nil {
993 return nil, err
994 }
995
996
997
998 f, err := os.Open(runDir)
999 if err != nil {
1000 return nil, err
1001 }
1002 defer f.Close()
1003
1004
1005 _, err = f.Readdirnames(1)
1006
1007 if err == io.EOF {
1008 return nil, err
1009 }
1010 err = f.Close()
1011 if err != nil {
1012 return nil, err
1013 }
1014
1015
1016 if err := VerifyLayoutSignatures(layoutEnv, layoutKeys); err != nil {
1017 return nil, err
1018 }
1019
1020 useDSSE := false
1021 if _, ok := layoutEnv.(*Envelope); ok {
1022 useDSSE = true
1023 }
1024
1025
1026 layout, ok := layoutEnv.GetPayload().(Layout)
1027 if !ok {
1028 return nil, ErrNotLayout
1029 }
1030
1031
1032 if err := VerifyLayoutExpiration(layout); err != nil {
1033 return nil, err
1034 }
1035
1036
1037 layout, err = SubstituteParameters(layout, parameterDictionary)
1038 if err != nil {
1039 return nil, err
1040 }
1041
1042 rootCertPool, intermediateCertPool, err := LoadLayoutCertificates(layout, intermediatePems)
1043 if err != nil {
1044 return nil, err
1045 }
1046
1047
1048 stepsMetadata, err := LoadLinksForLayout(layout, linkDir)
1049 if err != nil {
1050 return nil, err
1051 }
1052
1053
1054 stepsMetadataVerified, err := VerifyLinkSignatureThesholds(layout,
1055 stepsMetadata, rootCertPool, intermediateCertPool)
1056 if err != nil {
1057 return nil, err
1058 }
1059
1060
1061 stepsSublayoutVerified, err := VerifySublayouts(layout,
1062 stepsMetadataVerified, linkDir, intermediatePems, lineNormalization)
1063 if err != nil {
1064 return nil, err
1065 }
1066
1067
1068 VerifyStepCommandAlignment(layout, stepsSublayoutVerified)
1069
1070
1071
1072
1073
1074 stepsMetadataReduced, err := ReduceStepsMetadata(layout,
1075 stepsSublayoutVerified)
1076 if err != nil {
1077 return nil, err
1078 }
1079
1080
1081 if err = VerifyArtifacts(layout.stepsAsInterfaceSlice(),
1082 stepsMetadataReduced); err != nil {
1083 return nil, err
1084 }
1085
1086 inspectionMetadata, err := RunInspections(layout, runDir, lineNormalization, useDSSE)
1087 if err != nil {
1088 return nil, err
1089 }
1090
1091
1092
1093 for k, v := range stepsMetadataReduced {
1094 inspectionMetadata[k] = v
1095 }
1096
1097 if err = VerifyArtifacts(layout.inspectAsInterfaceSlice(),
1098 inspectionMetadata); err != nil {
1099 return nil, err
1100 }
1101
1102 summaryLink, err := GetSummaryLink(layout, stepsMetadataReduced, stepName, useDSSE)
1103 if err != nil {
1104 return nil, err
1105 }
1106
1107 return summaryLink, nil
1108 }
1109
View as plain text