renard: Index | Files | Directories

package renard

import ""

Package renard implements the RENARD signature format

Renard (RNR) is a signature format designed to provide strong integrity guarantees on files. It is based on COSE and developed for Firefox add-ons (web extensions) and updates.

The binary representation of an RNR signature is a COSE_Sign structure stored in a signing block inserted in the ZIP or MAR envelope of a file, immediately before the Central Directory section (similar to Android’s APKv2). This method allows clients to verify signatures with minimal parsing of the archive, while retaining a valid archive that can be decompressed using standard tools.

A signer receives an unsigned file, inserts needed metadata inside the file, then signs the SHA256 hash of the outer envelope using P-256. The signature block is stored in a COSE document and inserted in the outer envelope.

A verifier receives a signed file, extracts the signature block from the file, calculates the SHA256 hash of the outer envelope (excluding the signature block) and verifies the signature using the public key of the end-entity certificate stored in the COSE document. The verifier then checks the certificate chain, signed timestamp, and root against a local truststore.


Package Files

encoders.go renard.go timestamp.go writer.go


var AvailableEncoders = make(map[FormatIdentifier]EncoderHandler)

AvailableEncoders contains the set of registered encoders

var WellKnownTSA = []string{

WellKnownTSA is a list of publicly accessible timestamp authorities

func RegisterEncoder Uses

func RegisterEncoder(id FormatIdentifier, h EncoderHandler)

RegisterEncoder a new encoder as available

type CounterSignature Uses

type CounterSignature interface{}

CounterSignature is an optional signature that can be applied after the main signatures are issued to allow a 3rd party to add additional trust to a given artifact

type Encoder Uses

type Encoder interface {
    DecodeSignedSections() (r *bytes.Reader, err error)
    DecodeSignature() (coseSig []byte, err error)
    EncodeTo(w io.Writer, coseSig []byte) (err error)

Encoder implements file parsing, marshalling and unmarshalling

type EncoderHandler Uses

type EncoderHandler interface {
    NewEncoder(*bytes.Reader) (Encoder, error)

EncoderHandler provides an interface to make a new encoder

type FormatIdentifier Uses

type FormatIdentifier uint

FormatIdentifier identifies a supported input file format

const (
    Zip FormatIdentifier = 1 + iota // import
    Mar                             // import

File formats are identified by a given constant

func (FormatIdentifier) String Uses

func (id FormatIdentifier) String() string

type SignMessage Uses

type SignMessage struct {
    Hashes           map[crypto.Hash][]byte // hashes of signable data indexed by hash algorithm
    Payload          []byte
    Signatures       []Signature
    CounterSignature CounterSignature
    // contains filtered or unexported fields

SignMessage is the document that contains signatures and timestamps that protect a file. A user of the Renard format initializes a new SignMessage, populates it, then inserts it into a file according to its format. The raw representation of a SignMessage follows the COSE_Sign specification from rfc8152.

func NewSignMessage Uses

func NewSignMessage() *SignMessage

NewSignMessage constructs an empty SignMessage

func (*SignMessage) AddSignature Uses

func (msg *SignMessage) AddSignature(signer crypto.Signer, chain []*x509.Certificate, tsaServers []string) (err error)

AddSignature takes a private key, chain of certificates (ordered from end-entity to root) and a list of timestamping authority servers, then prepares a signature that will sign and timestamp the message when finalized.

While this function takes a full chain, for verification purpose, the root certificate is not included in the final signature and is assumed to be known to verifiers.

The signing algorithm is determined by the key type. RSA keys get PS256, ECDSA keys get ES256 for P-256 and ES384 for P-384. No other curves are supported.

A list of valid and trusted TSA servers is kept in WellKnownTSA.

func (*SignMessage) Finalize Uses

func (msg *SignMessage) Finalize() (err error)

Finalize performs the signature process with all the configured cose signers, issues timestamps on all of the signatures, then marshals the signature message into a COSE message ready for writing to an output.

func (*SignMessage) ParseCoseSignMsg Uses

func (msg *SignMessage) ParseCoseSignMsg(coseMsg []byte) (err error)

ParseCoseSignMsg parses a binary cose signature into a renard sign message.

func (*SignMessage) ReadPayload Uses

func (msg *SignMessage) ReadPayload(buf *bytes.Reader, ff FormatIdentifier) (err error)

ReadPayload extracts the signable data from a payload passed as a bytes.Reader in the format specified by the format identifier. The signable data is stored as a payload of the SignMessage that can be later timestamped and signed.

func (*SignMessage) ReadSignature Uses

func (msg *SignMessage) ReadSignature(buf *bytes.Reader, ff FormatIdentifier) (err error)

ReadSignature extracts and parses the signature data from a payload passed as a bytes.Reader in the format specified by the format identifier.

func (*SignMessage) SetRng Uses

func (msg *SignMessage) SetRng(rng io.Reader)

SetRng configures the signers to use a different random number generator than the default from crypto/rand

func (*SignMessage) Verify Uses

func (msg *SignMessage) Verify(tsaPool, localRoots *x509.CertPool) error

Verify verifies each of the signatures stored in a SignMessage and makes sure the certificates chain to roots in the provided truststore.

Signed timestamps in each signature are first verified, then certificates checked against a provided tsaPool. The SHA256 hash of the signature byte used as the timestamp payload.

Signatures are then verified. Certificate expiration is checked based on the time of issuance of the last signed timestamp listed in the SignMessage. In practice, it means signatures are considered valid as long as certificates were valid at the time of issuance of the signature.

func (*SignMessage) WritePayload Uses

func (msg *SignMessage) WritePayload(w io.Writer) error

WritePayload constructs a file from the SignMessage and payload according to a format specified by the format identifier. The output file is passed to a writer, which is typically a file descriptor created with os.Open, or a bytes.Buffer.

type Signature Uses

type Signature struct {
    Algorithm      *cose.Algorithm
    CertChain      []*x509.Certificate
    Timestamps     []Timestamp // array of rfc3161 timestamps
    SignatureBytes []byte
    // contains filtered or unexported fields

A Signature is an authority-issued signature of the hash of the signed file

type Timestamp Uses

type Timestamp struct {
    HashAlgorithm crypto.Hash
    HashedMessage []byte
    Time          time.Time
    Accuracy      time.Duration
    SerialNumber  *big.Int
    Certificates  []x509.Certificate

    // Extensions contains raw X.509 extensions from the Extensions field of the
    // timestamp. When parsing time-stamps, this can be used to extract
    // non-critical extensions that are not parsed by this package. When
    // marshaling time-stamps, the Extensions field is ignored, see
    // ExtraExtensions.
    Extensions []pkix.Extension

    // ExtraExtensions contains extensions to be copied, raw, into any marshaled
    // timestamp response. Values override any extensions that would otherwise
    // be produced based on the other fields. The ExtraExtensions field is not
    // populated when parsing timestamp responses, see Extensions.
    ExtraExtensions []pkix.Extension

    // Raw contains the original pkcs7 encoded timestamp as returned by the TSA
    Raw []byte

Timestamp represents a Signed Timestamp issued by a TimeStamp Authority (TSA) according to



Package renard imports 20 packages (graph) and is imported by 1 packages. Updated 2020-03-22. Refresh now. Tools for package owners.