AMO/SigningService/API

From MozillaWiki
Jump to: navigation, search

General Info

Abstract

This document describes how addons are signed to be automatically in Mozilla's Marketplace infrastructure.

Definitions

endpoint-url 
The full URI for the service including the version string for the API as defined below.
version string 
This revision of the protocol is 1.0 so the version string is "/1.0/".
root certificate 
The signing CA's root certificate in standard X.509 format. This certificate will be included in each build of the user agent.
generated key and certificate 
An very short lived private and public key pair that are generated in an automated fashion, on demand. The public key is then certified by the CA root certificate.
unsigned archive 
A JAR file that has been uploaded by a developer but not signed by the service yet.
signed archive 
A JAR file that has been created by Zamboni to include the contents of the unsigned archive and the generated manifest and signature files.
manifest file 
A file describing the contents of a JAR file. Format detailed here.
signature file 
A file of the same format as the manifest file that contains a single entry for the manifest file. Official format detailed here. Note that XPI signing is an incompatible subset of JAR signing due to changes made in how XPIs are verified for improved security.
app id 
A unique identifier for the combination of addon name and version that will be used in the generated key and certificate. A strong preference for human readable.

Related documentation

JAR signing 
JDK documentation
JAR validation 
JDK documentation
PKCS#7 
Cryptographic Message Syntax is a brief intro with links

Data formats

The data formats are described in depth in the JDK documentation. There are three basic formats being dealt with:

  • Zip archives
  • An HTTP header like format for archive manifests and signatures
  • PKCS#7 detached signature in DER format

Components

Signing clients 
https://github.com/mozilla/signing-clients/

signing-clients is just a simple library for generating, parsing, and formatting the manifest and signature file formats.

Trunion 
https://github.com/mozilla/trunion/

The actual signing service. This is the same code base as the receipt signing service but runs in a separate process space to provide a degree of separation between app signing, receipt signing, and addon signing credentials.

Zamboni, packaged app handling specifically 
https://github.com/mozilla/zamboni/blob/master/lib/crypto/packaged.py

Zamboni is responsible for receiving and storing an uploaded application archive, generating manifest and signature files for it via the signing-clients library, requesting a signature from the trunion signing service, and creating a new signed application archive containing the additional three files.

API

POST http
//<endpoint-url>/sign_addon OR http://<endpoint-url>/sign/addon :
  • This takes two arguments:
    • the archive's signature file as multipart/form-data as an input with the name "file" with a filename included.
    • the app id for this XPI at this version.
  • It then returns a PKCS#7 detached signature of the uploaded content in a JSON object with a single key and value pair. The key is the uploaded content's specified filename with its extension(".sf") replaced with ".rsa". The value is a base64 encoded representation of the PKCS#7 data.

Example request

POST /1.0/sign_addon HTTP/1.1
Host: localhost:5000
Content-Length: 306
Content-Type: multipart/form-data; boundary=df8e3fdaf425408e956aff8ca19d0263
Accept-Encoding: gzip, deflate, compress
Accept: */*
User-Agent: python-requests/0.14.2 CPython/2.7.1 Darwin/11.4.2

--df8e3fdaf425408e956aff8ca19d0263
Content-Disposition: form-data; name="id"
Content-Type: text/plain
digital-doughnuts-addon-v1.0
--df8e3fdaf425408e956aff8ca19d0263
Content-Disposition: form-data; name="file"; filename="zigbert.sf"
Content-Type: application/octet-stream

Signature-Version: 1.0
MD5-Digest-Manifest: PTUbaADVign9DDK3ntq9ww==
SHA1-Digest-Manifest: FkVPRYqW9UT8kcbm8VS08TIWsH4=

--df8e3fdaf425408e956aff8ca19d0263--

Example response

Response body truncated for brevity.

HTTP/1.0 200 OK
Server: PasteWSGIServer/0.5 Python/2.6.8
Date: Wed, 01 Oct 2014 20:43:05 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 3607

{"zigbert.rsa": "MIIKfQYJKoZIhvcNAQcCoIIKbjCCCmoCAQExCzAJBgUrDgMCGgUAMAsGCSq...=="}

HTTP response codes

200 OK 
The request was processed successfully and the server is returning a PKCS#7 signature
400 Bad request 
The request body was incorrectly formatted
401 Unauthorized 
The authentication credentials are invalid. At the moment authorization consists of a simple whitelist of IPs. In the future this may be used to indicate a BrowserID or other authentication mechanism has failed or the credentials are not authorized to use the service.
409 Conflict 
A certificate has already been generated for the app id provided
503 Service Unavailable 
Indicates that the server(s) are undergoing maintenance.