ima

package module
v0.0.0-...-c2cb226 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 11, 2017 License: Apache-2.0 Imports: 9 Imported by: 2

README

go-ima

GoDoc

Integrity Measurement Architecture (or IMA) is a component of the Linux kernel that allows for the signing of binaries, and ensure that software that gets run is intact.

This repo contains a go native implementation of the IMA signing format, as well as some basic tools to read and write those to the filesytem.

The interface looks a lot like a crypto.Signer, and the goal was to create an API that was familiar to Go developers. Additionally, this code only requires a crypto.Signer to create Signatures, and a crypto.PublicKey to verify them.

This is handy if you have a hardware device (such as an HSM) with blinded private key material.

Documentation

Overview

Integrity Measurement Architecture, or IMA defines a set of formats for signing and measuring files. This package contains a set of parsers to read and validate IMA Signatures, and interfaces to allow crypto.Signer to create new Signatures over new or existing files.

Index

Constants

This section is empty.

Variables

View Source
var (
	// This is returned when the KeyPool does not have the KeyId in the
	// keychain, which means there's absolutely no way we have a valid
	// Signature, since we absolutely don't have the public key.
	UnknownSigner error = fmt.Errorf("ima: unknown signature keyid")
)

Functions

func PublicKeyId

func PublicKeyId(pubKey crypto.PublicKey) ([4]byte, error)

IMA creates a content-based ID to help validate signatures which is based on a hash the public key. In particular, it's the last 4 bytes of a SHA1 hash of the DER encoded RSA Public Key. Other formates are not supported at this time.

func Serialize

func Serialize(signature Signature) ([]byte, error)

Take a Signature, and convert it to a byte array. This can be used to write out IMA EVM signatures.

func Sign

func Sign(signer crypto.Signer, rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)

Given a crypto.Signer, a RNG source (to be used during the underlying signer.Sign call), a digest, and a crypto.SignerOpts, sign the digest and serialize the Signature as an IMA EVM v2.0 signature.

Types

type Hash

type Hash struct {
	Id   uint8
	Hash crypto.Hash
}

Encapsulation of an IMA EVM Hash function. These should likely not be used directly - talking directly about crypto.Hash numbers is much safer. This part of the IMA EVM library is useful to convert between IMA EVM Hash IDs and the standard Go crypto Hash objects.

These objects are only exported in the event that someone needs a very precise understanding of the mapping between IMA EVM hashes and the native Go hashes.

var (
	MD4 Hash = Hash{Id: 0, Hash: crypto.MD4}
	MD5 Hash = Hash{Id: 1, Hash: crypto.MD5}

	RIPEMD160 Hash = Hash{Id: 3, Hash: crypto.RIPEMD160}

	SHA1   Hash = Hash{Id: 2, Hash: crypto.SHA1}
	SHA224 Hash = Hash{Id: 7, Hash: crypto.SHA224}
	SHA256 Hash = Hash{Id: 4, Hash: crypto.SHA256}
	SHA384 Hash = Hash{Id: 5, Hash: crypto.SHA384}
	SHA512 Hash = Hash{Id: 6, Hash: crypto.SHA512}

	// List of all Hash functions.
	HashFunctions = Hashes{
		MD4, MD5,
		RIPEMD160,
		SHA1, SHA224, SHA256, SHA384, SHA512,
	}
)

type Hashes

type Hashes []Hash

List of IMA EVM Hash functions.

func (Hashes) ToCrypto

func (h Hashes) ToCrypto(hash uint8) (*crypto.Hash, error)

Convert a ima.Hash to a crypto.Hash. This will enumerate the Hsah functions in the Hashes, and find a crypto.hash that corresponds to the IMA EVM hash ID.

func (Hashes) ToHash

func (h Hashes) ToHash(hash crypto.Hash) (*Hash, error)

Convert a crypto.Hash to an ima.Hash. This will enumerate the Hash functions in the Hashes, and find an IMA EVM Hash object that corresponds to the native Go Hash function.

type KeyPool

type KeyPool struct {
	// contains filtered or unexported fields
}

KeyPool is a keyring of crypto.PublicKeys. Internally, this uses the PublicKeyId to serve not unlike a bloom filter for key selection, which allows the Verify function to only try keys which have matching Key IDs.

func NewKeyPool

func NewKeyPool() KeyPool

Initialize a KeyPool

func (KeyPool) AddKey

func (k KeyPool) AddKey(key crypto.PublicKey) error

Add a new crypto.PublicKey to the keychain.

func (KeyPool) Get

func (k KeyPool) Get(id [4]byte) []crypto.PublicKey

Get all matching keys by the KeyId.

func (KeyPool) MaybeContains

func (k KeyPool) MaybeContains(key crypto.PublicKey) bool

Cheeck to see if the crypto.PublicKey's PublicKeyId is set in the underlying storage, and if that key might already be included.

type Signature

type Signature struct {
	Header    SignatureHeader
	Signature []byte
}

IMA Signature encapsulation. This contains both the IMA Signature Header directly, as well as the Signature, in bytes.

func Parse

func Parse(signature []byte) (*Signature, error)

Take a byte array and return a new Signature object, containing the parsed headers and Signature. This can be used to verify IMA signatures.

func (Signature) Verify

func (s Signature) Verify(opts VerifyOptions) (crypto.PublicKey, error)

Verify the Signature with the provided VerifyOptions.

If the KeyId is unknown to the underlying KeyPool, this will return UnknownSigner.

This function will attempt to verify the signature using each of the Public keys with a matching KeyId in the order they were added to the Pool. When a Signature matches, the Public Key will be returned. If not, the error from the last validation attempt will be returned.

func (Signature) VerifyKey

func (s Signature) VerifyKey(pub crypto.PublicKey, digest []byte, hash crypto.Hash) error

Verify the Signature against the digest matches both our digest and hash algorithm for a specific key.

At this time, only RSA Public Keys are supported due to IMA only supporting RSA signatures.

Any PublicKey struct except an rsa.PublicKey will return an opaque error.

type SignatureHeader

type SignatureHeader struct {

	// Always 0x03.
	Magic uint8

	// Either format 0x01, or format 0x02. This library only supports IMA
	// Version 0x02.
	Version uint8

	// IMA Hash Algorithm used. This is an awkwardly sorted enum of a mix
	// of total shit algorithms and moderately tolerable ones. The Hash type
	// in this library can be used to convert this to a sensible format, as
	// well as the Hash() helper.
	HashAlgorithm uint8

	// Last 4 bytes of a SHA1 hash of the ASN.1 DER encoded RSA Public Key.
	// This is mostly useful to act as a bloom-filter for candidate keys to
	// check the Signature against.
	KeyID [4]byte

	// Completely useless field. Please do not use this. This is used
	// in the underlying byte serialization to let consumers know
	// the length of the Signature data.
	//
	// Users of this library can be happy to go about their buisness by running
	// len(Signature) instead. When the Signature is serialized, this field
	// will be set to exactly that, overriding whatever the current value
	// is.
	SignatureLength uint16
}

Internal structure to unpack an IMA signature onto. This will read out an IMA header from a binary stream, and provide enough context to read the reamining amount of data, or understand which key to find.

func (SignatureHeader) Hash

func (h SignatureHeader) Hash() (*crypto.Hash, error)

Get the native Go crypto.Hash used to compute the Hash that that signature is over. This can be used to hash data to generate the data to verify the signature against.

func (SignatureHeader) String

func (s SignatureHeader) String() string

Output an IMA signature in a human readable format, for debugging.

type VerifyOptions

type VerifyOptions struct {
	// Digest of the object to be verified that the caller has computed themselves.
	Digest []byte

	// Hash algorithm used to measure the file. If this is not the same as
	// the Signature's algorithm, Verify will fail to validate the Signature,
	// even though the file may match. When measuring a file, it's best to
	// load the Signature, and pull the Hash algorithm from the
	// `Signature.Header.Hash()` function call.
	Hash crypto.Hash

	// Keyring to validate Signatures against.
	Keys KeyPool
}

Options to handle the validation of a Signature.

Directories

Path Synopsis
cmd
Bindings to read, write and validate IMA signatures stored as an xattr on a file.
Bindings to read, write and validate IMA signatures stored as an xattr on a file.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL