diff --git a/cmd/proof/errors.go b/cmd/proof/errors.go index 81ba2e3..0329efb 100644 --- a/cmd/proof/errors.go +++ b/cmd/proof/errors.go @@ -23,6 +23,8 @@ func verificationErrorCode(err error) int { switch typed.Kind { case coreerr.KindDependencyMissing: return exitcode.DependencyMiss + case coreerr.KindInternal: + return exitcode.InternalError case coreerr.KindInvalidInput: return exitcode.InvalidInput case coreerr.KindValidation: diff --git a/cmd/proof/errors_test.go b/cmd/proof/errors_test.go index 3677639..f4f53cf 100644 --- a/cmd/proof/errors_test.go +++ b/cmd/proof/errors_test.go @@ -17,6 +17,7 @@ func TestCLIErrorExitCode(t *testing.T) { } func TestVerificationErrorCodeFromTypedError(t *testing.T) { + require.Equal(t, exitcode.InternalError, verificationErrorCode(coreerr.New(coreerr.KindInternal, "x", "internal"))) require.Equal(t, exitcode.InvalidInput, verificationErrorCode(coreerr.New(coreerr.KindInvalidInput, "x", "bad input"))) require.Equal(t, exitcode.PolicyOrSchema, verificationErrorCode(coreerr.New(coreerr.KindValidation, "x", "bad schema"))) require.Equal(t, exitcode.VerificationErr, verificationErrorCode(coreerr.New(coreerr.KindVerification, "x", "bad signature"))) diff --git a/core/schema/schema.go b/core/schema/schema.go index e44b406..73e385f 100644 --- a/core/schema/schema.go +++ b/core/schema/schema.go @@ -63,7 +63,7 @@ func ListRecordTypes() []RecordType { func ValidateRecord(data []byte, recordType string) error { if err := validateWithSchema(data, "v1/proof-record-v1.schema.json"); err != nil { return coreerr.Wrap( - coreerr.KindValidation, + wrappedKind(err, coreerr.KindValidation), "schema.record.base_validation_failed", "record schema validation failed", err, @@ -85,7 +85,7 @@ func ValidateRecord(data []byte, recordType string) error { } if err := validateWithCompiledSchema(data, customSchema); err != nil { return coreerr.Wrap( - coreerr.KindValidation, + wrappedKind(err, coreerr.KindValidation), "schema.record.custom_type_validation_failed", "custom record type schema validation failed", err, @@ -96,7 +96,7 @@ func ValidateRecord(data []byte, recordType string) error { } if err := validateWithSchema(data, path); err != nil { return coreerr.Wrap( - coreerr.KindValidation, + wrappedKind(err, coreerr.KindValidation), "schema.record.type_validation_failed", "record type schema validation failed", err, @@ -205,6 +205,13 @@ func compileSchema(name string, raw []byte) (*jsonschema.Schema, error) { return compiled, nil } +func wrappedKind(err error, fallback coreerr.Kind) coreerr.Kind { + if typed, ok := coreerr.As(err); ok { + return typed.Kind + } + return fallback +} + func schemaPathForType(recordType string) (string, bool) { for _, rt := range builtins { if rt.Name == recordType { diff --git a/core/schema/schema_test.go b/core/schema/schema_test.go index ea76f01..04222ec 100644 --- a/core/schema/schema_test.go +++ b/core/schema/schema_test.go @@ -49,6 +49,15 @@ func TestValidateRecordTypedError(t *testing.T) { require.Equal(t, coreerr.KindValidation, typed.Kind) } +func TestValidateRecordMalformedJSONKeepsInvalidInputKind(t *testing.T) { + err := ValidateRecord([]byte("{"), "decision") + require.Error(t, err) + + typed, ok := coreerr.As(err) + require.True(t, ok) + require.Equal(t, coreerr.KindInvalidInput, typed.Kind) +} + func TestValidateCustomSchema(t *testing.T) { dir := t.TempDir() p := filepath.Join(dir, "custom.schema.json") diff --git a/scripts/install.sh b/scripts/install.sh index 9133f26..d3539ac 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -76,9 +76,24 @@ trap 'rm -rf "${workdir}"' EXIT base_url="https://github.com/${REPO}/releases/download/${VERSION}" checksums_path="${workdir}/checksums.txt" +sig_path="${workdir}/checksums.txt.sig" +cert_path="${workdir}/checksums.txt.pem" curl -fsSL "${base_url}/checksums.txt" -o "${checksums_path}" +if curl -fsSL "${base_url}/checksums.txt.sig" -o "${sig_path}" && \ + curl -fsSL "${base_url}/checksums.txt.pem" -o "${cert_path}"; then + if command -v cosign >/dev/null 2>&1; then + cosign verify-blob \ + --certificate "${cert_path}" \ + --signature "${sig_path}" \ + "${checksums_path}" >/dev/null + echo "verified: checksums.txt signature" + else + echo "note: cosign not found; skipped signature verification for checksums.txt" + fi +fi + asset_name="$( awk '{print $2}' "${checksums_path}" \ | grep -E "_${os}_${arch}\\.(tar\\.gz|zip)$" \ @@ -131,21 +146,6 @@ fi mkdir -p "${INSTALL_DIR}" install -m 0755 "${binary_path}" "${INSTALL_DIR}/proof" -sig_path="${workdir}/checksums.txt.sig" -cert_path="${workdir}/checksums.txt.pem" -if curl -fsSL "${base_url}/checksums.txt.sig" -o "${sig_path}" && \ - curl -fsSL "${base_url}/checksums.txt.pem" -o "${cert_path}"; then - if command -v cosign >/dev/null 2>&1; then - cosign verify-blob \ - --certificate "${cert_path}" \ - --signature "${sig_path}" \ - "${checksums_path}" >/dev/null - echo "verified: checksums.txt signature" - else - echo "note: cosign not found; skipped signature verification for checksums.txt" - fi -fi - echo "installed: ${INSTALL_DIR}/proof (${VERSION}, ${os}/${arch})" case ":${PATH}:" in *:"${INSTALL_DIR}":*) ;;