Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements profile signing and verification [Experimental] #1228

Merged
merged 1 commit into from
Oct 27, 2016

Conversation

bookshelfdave
Copy link

@bookshelfdave bookshelfdave commented Oct 18, 2016

This PR is a prototype/work in progress of profile signing and verification.
It's most definitely NOT complete and has many TODOs and ideas that need to be worked out.

Demo:

    1. Generate a pair of 2048 bit RSA keys to use to sign and verify an artifact:
    • bundle exec inspec artifact generate --keyname foo
    1. Sign an existing profile:
    • bundle exec inspec artifact sign-profile --profile ./examples/profile-attribute/ --keyname foo
    1. Verify the .iaf file:
    • bundle exec inspec artifact verify --infile profile-attribute-0.1.0.iaf --outfile bar.tar.gz

Notes:

Implementation notes here: https://gist.github.com/metadave/a11745db15fc1bc33a44719c5e3a026e

Installing artifacts

The current implementation allows for a .iaf file to be extracted to a .tar.gz
file with verification. We could extend the command to install a profile
to a given location w/ verification. (via lib/inspec/file_provider.rb)

Generate keys

The initial implementation uses 2048 bit RSA key pairs (public + private).
Public keys must be available for a customer to install and verify an artifact.
Private keys should be stored in a secure location and NOT be distributed.
(They're only for creating artifacts).

.IAF file format

.iaf = "Inspec Artifact File", easy to rename if you'd like something more appropriate.
The iaf file wraps a binary artifact with some metadata. The first implementation
looks like this:

INSPEC-PROFILE-1
name_of_signing_key
algorithm
signature
<empty line>
binary-blob
<eof>

Let's look at each line:

INSPEC-PROFILE-1:

This is the artifact version descriptor. It should't change unless the
format of the archive changes.

name_of_signing_key

The name of the public key that can be used to verify an artifact

algorithm

The digest used to sign, I picked SHA512 to start with.
If we support multiple digests, we'll need to have the verify() method
support each digest.

signature

The result of passing the binary artifact through the digest algorithm above.
Result is base64 encoded.

<empty line>

We use an empty line to separate artifact header from artifact body (binary blob).
The artifact body can be anything you like.

binary-blob

A binary blob, most likely a .tar.gz or tar.xz file. We'll need to pick one and
stick with it as part of the "INSPEC-1" artifact version. If we change block
format, the artifact version descriptor must be incremented, and the sign()
and verify() methods must be updated to support a newer version.

Key revocation

This implementation doesn't support key revocation. However, a customer
can remove the public cert file before installation, and artifacts will then
fail verification.

Key locations

This implementation uses the current working directory to find public and
private keys. We should establish a common key directory (similar to /hab/cache/keys
or ~/.hab/cache/keys in Habitat).

Extracting artifacts outside of Inspec

As in Habitat, the artifact format for Inspec allows the use of common
Unix tools to read the header and body of an artifact.
To extract the header from a .iaf:
sed '/^$/q' foo.iaf
To extract the raw content from a .iaf:
sed '1,/^$/d' foo.iaf


Here's a mini-demo of this feature:

1__tmux_and_cli_rb______oc_inspec_lib_bundles_inspec-artifact__-_vim

NOTE: this screenshot is out of date, however the general idea is still the same

@chris-rock
Copy link
Contributor

cc @aaronlippold @mhedgpeth

@chris-rock
Copy link
Contributor

chris-rock commented Oct 18, 2016

implements #966

@chris-rock
Copy link
Contributor

@metadave Awesome work. I was thinking about #967 as well. Do we use the same file extensions for profiles and reports? Or we use specific extensions like: InSpec Signed Profile .isp and InSpec Signed Report .inr

I like the current scope, but lets the feature mark as experimental. Distribution of valid keys is not part of this PR.

@bookshelfdave
Copy link
Author

bookshelfdave commented Oct 24, 2016

@chris-rock I would suggest keeping signed reports and profiles separate, I like your suggestion: .isp and .isr.

This might change the headers to:

INSPEC-PROFILE-1
name_of_signing_key
algorithm
signature
<empty line>
binary-blob
<eof>
INSPEC-REPORT-1
name_of_signing_key
algorithm
signature
<empty line>
binary-blob
<eof>

@aaronlippold
Copy link
Collaborator

👍

@bookshelfdave
Copy link
Author

bookshelfdave commented Oct 25, 2016

I still have to write the profile install bits.

Signed-off-by: Dave Parfitt <dparfitt@chef.io>
@chris-rock chris-rock changed the title [RFC] profile signing and verification Implements profile signing and verification [Experimental] Oct 27, 2016
@chris-rock
Copy link
Contributor

Awesome work @metadave This is a great step forward to secure the execution and reporting of compliance profiles

@chris-rock chris-rock merged commit a890f1b into master Oct 27, 2016
@chris-rock chris-rock deleted the dp_signing branch October 27, 2016 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants