Giter Club home page Giter Club logo

in-toto-golang's Introduction

in-toto Build CII Best Practices Documentation Status

in-toto provides a framework to protect the integrity of the software supply chain. It does so by verifying that each task in the chain is carried out as planned, by authorized personnel only, and that the product is not tampered with in transit.

in-toto requires a project owner to create a layout. A layout lists the sequence of steps of the software supply chain, and the functionaries authorized to perform these steps. When a functionary performs a step in-toto gathers information about the used command and the related files and stores it in a link metadata file. As a consequence link files provide the required evidence to establish a continuous chain that can be validated against the steps defined in the layout.

The layout, signed by the project owners, together with the links, signed by the designated functionaries, are released as part of the final product, and can be validated manually or via automated tooling in, e.g. a package manager.

Getting Started

Installation

in-toto is available on PyPI and can be installed via pip. See in-toto.readthedocs.io to learn about system dependencies and installation alternatives and recommendations.

pip install in-toto

Create layout, run supply chain steps and verify final product

Layout

The in-toto software supply chain layout consists of the following parts:

  • expiration date
  • readme (an optional description of the supply chain)
  • functionary keys (public keys, used to verify link metadata signatures)
  • signatures (one or more layout signatures created with the project owner key(s))
  • software supply chain steps correspond to steps carried out by a functionary as part of the software supply chain. The steps defined in the layout list the functionaries who are authorized to carry out the step (by key id). Steps require a unique name to associate them (upon verification) with link metadata that is created when a functionary carries out the step using the in-toto tools. Additionally, steps must have material and product rules which define the files a step is supposed to operate on. Material and product rules are described in the section below.
  • inspections define commands to be run during the verification process and can also list material and product rules.

Take a look at the demo layout creation example for further information on how to create an in-toto layout.

Artifact Rules

A software supply chain usually operates on a set of files, such as source code, executables, packages, or the like. in-toto calls these files artifacts. A material is an artifact that will be used when a step or inspection is carried out. Likewise, a product is an artifact that results from carrying out a step.

The in-toto layout provides a simple rule language to authorize or enforce the artifacts of a step and to chain them together. This adds the following guarantees for any given step or inspection:

  • Only artifacts authorized by the project owner are created, modified or deleted,
  • each defined creation, modification or deletion is enforced, and also
  • restricted to the scope of its definition, which chains subsequent steps and inspections together.

Note that it is up to you to properly secure your supply chain, by authorizing, enforcing and chaining materials and products using any and usually multiple of the following rules:

  • CREATE <pattern>
  • DELETE <pattern>
  • MODIFY <pattern>
  • ALLOW <pattern>
  • DISALLOW <pattern>
  • REQUIRE <file>
  • MATCH <pattern> [IN <source-path-prefix>] WITH (MATERIALS|PRODUCTS) [IN <destination-path-prefix>] FROM <step>

Rule arguments specified as <pattern> allow for Unix shell-style wildcards as implemented by Python's fnmatch.

in-toto's Artifact Rules, by default, allow artifacts to exist if they are not explicitly disallowed. As such, a DISALLOW * invocation is recommended as the final rule for most step definitions. To learn more about the different rule types, their guarantees and how they are applied, take a look at the Artifact Rules section of the in-toto specification.

Carrying out software supply chain steps

in-toto-run

in-toto-run is used to execute a step in the software supply chain. This can be anything relevant to the project such as tagging a release with git, running a test, or building a binary. The relevant step name and command are passed as arguments, along with materials, which are files required for that step's command to execute, and products which are files expected as a result of the execution of that command. These, and other relevant details pertaining to the step are stored in a link file, which is signed using the functionary's key.

If materials are not passed to the command, the link file generated just doesn't record them. Similarly, if the execution of a command via in-toto-run doesn't result in any products, they're not recorded in the link file. Any files that are modified or used in any way during the execution of the command are not recorded in the link file unless explicitly passed as artifacts. Conversely, any materials or products passed to the command are recorded in the link file even if they're not part of the execution of the command.

See this simple usage example from the demo application for more details. For a detailed list of all the command line arguments, run in-toto-run --help or look at the online documentation.

in-toto-record

in-toto-record works similar to in-toto-run but can be used for multi-part software supply chain steps, i.e. steps that are not carried out by a single command. Use in-toto-record start ... to create a preliminary link file that only records the materials, then run the commands of that step or edit files manually and finally use in-toto-record stop ... to record the products and generate the actual link metadata file. For a detailed list of all command line arguments and their usage, run in-toto-record start --help or in-toto-record stop --help, or look at the online documentation.

Release final product

In order to verify the final product with in-toto, the verifier must have access to the layout, the *.link files, and the project owner's public key(s).

Verification

Use in-toto-verify on the final product to verify that

  • the layout was signed with the project owner's private key(s),
  • has not expired,
  • each step was performed and signed by the authorized functionary,
  • the functionaries used the commands, they were supposed to use,
  • materials and products of each step were in place as defined by the rules, and
  • run the defined inspections

For a detailed list of all command line arguments and their usage, run in-toto-verify --help or look at the online documentation.

Signatures

in-toto-sign is a metadata signature helper tool to add, replace, and verify signatures within in-toto Link or Layout metadata, with options to:

  • replace (default) or add signature(s), with layout metadata able to be signed by multiple keys at once while link metadata can only be signed by one key at a time
  • write signed metadata to a specified path (if no output path is specified, layout metadata is written to the path of the input file while link metadata is written to <name>.<keyid prefix>.link)
  • verify signatures

This tool serves well to re-sign test and demo data. For example, it can be used if metadata formats or signing routines change.

For a detailed list of all command line arguments and their usage, run in-toto-sign --help or look at the online documentation.

in-toto demo

You can try in-toto by running the demo application. The demo basically outlines three users viz., Alice (project owner), Bob (functionary) and Carl (functionary) and how in-toto helps to specify a project layout and verify that the layout has been followed in a correct manner.

Specification

You can read more about how in-toto works by taking a look at the specification.

Security Issues and Bugs

See SECURITY.md.

Governance and Contributing

For information about in-toto's governance and contributing guidelines, see GOVERNANCE.md and CONTRIBUTING.md.

Acknowledgments

This project is managed by Prof. Santiago Torres-Arias at Purdue University. It is worked on by many folks in academia and industry, including members of the Secure Systems Lab at NYU and the NJIT Cybersecurity Research Center.

This research was supported by the Defense Advanced Research Projects Agency (DARPA), the Air Force Research Laboratory (AFRL), and the US National Science Foundation (NSF). Any opinions, findings, and conclusions or recommendations expressed in this material are those of the authors and do not necessarily reflect the views of DARPA, AFRL, and NSF. The United States Government is authorized to reproduce and distribute reprints notwithstanding any copyright notice herein.

in-toto-golang's People

Contributors

adityasaky avatar alanssitis avatar asraa avatar ayush159 avatar chuangw6 avatar cindykimxp avatar dentrax avatar dependabot[bot] avatar developer-guy avatar forrin avatar lehors avatar lukpueh avatar marcelamelara avatar mikhailswift avatar msuozzo avatar omerlh avatar pcaderno avatar pradyumnakrishna avatar puerco avatar pxp928 avatar santiagotorres avatar seb-bah avatar shibumi avatar sudo-bmitch avatar viveksahu26 avatar wlynch avatar yaxhveer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

in-toto-golang's Issues

subsetCheck function as part of our Set implementation

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:
Right now the SubsetCheck function operates on string slices. It might makes sense to use Sets in our constant getter functions.

Current behavior:
constant getter functions return string slices + subsetCheck operates on string slices.

Expected behavior:
constant getter functions and subsetcheck function should operate on our Set implementation.

Support parameter substitution

Description of issue or feature request:
Parameter substitution is not supported by this implementation.

Current behavior: Parameter substitution is not performed

Expected behavior: This implementation should provide a similar interface for integrators to perform parameter substitution.

GPG support

Description of issue or feature request:

The in-toto python implementation supports gpg keys and signatures. We could add this feature using the existing golang pgp support. (the module exists, but finding it is a pain...)
Current behavior: any metadata with rfc4880 packets will fail to load

Expected behavior: They should be parsed and handled appropriately

in-toto-run capturing implementation

feature request:

The golang implementation is missing functions for capturing changes right now.
This issue tries to give a small roadmap on implementing the capturing functionality.

For this I had a look on the python implementation and tried to conclude which funtions are missing in the golang implementation. I hope I understood this correct.

What we have right now:

  • Reading and generating hashes for multiple files: RecordArtifacts()
  • Converting errors to an exit code: WaitErrToExitCode()
  • Running commands via RunCommands()
  • Hashing files , running commands on them, hashing files again: InTotoRun()

What is missing?

  • signing the linked metadata
  • generating .link files?
  • arbitrary RecordStart/RecordStop functions

Is this the actual functionality we want or did I misunderstood something?
What I didn't see in the python implementation is triggering intoto via another process (for example TravisCI triggers an intoto-run for hashing artifacts.. doing something like building artifacts.. and triggering again for retrieving hashes for artifacts + recording materials and products.
Is this covered via the RecordStart and RecordStop functionality? How are these functions different to our RecordArtifacts functions?

I am a little bit confused about this topic, I think ^^ I actually thought this would go away after doing a few PRs for the error handling etc.

In-toto record functionality

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:
Most of the run functionality has been fulfilled by #56, what is missing is record functionality for in-toto.
Record functionality is explained here: https://github.com/in-toto/in-toto#in-toto-record

in-toto-record works similar to in-toto-run but can be used for multi-part software supply chain steps, i.e. steps that are not carried out by a single command. Use in-toto-record start ... to create a preliminary link file that only records the materials, then run the commands of that step or edit files manually and finally use in-toto-record stop ... to record the products and generate the actual link metadata file. For a detailed list of all command line arguments and their usage, run in-toto-record start --help or in-toto-record stop --help, or look at the online documentation.

The difference to the python implementation is, that we do not want a cli for in-toto-golang. The functionality should be implemented as library with RecordStart and RecordStop methods.

Current behavior:
No record functionality

Expected behavior:
In-toto-golang should support record functionality for satisfying the in-toto specification.

ecdsa curve sanity checks

Description of issue or feature request:
The current ecdsa implementation does not do sanity checks for different ecdsa curves. Right now, we trust the developer, that
the dev will pick the right curve name in the key.Scheme string. Theoretically and practically the dev could just load an ecdsa key with another curve, than specified in the scheme.

Current behavior:
We do no sanity checks for ecdsa curves, thus it's possible that ecdsa key and key.Scheme do not match.

Expected behavior:
We should validate if the curve used in the ecdsa key matches the curve specified in the key.Scheme variable.

Moving to Github Actions for CI

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:
Today I ran into a network problem with appveyor:

Build started
git clone -q https://github.com/in-toto/in-toto-golang.git c:\gopath\src\github.com\in-toto\in-toto-golang
fatal: unable to access 'https://github.com/in-toto/in-toto-golang.git/': Failed to connect to github.com port 443: Timed out
Command exited with code 128

Mistakes happen. This issue is not intended as a rant about appveyor, but I have read that the TUF team thinks about moving to Github Actions. Maybe it makes sense for us to switch, too. See this issue as a discussion, if we should move and if so, which benefits we would gain

Allow passing directory for inspections

Currently, you cannot run the inspections when the materials and products are in a different directory than the current directory.

linkMb, err := InTotoRun(inspection.Name, []string{"."}, []string{"."},

This means that while you can pass the paths for the layout and root key, you have to be in the same directory with the rest of the materials to execute the verification with this library, or copy around the materials.

Given the fact that most commonly, the in-toto artifacts are usually grouped in the same directory, would it make sense to be able to pass the path?

This branch introduces that path to the RunInspections functions, but does not break compatibility for the InTotoVerify function by creating a new one, InTotoVerifyWithDirectory.

Of course, the implementation is open for discussion, but is the functionality something desired in the library?

Thanks!

Do not share state in test functions

Description of issue or feature request:
Right now, we call a TestMain method to create a test directory, copy over all our test files and work on this directory for each test. This can be dangerous, because tests are sharing states. Just imagine a test, that does not clean up properly or that alters one of our test files. The solution is to create a helper function, that creates a separate test directory for each function.
The disadvantage would be to have to call that function in every test, the benefit would be an isolated test environment for each test. We can make use of T.TempDir for this. T.TempDir is new in Go 1.15 and will cleanup the test directory automatically, when exiting the function.

Current behavior:
One big test directory for all tests

Expected behavior:
We should create an isolated test directory for each step.

Add tests

Currently a full passing supply chain verification is tested, plus a few unit tests, which gives us a bit more than 80% coverage. We want 100%! :)

Test clean up does not work due to deferring functions not being called

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:
Right now, we use the TestMain function for setting up our temporary test directories, copying the test/data directory over and cleaning it up. The problem is, that the deferring functions are not being called, due to calling os.Exit(m.Run()) in the end.
This can be fixed either via using Go 1.15 in August and just calling m.Run() without os.Exit() or via creating setup and teardown methods, like this:

func setup() string {
	testDir, err := ioutil.TempDir("", "testdir")
	if err != nil {
		panic("Cannot create temp test dir")
	}
	err = os.Chdir(testDir)
	if err != nil {
		fmt.Printf("Unable to change dir to %s: %s", testDir, err)
	}
        return testDir
}

func teardown(testdir string) {
	if err := os.RemoveAll(testDir); err != nil {
		fmt.Printf("Unable to remove directory %s: %s", testDir, err)
	}
}

func TestMain(m *testing.M) {
	testdir := setup()
	code := m.Run()
	teardown(testdir)
	os.Exit(code)
}

Current behavior:
TestMain does not clean up properly after calling the tests.

Expected behavior:
The temporary test directories should be deleted, after calling the tests.

canonical_json encoder coerces floats to ints

Description of issue or feature request:
It appears that our implementation of canonical_json is failing the spec, as it coerces float types to ints. The error was nailed down to this line by @radu-matei

Current behavior:
The input object

{
    "anumber": 1.2,
    "znumber": 2.3
}

outputs
{"anumber":1,"znumber":2}

Expected behavior:
The routine should fail, as do the rust and python implementations. Do, see this snippet

Failure of sublayout verification leads to failure of entire verification routine

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:

#19 introduced sublayout verification capabilities, which closely resemble the reference implementation. Currently, the overall verification process fails as soon as sublayout verification fails at some stage, instead of proceeding with other steps and checking for threshold value later.

Expected behavior:

The implementation must continue the verification routine and consider summary links only from successfully verified sublayouts. The verification routine can then check if threshold value is met further down the line.

For more details: #19 (comment)

Windows Compatibility

Description of issue or feature request:

I had a a deep-dive into Windows today via installing a Windows10 Vagrant box, starting Jetbrains GoLand in it and executing the tests for master and for my branches.

I have bad news.

Did we ever execute tests via appveyor on Windows, besides go fmt?
If so, then I am interested in what appveyor is actually doing, because the tests on Windows definitely fail.

There are several issues. First I thought it's the Github Runner, that is behaving odd, but in reality it's our code.
Somehow generateKeyID calculates a different checksum on Windows. I have no explanation for this.

Here is what I did:

  1. First I compared file sizes of our test data files, these were differently. Later I read at StackOverflow, that these are just different metrics: https://askubuntu.com/questions/573586/files-sizes-differs-from-windows-to-linux#:~:text=The%20different%20file%20structure%20which,sizes%20in%20different%20operating%20systems.

  2. So I decided to calculate the checksum on Linux via md5sum and sha256sum and on Windows via CertUtil -hashfile <input file> sha256. Well.. and all of our test data files, had a different check sum. Do you have any explanation for this?

I tried setting .gitattributes and eol=lf and such stuff, but it didn't help.

What is even more odd is, that we use pem.Decode(), so actually the file format is irrelevant. But still we are ending up with a different keyID. I expect an issue in EncodeCanonicalData, but I can't really explain what is going on there.

Current behavior:
Right now we are not Windows compatible and I doubt that we ever were windows compatible.

Expected behavior:
We should be compatible with windows.

PS:
Do we have checks for Windows/Linux compatibility with in-toto-py and/or TUF?

CC: @SantiagoTorres @trishankatdatadog maybe you have an explanation for this.

Create helper functions for *lang-related type juggling*

Move the following two type conversion loops to helper functions:

// Go does not allow to pass []Step as []interface{}
// We have to manually copy first :(
// https://golang.org/doc/faq#convert_slice_of_interface
stepsI := make([]interface{}, len(layout.Steps))
for i, v := range layout.Steps {
stepsI[i] = v
}

// Convert []Inspections to []interace{} (see `stepsI` above)
inspectionsI := make([]interface{}, len(layout.Inspect))
for i, v := range layout.Inspect {
inspectionsI[i] = v
}

Addresses @SantiagoTorres's #1 (comment).

Potential bug in InTotoRun

Description of issue or feature request:

byProducts, err := RunCommand(cmdArgs, runDir)

We are not handling an empty cmdArgs either as nil or empty string slice. We should check if our code still works with both and that we are not running into a panic.

Furthermore, we should add tests to cover these edge cases.

Add metadata schema validation

Description of issue or feature request:
model.go defines structs that may be used to hold in-toto metadata. The metadata schema is only loosely prescribed by the used datatypes and by the specified json tags.

We need a generic schema validation facility that allows to verify if a given instance of a struct is conformant with the in-toto metadata specification.

For inspiration take a look at the reference implementation, where we use a ValidationMixin for top-level metadata models, plus securesystemslib.schema-checkers to validate mostly (but not exclusively) crypto-related data structures, see as defined in (securesystemslib.formats, in_toto.formats and in_toto.gpg.formats).

Current behavior:
No methods to validate the data model.

Expected behavior:
Provide methods to validate the data model and use where appropriate (e.g. to check function parameters).

Revise error style

In #1 (comment), @aaaaalbert and @SantiagoTorres, suggest to not use assignments in conditions (which, FWIW, seems to be a go-thonic way to handle errors.

So instead of e.g:

if err := someFunction(); err != nil {
  return error
}

we should use:

err := someFunction()
if error != nil {
  return error
}

It might be worth to read more about error handling in go and see if there is a good way to reduce clutter. Here's some literature:

InTotoRun inconsistency: handling symlink cycles

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:
When symlink cycles are detected, the Golang and Python implementations differ in how the symlink cycle error is handled.

In Python, the paths that are causing the symbolic link cycles are recorded but eventually skipped when reaching a certain depth, the warning is logged, and in_toto_run continues to record the artifacts.

In Golang, the symbolic link cycles are detected (very awesomely) and the InTotoRun function exits completely, returning an error (see line 147 in runlib.go here).

Since the Python implementation is the more canonical when there are differences in implementation, should we follow its method of handling symlink cycles and document the change? However, this may be because the Python version doesn't have symlink cycle detection implemented, and maybe we can change the Python implementation to match Golang's?

Current behavior:
Golang - When symlink cycles are detected, ErrSymCycle is returned and function exits.
Python - When symlink cycles are detected, the symlink is skipped and InTotoRun continues.

Expected behavior:

  • Golang - When symlink cycles are detected, the symlink is skipped on first pass and InTotoRun continues. (Change: logs ErrSymCycle instead of returning it, and continue)
  • Python - When symlink cycles are detected, the symlink is skipped on first pass and InTotoRun continues. (Change: either no change by continue having it skip when reaching a certain depth, or add change to detect symlink and skip on first pass)

OR

  • Golang - When symlink cycles are detected, ErrSymCycle is returned and function exits. (No Change)
  • Python - When symlink cycles are detected, ErrSymCycle is returned and function exits. (Change: detect symlink and emit error)

Run unit tests against the last two stable Go releases

Description of issue or feature request:

Go's Release Policy determines the last two releases as stable releases. Therefore we should make sure that our code runs on the last two releases. Running it on the current release may be not enough (due to support for other software, etc).

Current behavior:

Right now we only test against the current release.

Expected behavior:

We should actually test against the last two releases.

CLI tool

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

People at Kubecon 2021 mentioned that they want a CLI tool for in-toto-golang. There is a cli tool for testing in one of our forks. We should adopt it.

Description of issue or feature request:

Provide a cli tool via a separate cmd directory.

Current behavior:

This repository just provides a library.

Expected behavior:

This library should also provide a cli tool with basic functionality.

Support multiple hashing algorithms

Description of issue or feature request: The current implementation is fixed to sha256. While this is is enough for a MVP, we need to support plug-able and extendable hash functions.

Current behavior: It is not possible to generate hashes using any other algorithm than sha256.

Expected behavior: It should be possible to programmatically select the hashing algorithm to compute artifact integrity and for signature verification.

Abstract PKI with SPIRE

We would like to use SPIRE to provide the PKI to in-toto. This would give us the ability to tie build to hardware security modules, or cloud meta-data in a predictable way through the SPIRE plugin system. I am opening this ticket to start a discussion on how the implementation should look.

Use tabs for code indentation in multi-line comments

Description of issue or feature request:
Since #16 we use tabs instead of spaces for indentation by auto-formatting with gofmt. However, gofmt does not re-indent multi-line comments.

Given that godoc displays indented blocks in multi-line comments as code, I suggest that we use tabs there as well (for consistency).

See godoc docs note: "Pre-formatted text must be indented relative to the surrounding comment text".

Current behavior:
Code block in multi-line comments are indented with spaces.

Expected behavior:
Indent code blocks in multi-line comments with tabs.

Add further tests for sublayout verification

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:

#19 added sublayout verification functionality to the go implementation. However, there are certain tests missing that must be added. Specifically we must test for:

  • multi level sublayouts
  • failure to verify superlayout because of failure of verification of sublayout
  • further tests designed for verification to fail to ensure failure occurs gracefully

Current behavior:

The above tests are currently missing, as to add them, we will have to include a variety of layout and link files.

Expected behavior:

The tests must be added after the go implementation has an updated runlib capable of signing and generating layouts on the fly. We can use this capability to create the metadata files required for the tests.

compare the way we store symlinks in our link metadata to the reference implementation

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:
We still need to decide if link metadata stores the path of the source or the target of a symlink.
The python reference implementation is might be useful for this.

Current behavior:

unknown

Expected behavior:

see python reference implementation

Support CREATE, DELETE, MODIFY

Description of issue or feature request:
The current set of rules supported by this implementation doesn't include CREATE, DELETE, and MODIFY.

Current behavior: These rules aren't parsed accordingly (which leads to failure).

Expected behavior: These rules should be processed according to the spefcification.

Consider splitting signing-spec/ITE-5 code (`package ssl`) into a standalone repository

I wanted to broach the conversation of splitting off the implementation of the new signing-spec / ITE-5 support introduced in #101 into a standalone repository. The signing-spec, now renamed DSSE, is in the process of a v1 release: secure-systems-lab/dsse#37, and I was wondering about releasing this implementation as github.com/secure-systems-lab/dsse-go, for example, to go along with the spec (and the Python implementation included there). This package could of course be imported and used in the ITE-6 specific branch(es) here. Any thoughts?

Edit: @trishankatdatadog pointed out that this new repository could be the equivalent of securesystemslib for the Go implementations of in-toto/TUF over time, and I'm given to agree. It can definitely live under that moniker, and can start off by implementing DSSE.

@kommendorkapten @dlorenc @SantiagoTorres @MarkLodato @mnm678 @trishankatdatadog

Ed25519 and dsa support

Description of issue or feature request:
According to the in-toto specification other signatures such as ed2119 and dsa signatures are supported

Current behavior: There are no mechanisms to sign or verify metadata using these signing algorithms.

ecdsa-sha2-nistp384 support

Description of issue or feature request:
The securesystemslib supports ecdsa-sha2-nistp384 as scheme. We should catch up with the securesystemslib and provide
support for this curve as well. I suggest to use Go's Hash interface for setting the correct hash algorithm: https://godoc.org/crypto#Hash

This could be also useful if we want to support more RSA schemes.

Current behavior:
Right now we only support ecdsa-sha2-nistp256.

Expected behavior:
We should catch up with the securesystemslib and support ecdsa-sha2-nistp384, too.

Error handling

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:
With Go 13, Go got better error handling with functions like errors.Is() or errors.As(). We might want to adapt our code, so developers can use this functions with our library.

Current behavior:

Right now we are excessively using fmt.Errorf("..") for error messages. Instead we should declare global Error types like in the Symlink implementation and return error types:

// ErrSymCycle signals a detected symlink cycle in our RecordArtifacts() function.
var ErrSymCycle = errors.New("symlink cycle detected")

This way we have error documentation and can use errors.Is(err, ErrSymCycle) for error checking. This is a huge benefit over string checking with if err.Error() == "..." { .. }, because with the latter we can run into a nil pointer dereference if Error() returns nil.

Expected behavior:

Use documented error types like:

// ErrSymCycle signals a detected symlink cycle in our RecordArtifacts() function.
var ErrSymCycle = errors.New("symlink cycle detected")

More about new Go 1.13 error handling can be found here: https://blog.golang.org/go1.13-errors

Feedback @SantiagoTorres @lukpueh ?

Hardware Security Module (HSM) Support

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:
For supporting Hardware Security Modules (HSMs), we need the the following features:

  • possibility to pass a custom keyID
  • possibly more?

Current behavior:

Currently, we have no HSM support, because we load keys from file. HSM support is especially interesting in combination with a smartcard daemon (for example a RSA key on a Yubikey).

Expected behavior:

We should support HSMs, if we want to keep up with modern security options.

in_toto.Signature struct definition does not match specification

The current definition of in_toto.Signature in this library is as follows https://github.com/in-toto/in-toto-golang/blob/master/in_toto/model.go#L306:

type Signature struct {
	KeyID       string `json:"keyid"`
	Sig         string `json:"sig"`
	Certificate string `json:"cert"`
}

This definition contains a "cert" field. However, this field is not part of the in-toto specification: per https://github.com/in-toto/docs/blob/master/in-toto-spec.md#42-file-formats-general-principles, items in the "signatures" block should only have "keyid" and "sig".

The "cert" field is also not part of the Python schema (https://github.com/secure-systems-lab/securesystemslib/blob/master/securesystemslib/formats.py#L397) and none of the example files I have seen contain it either (for example, https://github.com/in-toto/kubectl-in-toto/blob/master/example/functionary/build.f5c8b97a.link#L3).

The current behavior causes issues when marshalling an in_toto.Metablock struct as JSON because the extra field is included:

{
  "signatures": [
    {
      "cert": "",
      "keyid": "706bdfbb46c397eb55a64c902c5241dabeb16cfa5c7456250800441bade2cdf9",
      "sig": "827074c151970a7e45cbc5b8d66ba84b9e501e699a826d37132853fac889e58e542b6f860c3399e157bab7afdad9bee24523e2ac40427c4c93e821d2c936a260329fd2262b78ef431fd06014b9a7c154282fc3f37f9e7ac18c015350dd6da6ea3ae7bfd43615d8dec3d9f18ce389aa8598253bc84c71646956e34c887a0424e5af89ffe395018cf71470121ae657d9129c4b6edc3f75edab45c1ee78f9c662234d148e3aa972a5cbbca46f1c7c18fd8c4fc6a54e3338a0b318cc21d0f6634279f18187367fb457789eaa7df30a420eab98d9e682e41821e82daed015f92699605f0a60f45496b3497e23a553bcc11fe1d00ed64c42ce15dd02ce5f10df8bb9cb"
    }
  ],

Given that "cert" is not part of the spec, it seems like it should not be part of this struct either (or, at minimum, the JSON field should be annotated with omitempty like https://github.com/in-toto/in-toto-golang/blob/master/in_toto/model.go#L30 so that it is not written out when a value is not present).

Lack of version tagging causing issues with `go get`

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:

In kubesec if you try install it with go get ... it'll grab the latest version of the in-toto lib, ignoring the date & commit sha because they're both 0.0.0

Current behavior:

see above

Also here: controlplaneio/kubesec#109

Expected behavior:

It'd be nice to have go get installs work properly. It doesn't seem particularly popular but users may just try it, it wont work, and they abandon the tool rather than reporting.

0.x.x major version can still implement breaking changes according to semver so shouldn't cause any issues other than the extra effort of tagging.

Go 1.15 Support

Description of issue or feature request:

In late August Go 1.15 will arrive, I had a look on the changelog and this release will fix a few issues for us.
Full changelog is here: https://tip.golang.org/doc/go1.15

Current behavior + potential impact:

  • ecdsa signature: Right now we are creating our own ASN1 ecdsa signature object for signing. With Go 1.15 we can use the new ecdsa functions ecdsa.SignASN1 and ecdsa.VerifyASN1

  • Test cleanup: Right now our test directory cleanup is broken and does not work correctly. One way for fixing this has been proposed in: #60 . Go 1.15 reduces a new way: 1. TestMain does not need an exit code anymore. The exit code will be automatically wrapped around the TestMain function. 2. TestMain has now support for creating temporary test directories. This may be easier to use, because TestMain will take care about the clean up. No deferred functions needed anymore. See also:


The testing.T type now has a Deadline method that reports the time at which the test binary will have exceeded its timeout.
A TestMain function is no longer required to call os.Exit. If a TestMain function returns, the test binary will call os.Exit with the value returned by m.Run. The new methods T.TempDir and B.TempDir return temporary directories that are automatically cleaned up at the end of the test. go test -v now groups output by test name, rather than printing the test name on each line.


validate functions, specifically key validations

Description of issue or feature request:
Right now, most or even all of our validate functions in the model.go file are unexported.
It needs to be discussed, if we want to export these functions or if we only want to use them internally.

Furthermore the validateKeyVal function is not being used right now, because most of the functionality
is already being covered by internal code in the GenerateSignature, ValidateSignature and LoadKey functions.

We also might want to talk about key validation in general. Are we happy with the current approach? Should
we do it differently? What requirements do we have on a valid key actually? What kind of mistakes are forgivable?
When is a key definitely invalid?

I would also like to use this issue to highlight a small nit: Right now, we are mixing the words validation and verification
in many places. Might make sense to use these words in different situations and keep the wording consistent.

Test interoperability with the python implementation via subprocess calls

Please fill in the fields below to submit an issue or feature request. The
more information that is provided, the better.

Description of issue or feature request:
Right now, we have a static test/data directory with some test data in it. I am not sure, if this test data got created with in-toto-python. I would like to suppose, that we add a few tests calling in-toto-python dynamically. That way, we do not mix up in-toto-python generated test/data and our static test data. Furthermore we have some dynamic tests. Thanks to @trishankatdatadog for pointing this out.

Current behavior:
We just test against a static test directory

Expected behavior:
We should be able to test in-toto-python interoperability via calling in-toto-python. The Go TUF implementation is a nice example for such tests.

Exclude patterns

Description of issue or feature request: The python implementation has a nice frontend feature to ignore artifacts a-la .gitignore we should port that.

Current behavior: This feature is not implemented, so runlib captures all the materials in the directory.

Expected behavior: It should be possible to specify patterns to ignore when collecting file integrity.

Signed link generation

Description of issue or feature request: The current implementation can only generate unsigned links for the sake of inspections. Although this is enough to perform verification it is not the complete functionality required for use by functionaries.

Current behavior: There are no library functions to generate and sign in-toto link metadata. (only to run inspections)

Expected behavior: A function or group of functions should be available to generate and sign in-toto link metadata.

Use Go Linter for CI

Description of issue or feature request:
As of today, we are not satisfying a few constraints in the Go specification.
I ran go lint over our project and got the following output:

in_toto/canonicaljson.go:1:1: don't use an underscore in package name
in_toto/canonicaljson_test.go:1:1: don't use an underscore in package name
in_toto/examples_test.go:1:1: don't use an underscore in package name
in_toto/hash.go:1:1: don't use an underscore in package name
in_toto/hash.go:21:6: exported type Hash should have comment or be unexported
in_toto/hash_test.go:1:1: don't use an underscore in package name
in_toto/in_toto_test.go:1:1: don't use an underscore in package name
in_toto/keylib.go:1:1: don't use an underscore in package name
in_toto/keylib.go:54:6: func getSupportedKeyIdHashAlgorithms should be getSupportedKeyIDHashAlgorithms
in_toto/keylib.go:143:107: method parameter keyIdHashAlgorithms should be keyIDHashAlgorithms
in_toto/keylib.go:265:51: method parameter keyIdHashAlgorithms should be keyIDHashAlgorithms
in_toto/keylib_test.go:1:1: don't use an underscore in package name
in_toto/keylib_test.go:116:3: struct field keyIdHashAlgorithms should be keyIDHashAlgorithms
in_toto/model.go:1:1: don't use an underscore in package name
in_toto/model.go:45:2: struct field KeyId should be KeyID
in_toto/model.go:46:2: struct field KeyIdHashAlgorithms should be KeyIDHashAlgorithms
in_toto/model.go:52:1: comment on exported var ErrEmptyKeyField should be of the form "ErrEmptyKeyField ..."
in_toto/model.go:55:1: comment on exported var ErrInvalidHexString should be of the form "ErrInvalidHexString ..."
in_toto/model.go:58:1: comment on exported var ErrSchemeKeyTypeMismatch should be of the form "ErrSchemeKeyTypeMismatch ..."
in_toto/model.go:61:1: comment on exported var ErrUnsupportedKeyIdHashAlgorithms should be of the form "ErrUnsupportedKeyIdHashAlgorithms ..."
in_toto/model.go:62:5: var ErrUnsupportedKeyIdHashAlgorithms should be ErrUnsupportedKeyIDHashAlgorithms
in_toto/model.go:64:1: comment on exported var ErrKeyKeyTypeMismatch should be of the form "ErrKeyKeyTypeMismatch ..."
in_toto/model.go:274:2: struct field KeyId should be KeyID
in_toto/model.go:377:7: exported const LinkNameFormatShort should have comment or be unexported
in_toto/model.go:378:7: exported const SublayoutLinkDirFormat should have comment or be unexported
in_toto/model.go:488:9: range var keyId should be keyID
in_toto/model.go:520:1: comment on exported method Layout.StepsAsInterfaceSlice should be of the form "StepsAsInterfaceSlice ..."
in_toto/model.go:532:1: exported method Layout.InspectAsInterfaceSlice should have comment or be unexported
in_toto/model.go:554:6: range var keyId should be keyID
in_toto/model.go:568:10: if block ends with a return statement, so drop this else and outdent its block
in_toto/model.go:578:10: if block ends with a return statement, so drop this else and outdent its block
in_toto/model.go:610:6: func checkRequiredJsonFields should be checkRequiredJSONFields
in_toto/model_test.go:1:1: don't use an underscore in package name
in_toto/model_test.go:23:2: var invalidJsonBytes should be invalidJSONBytes
in_toto/rulelib.go:1:1: don't use an underscore in package name
in_toto/rulelib_test.go:1:1: don't use an underscore in package name
in_toto/runlib.go:1:1: don't use an underscore in package name
in_toto/runlib_test.go:1:1: don't use an underscore in package name
in_toto/util.go:1:1: don't use an underscore in package name
in_toto/util_test.go:1:1: don't use an underscore in package name
in_toto/verifylib.go:6:1: don't use an underscore in package name
in_toto/verifylib.go:522:10: range var authorizedKeyId should be authorizedKeyID
in_toto/verifylib.go:556:21: error strings should not be capitalized or end with punctuation or a newline
in_toto/verifylib.go:571:21: error strings should not be capitalized or end with punctuation or a newline
in_toto/verifylib.go:625:7: range var keyId should be keyID
in_toto/verifylib_test.go:1:1: don't use an underscore in package name
in_toto/verifylib_test.go:551:2: var keyId1 should be keyID1
in_toto/verifylib_test.go:552:2: var keyId2 should be keyID2
in_toto/verifylib_test.go:553:2: var keyId3 should be keyID3
in_toto/verifylib_test.go:619:2: var keyId1 should be keyID1
in_toto/verifylib_test.go:620:2: var keyId2 should be keyID2
in_toto/verifylib_test.go:641:2: var keyId3 should be keyID3

Most of these issues are spelling issues like keyId vs KeyID or invalid error string formatting.
The biggest issue is the package name. in_toto works, but actually it's invalid. Package names are not supposed to use underscores.

Current behavior:
We are violating a few Go specifications and I don't know if this is 'bad'.
Moreover we are not checking go lint periodically.. we might want to change this.

Expected behavior:
We should comply with the Go specification, otherwise we will might end up with high technical debt and cleaning that later if Go starts enforcing it. Furthermore we should use go lint in our Continuous Integration.

in-toto attestation JSON schema verify via CLI

Abstract

in-toto attestations are in the form of JSON. We can use JSON schema to validate the schema of the attestation.

Motivation

We started to work on a PR to verify in-toto attestations by using Cue or Rego languages in the cosign project. So, if in-toto attestations have JSON schemas, we can use them in the in-toto-golang CLI. Also, cosign has a dependency on the in-toto-golang project for the structs of the in-toto attestations. So, if we add support of verifying JSON schemas to the in-toto-golang project, we can use it in cosign project too.

References

I found some additional resources that might help us to implement this:

cc: @Dentrax @erkanzileli

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.