README

MAR Signing
===========

.. sectnum::
.. contents:: Table of Contents

MAR is Firefox's update file format. For a full description, see
`go.mozilla.org/mar`_.

.. _`go.mozilla.org/mar`: https://godoc.org/go.mozilla.org/mar


Configuration
-------------

The only thing needed to configure a MAR signer is a private key, either RSA or
ECDSA P256/P384.

.. code:: yaml

	signers:
    - id: testmar
      type: mar
      privatekey: |
          -----BEGIN PRIVATE KEY-----
          MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDHV+bKFLr1p5FR
		  ...
          -----END PRIVATE KEY-----

Signature request
-----------------

This signer supports `/sign/hash`, `/sign/data` and `/sign/file` endpoints.
They all use the same request format:

.. code:: json

	[
		{
			"input": "Y2FyaWJvdW1hdXJpY2UK",
			"keyid": "testmar"
		}
	]

The `/sign/file` endpoint takes a whole MAR encoded in base64. It will parse the
mar, sign it and return the signed file.

The `/sign/data` and `/sign/hash` endpoint only does the signing step. They
takes a MAR block already prepared for signature, calculate its digest (if
`/sign/data`) and return the signature bytes to be inserted in the signature
field. Because the signer needs to know which algorithm to use for signature,
the signature algorithm can be specified in the signing request options. The
acceptable value of the `sigalg` field can be found in `the constants of the MAR
package`_.

.. _`the constants of the MAR package`: https://godoc.org/go.mozilla.org/mar#pkg-constants

.. code:: json

	[
		{
			"input": "Y2FyaWJvdW1hdXJpY2UK",
			"keyid": "testmar",
			"options": {
				"sigalg": 1
			}
		}
	]

Signature response
------------------

Data & Hash Signing
~~~~~~~~~~~~~~~~~~~

The response to a data or hash signing request contains the base64 of the
signature in the `signature` field of the JSON response. You should decode this
base64 and insert it into the MAR's signature entry.

.. code:: json

	[
	  {
	    "ref": "7khgpu4gcfdv30w8joqxjy1cc",
	    "type": "mar",
	    "signer_id": "testmar",
	    "signature": "MIIGPQYJKoZIhvcN..."
	  }
	]

File Signing
~~~~~~~~~~~~

The response to a file signing request contains the base64 of the signed MAR in the `signed_file` field of the json response. You should base64
decode that field and write the output as a file.

.. code:: json

	[
	  {
	    "ref": "7khgpu4gcfdv30w8joqxjy1cc",
	    "type": "mar",
	    "signer_id": "testmar",
	    "signed_file": "MIIGPQYJKoZIhvcN..."
	  }
	]

Verifying signatures
--------------------

Firefox has a `signmar` tool that can be used to verify MAR signatures. Refer to
`MAR Signing and Verification`_ for more details.

.. _`MAR Signing and Verification`: https://wiki.mozilla.org/Software_Update:MAR_Signing_and_Verification
Expand ▾ Collapse ▴

Documentation

Index

Constants

View Source
const (
	// Type of this signer is "mar"
	Type = "mar"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type MARSigner

type MARSigner struct {
	signer.Configuration
	// contains filtered or unexported fields
}

    MARSigner holds the configuration of the signer

    func New

    func New(conf signer.Configuration) (s *MARSigner, err error)

      New initializes a mar signer using a configuration

      func (*MARSigner) Config

      func (s *MARSigner) Config() signer.Configuration

        Config returns the configuration of the current signer

        func (*MARSigner) GetDefaultOptions

        func (s *MARSigner) GetDefaultOptions() interface{}

          GetDefaultOptions returns default options of the signer

          func (*MARSigner) SignData

          func (s *MARSigner) SignData(data []byte, options interface{}) (signer.Signature, error)

            SignData takes a MAR file already marshalled for signature and returns a base64 encoded signature.

            This function expects the caller to handle parsing of the MAR file, which can be really tricky because the signature headers need to be placed in the file prior to marshalling it for signature. You should consider calling the SignFile interface instead, which will handle all that magic for you.

            func (*MARSigner) SignFile

            func (s *MARSigner) SignFile(input []byte, options interface{}) (signer.SignedFile, error)

              SignFile takes a MAR file and returns a signed MAR file

              func (*MARSigner) SignHash

              func (s *MARSigner) SignHash(hashed []byte, options interface{}) (signer.Signature, error)

                SignHash takes the hash of the signable data of a MAR file, signs it and returns a base64 encoded signature

                type Options

                type Options struct {
                	// SigAlg is an integer that represents the type of signature requested.
                	// It must map the SigAlg constants from the MAR package
                	SigAlg uint32 `json:"sigalg"`
                }

                  Options accepts the name of the signature algorithm used by the SignData interface to decide which algorithm to sign the data with

                  func GetOptions

                  func GetOptions(input interface{}) (options Options, err error)

                    GetOptions takes a input interface and reflects it into a struct of options

                    type Signature

                    type Signature struct {
                    	Data []byte
                    }

                      Signature is a MAR signature

                      func (*Signature) Marshal

                      func (sig *Signature) Marshal() (string, error)

                        Marshal returns the base64 representation of a signature

                        Source Files