diff --git a/unum/vendor/github.com/docker/libtrust/jsonsign.go b/unum/vendor/github.com/docker/libtrust/jsonsign.go
new file mode 100644
index 0000000..cb2ca9a
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/jsonsign.go
@@ -0,0 +1,657 @@
+package libtrust
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/x509"
+	"encoding/base64"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"sort"
+	"time"
+	"unicode"
+)
+
+var (
+	// ErrInvalidSignContent is used when the content to be signed is invalid.
+	ErrInvalidSignContent = errors.New("invalid sign content")
+
+	// ErrInvalidJSONContent is used when invalid json is encountered.
+	ErrInvalidJSONContent = errors.New("invalid json content")
+
+	// ErrMissingSignatureKey is used when the specified signature key
+	// does not exist in the JSON content.
+	ErrMissingSignatureKey = errors.New("missing signature key")
+)
+
+type jsHeader struct {
+	JWK       PublicKey `json:"jwk,omitempty"`
+	Algorithm string    `json:"alg"`
+	Chain     []string  `json:"x5c,omitempty"`
+}
+
+type jsSignature struct {
+	Header    jsHeader `json:"header"`
+	Signature string   `json:"signature"`
+	Protected string   `json:"protected,omitempty"`
+}
+
+type jsSignaturesSorted []jsSignature
+
+func (jsbkid jsSignaturesSorted) Swap(i, j int) { jsbkid[i], jsbkid[j] = jsbkid[j], jsbkid[i] }
+func (jsbkid jsSignaturesSorted) Len() int      { return len(jsbkid) }
+
+func (jsbkid jsSignaturesSorted) Less(i, j int) bool {
+	ki, kj := jsbkid[i].Header.JWK.KeyID(), jsbkid[j].Header.JWK.KeyID()
+	si, sj := jsbkid[i].Signature, jsbkid[j].Signature
+
+	if ki == kj {
+		return si < sj
+	}
+
+	return ki < kj
+}
+
+type signKey struct {
+	PrivateKey
+	Chain []*x509.Certificate
+}
+
+// JSONSignature represents a signature of a json object.
+type JSONSignature struct {
+	payload      string
+	signatures   []jsSignature
+	indent       string
+	formatLength int
+	formatTail   []byte
+}
+
+func newJSONSignature() *JSONSignature {
+	return &JSONSignature{
+		signatures: make([]jsSignature, 0, 1),
+	}
+}
+
+// Payload returns the encoded payload of the signature. This
+// payload should not be signed directly
+func (js *JSONSignature) Payload() ([]byte, error) {
+	return joseBase64UrlDecode(js.payload)
+}
+
+func (js *JSONSignature) protectedHeader() (string, error) {
+	protected := map[string]interface{}{
+		"formatLength": js.formatLength,
+		"formatTail":   joseBase64UrlEncode(js.formatTail),
+		"time":         time.Now().UTC().Format(time.RFC3339),
+	}
+	protectedBytes, err := json.Marshal(protected)
+	if err != nil {
+		return "", err
+	}
+
+	return joseBase64UrlEncode(protectedBytes), nil
+}
+
+func (js *JSONSignature) signBytes(protectedHeader string) ([]byte, error) {
+	buf := make([]byte, len(js.payload)+len(protectedHeader)+1)
+	copy(buf, protectedHeader)
+	buf[len(protectedHeader)] = '.'
+	copy(buf[len(protectedHeader)+1:], js.payload)
+	return buf, nil
+}
+
+// Sign adds a signature using the given private key.
+func (js *JSONSignature) Sign(key PrivateKey) error {
+	protected, err := js.protectedHeader()
+	if err != nil {
+		return err
+	}
+	signBytes, err := js.signBytes(protected)
+	if err != nil {
+		return err
+	}
+	sigBytes, algorithm, err := key.Sign(bytes.NewReader(signBytes), crypto.SHA256)
+	if err != nil {
+		return err
+	}
+
+	js.signatures = append(js.signatures, jsSignature{
+		Header: jsHeader{
+			JWK:       key.PublicKey(),
+			Algorithm: algorithm,
+		},
+		Signature: joseBase64UrlEncode(sigBytes),
+		Protected: protected,
+	})
+
+	return nil
+}
+
+// SignWithChain adds a signature using the given private key
+// and setting the x509 chain. The public key of the first element
+// in the chain must be the public key corresponding with the sign key.
+func (js *JSONSignature) SignWithChain(key PrivateKey, chain []*x509.Certificate) error {
+	// Ensure key.Chain[0] is public key for key
+	//key.Chain.PublicKey
+	//key.PublicKey().CryptoPublicKey()
+
+	// Verify chain
+	protected, err := js.protectedHeader()
+	if err != nil {
+		return err
+	}
+	signBytes, err := js.signBytes(protected)
+	if err != nil {
+		return err
+	}
+	sigBytes, algorithm, err := key.Sign(bytes.NewReader(signBytes), crypto.SHA256)
+	if err != nil {
+		return err
+	}
+
+	header := jsHeader{
+		Chain:     make([]string, len(chain)),
+		Algorithm: algorithm,
+	}
+
+	for i, cert := range chain {
+		header.Chain[i] = base64.StdEncoding.EncodeToString(cert.Raw)
+	}
+
+	js.signatures = append(js.signatures, jsSignature{
+		Header:    header,
+		Signature: joseBase64UrlEncode(sigBytes),
+		Protected: protected,
+	})
+
+	return nil
+}
+
+// Verify verifies all the signatures and returns the list of
+// public keys used to sign. Any x509 chains are not checked.
+func (js *JSONSignature) Verify() ([]PublicKey, error) {
+	keys := make([]PublicKey, len(js.signatures))
+	for i, signature := range js.signatures {
+		signBytes, err := js.signBytes(signature.Protected)
+		if err != nil {
+			return nil, err
+		}
+		var publicKey PublicKey
+		if len(signature.Header.Chain) > 0 {
+			certBytes, err := base64.StdEncoding.DecodeString(signature.Header.Chain[0])
+			if err != nil {
+				return nil, err
+			}
+			cert, err := x509.ParseCertificate(certBytes)
+			if err != nil {
+				return nil, err
+			}
+			publicKey, err = FromCryptoPublicKey(cert.PublicKey)
+			if err != nil {
+				return nil, err
+			}
+		} else if signature.Header.JWK != nil {
+			publicKey = signature.Header.JWK
+		} else {
+			return nil, errors.New("missing public key")
+		}
+
+		sigBytes, err := joseBase64UrlDecode(signature.Signature)
+		if err != nil {
+			return nil, err
+		}
+
+		err = publicKey.Verify(bytes.NewReader(signBytes), signature.Header.Algorithm, sigBytes)
+		if err != nil {
+			return nil, err
+		}
+
+		keys[i] = publicKey
+	}
+	return keys, nil
+}
+
+// VerifyChains verifies all the signatures and the chains associated
+// with each signature and returns the list of verified chains.
+// Signatures without an x509 chain are not checked.
+func (js *JSONSignature) VerifyChains(ca *x509.CertPool) ([][]*x509.Certificate, error) {
+	chains := make([][]*x509.Certificate, 0, len(js.signatures))
+	for _, signature := range js.signatures {
+		signBytes, err := js.signBytes(signature.Protected)
+		if err != nil {
+			return nil, err
+		}
+		var publicKey PublicKey
+		if len(signature.Header.Chain) > 0 {
+			certBytes, err := base64.StdEncoding.DecodeString(signature.Header.Chain[0])
+			if err != nil {
+				return nil, err
+			}
+			cert, err := x509.ParseCertificate(certBytes)
+			if err != nil {
+				return nil, err
+			}
+			publicKey, err = FromCryptoPublicKey(cert.PublicKey)
+			if err != nil {
+				return nil, err
+			}
+			intermediates := x509.NewCertPool()
+			if len(signature.Header.Chain) > 1 {
+				intermediateChain := signature.Header.Chain[1:]
+				for i := range intermediateChain {
+					certBytes, err := base64.StdEncoding.DecodeString(intermediateChain[i])
+					if err != nil {
+						return nil, err
+					}
+					intermediate, err := x509.ParseCertificate(certBytes)
+					if err != nil {
+						return nil, err
+					}
+					intermediates.AddCert(intermediate)
+				}
+			}
+
+			verifyOptions := x509.VerifyOptions{
+				Intermediates: intermediates,
+				Roots:         ca,
+			}
+
+			verifiedChains, err := cert.Verify(verifyOptions)
+			if err != nil {
+				return nil, err
+			}
+			chains = append(chains, verifiedChains...)
+
+			sigBytes, err := joseBase64UrlDecode(signature.Signature)
+			if err != nil {
+				return nil, err
+			}
+
+			err = publicKey.Verify(bytes.NewReader(signBytes), signature.Header.Algorithm, sigBytes)
+			if err != nil {
+				return nil, err
+			}
+		}
+
+	}
+	return chains, nil
+}
+
+// JWS returns JSON serialized JWS according to
+// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-7.2
+func (js *JSONSignature) JWS() ([]byte, error) {
+	if len(js.signatures) == 0 {
+		return nil, errors.New("missing signature")
+	}
+
+	sort.Sort(jsSignaturesSorted(js.signatures))
+
+	jsonMap := map[string]interface{}{
+		"payload":    js.payload,
+		"signatures": js.signatures,
+	}
+
+	return json.MarshalIndent(jsonMap, "", "   ")
+}
+
+func notSpace(r rune) bool {
+	return !unicode.IsSpace(r)
+}
+
+func detectJSONIndent(jsonContent []byte) (indent string) {
+	if len(jsonContent) > 2 && jsonContent[0] == '{' && jsonContent[1] == '\n' {
+		quoteIndex := bytes.IndexRune(jsonContent[1:], '"')
+		if quoteIndex > 0 {
+			indent = string(jsonContent[2 : quoteIndex+1])
+		}
+	}
+	return
+}
+
+type jsParsedHeader struct {
+	JWK       json.RawMessage `json:"jwk"`
+	Algorithm string          `json:"alg"`
+	Chain     []string        `json:"x5c"`
+}
+
+type jsParsedSignature struct {
+	Header    jsParsedHeader `json:"header"`
+	Signature string         `json:"signature"`
+	Protected string         `json:"protected"`
+}
+
+// ParseJWS parses a JWS serialized JSON object into a Json Signature.
+func ParseJWS(content []byte) (*JSONSignature, error) {
+	type jsParsed struct {
+		Payload    string              `json:"payload"`
+		Signatures []jsParsedSignature `json:"signatures"`
+	}
+	parsed := &jsParsed{}
+	err := json.Unmarshal(content, parsed)
+	if err != nil {
+		return nil, err
+	}
+	if len(parsed.Signatures) == 0 {
+		return nil, errors.New("missing signatures")
+	}
+	payload, err := joseBase64UrlDecode(parsed.Payload)
+	if err != nil {
+		return nil, err
+	}
+
+	js, err := NewJSONSignature(payload)
+	if err != nil {
+		return nil, err
+	}
+	js.signatures = make([]jsSignature, len(parsed.Signatures))
+	for i, signature := range parsed.Signatures {
+		header := jsHeader{
+			Algorithm: signature.Header.Algorithm,
+		}
+		if signature.Header.Chain != nil {
+			header.Chain = signature.Header.Chain
+		}
+		if signature.Header.JWK != nil {
+			publicKey, err := UnmarshalPublicKeyJWK([]byte(signature.Header.JWK))
+			if err != nil {
+				return nil, err
+			}
+			header.JWK = publicKey
+		}
+		js.signatures[i] = jsSignature{
+			Header:    header,
+			Signature: signature.Signature,
+			Protected: signature.Protected,
+		}
+	}
+
+	return js, nil
+}
+
+// NewJSONSignature returns a new unsigned JWS from a json byte array.
+// JSONSignature will need to be signed before serializing or storing.
+// Optionally, one or more signatures can be provided as byte buffers,
+// containing serialized JWS signatures, to assemble a fully signed JWS
+// package. It is the callers responsibility to ensure uniqueness of the
+// provided signatures.
+func NewJSONSignature(content []byte, signatures ...[]byte) (*JSONSignature, error) {
+	var dataMap map[string]interface{}
+	err := json.Unmarshal(content, &dataMap)
+	if err != nil {
+		return nil, err
+	}
+
+	js := newJSONSignature()
+	js.indent = detectJSONIndent(content)
+
+	js.payload = joseBase64UrlEncode(content)
+
+	// Find trailing } and whitespace, put in protected header
+	closeIndex := bytes.LastIndexFunc(content, notSpace)
+	if content[closeIndex] != '}' {
+		return nil, ErrInvalidJSONContent
+	}
+	lastRuneIndex := bytes.LastIndexFunc(content[:closeIndex], notSpace)
+	if content[lastRuneIndex] == ',' {
+		return nil, ErrInvalidJSONContent
+	}
+	js.formatLength = lastRuneIndex + 1
+	js.formatTail = content[js.formatLength:]
+
+	if len(signatures) > 0 {
+		for _, signature := range signatures {
+			var parsedJSig jsParsedSignature
+
+			if err := json.Unmarshal(signature, &parsedJSig); err != nil {
+				return nil, err
+			}
+
+			// TODO(stevvooe): A lot of the code below is repeated in
+			// ParseJWS. It will require more refactoring to fix that.
+			jsig := jsSignature{
+				Header: jsHeader{
+					Algorithm: parsedJSig.Header.Algorithm,
+				},
+				Signature: parsedJSig.Signature,
+				Protected: parsedJSig.Protected,
+			}
+
+			if parsedJSig.Header.Chain != nil {
+				jsig.Header.Chain = parsedJSig.Header.Chain
+			}
+
+			if parsedJSig.Header.JWK != nil {
+				publicKey, err := UnmarshalPublicKeyJWK([]byte(parsedJSig.Header.JWK))
+				if err != nil {
+					return nil, err
+				}
+				jsig.Header.JWK = publicKey
+			}
+
+			js.signatures = append(js.signatures, jsig)
+		}
+	}
+
+	return js, nil
+}
+
+// NewJSONSignatureFromMap returns a new unsigned JSONSignature from a map or
+// struct. JWS will need to be signed before serializing or storing.
+func NewJSONSignatureFromMap(content interface{}) (*JSONSignature, error) {
+	switch content.(type) {
+	case map[string]interface{}:
+	case struct{}:
+	default:
+		return nil, errors.New("invalid data type")
+	}
+
+	js := newJSONSignature()
+	js.indent = "   "
+
+	payload, err := json.MarshalIndent(content, "", js.indent)
+	if err != nil {
+		return nil, err
+	}
+	js.payload = joseBase64UrlEncode(payload)
+
+	// Remove '\n}' from formatted section, put in protected header
+	js.formatLength = len(payload) - 2
+	js.formatTail = payload[js.formatLength:]
+
+	return js, nil
+}
+
+func readIntFromMap(key string, m map[string]interface{}) (int, bool) {
+	value, ok := m[key]
+	if !ok {
+		return 0, false
+	}
+	switch v := value.(type) {
+	case int:
+		return v, true
+	case float64:
+		return int(v), true
+	default:
+		return 0, false
+	}
+}
+
+func readStringFromMap(key string, m map[string]interface{}) (v string, ok bool) {
+	value, ok := m[key]
+	if !ok {
+		return "", false
+	}
+	v, ok = value.(string)
+	return
+}
+
+// ParsePrettySignature parses a formatted signature into a
+// JSON signature. If the signatures are missing the format information
+// an error is thrown. The formatted signature must be created by
+// the same method as format signature.
+func ParsePrettySignature(content []byte, signatureKey string) (*JSONSignature, error) {
+	var contentMap map[string]json.RawMessage
+	err := json.Unmarshal(content, &contentMap)
+	if err != nil {
+		return nil, fmt.Errorf("error unmarshalling content: %s", err)
+	}
+	sigMessage, ok := contentMap[signatureKey]
+	if !ok {
+		return nil, ErrMissingSignatureKey
+	}
+
+	var signatureBlocks []jsParsedSignature
+	err = json.Unmarshal([]byte(sigMessage), &signatureBlocks)
+	if err != nil {
+		return nil, fmt.Errorf("error unmarshalling signatures: %s", err)
+	}
+
+	js := newJSONSignature()
+	js.signatures = make([]jsSignature, len(signatureBlocks))
+
+	for i, signatureBlock := range signatureBlocks {
+		protectedBytes, err := joseBase64UrlDecode(signatureBlock.Protected)
+		if err != nil {
+			return nil, fmt.Errorf("base64 decode error: %s", err)
+		}
+		var protectedHeader map[string]interface{}
+		err = json.Unmarshal(protectedBytes, &protectedHeader)
+		if err != nil {
+			return nil, fmt.Errorf("error unmarshalling protected header: %s", err)
+		}
+
+		formatLength, ok := readIntFromMap("formatLength", protectedHeader)
+		if !ok {
+			return nil, errors.New("missing formatted length")
+		}
+		encodedTail, ok := readStringFromMap("formatTail", protectedHeader)
+		if !ok {
+			return nil, errors.New("missing formatted tail")
+		}
+		formatTail, err := joseBase64UrlDecode(encodedTail)
+		if err != nil {
+			return nil, fmt.Errorf("base64 decode error on tail: %s", err)
+		}
+		if js.formatLength == 0 {
+			js.formatLength = formatLength
+		} else if js.formatLength != formatLength {
+			return nil, errors.New("conflicting format length")
+		}
+		if len(js.formatTail) == 0 {
+			js.formatTail = formatTail
+		} else if bytes.Compare(js.formatTail, formatTail) != 0 {
+			return nil, errors.New("conflicting format tail")
+		}
+
+		header := jsHeader{
+			Algorithm: signatureBlock.Header.Algorithm,
+			Chain:     signatureBlock.Header.Chain,
+		}
+		if signatureBlock.Header.JWK != nil {
+			publicKey, err := UnmarshalPublicKeyJWK([]byte(signatureBlock.Header.JWK))
+			if err != nil {
+				return nil, fmt.Errorf("error unmarshalling public key: %s", err)
+			}
+			header.JWK = publicKey
+		}
+		js.signatures[i] = jsSignature{
+			Header:    header,
+			Signature: signatureBlock.Signature,
+			Protected: signatureBlock.Protected,
+		}
+	}
+	if js.formatLength > len(content) {
+		return nil, errors.New("invalid format length")
+	}
+	formatted := make([]byte, js.formatLength+len(js.formatTail))
+	copy(formatted, content[:js.formatLength])
+	copy(formatted[js.formatLength:], js.formatTail)
+	js.indent = detectJSONIndent(formatted)
+	js.payload = joseBase64UrlEncode(formatted)
+
+	return js, nil
+}
+
+// PrettySignature formats a json signature into an easy to read
+// single json serialized object.
+func (js *JSONSignature) PrettySignature(signatureKey string) ([]byte, error) {
+	if len(js.signatures) == 0 {
+		return nil, errors.New("no signatures")
+	}
+	payload, err := joseBase64UrlDecode(js.payload)
+	if err != nil {
+		return nil, err
+	}
+	payload = payload[:js.formatLength]
+
+	sort.Sort(jsSignaturesSorted(js.signatures))
+
+	var marshalled []byte
+	var marshallErr error
+	if js.indent != "" {
+		marshalled, marshallErr = json.MarshalIndent(js.signatures, js.indent, js.indent)
+	} else {
+		marshalled, marshallErr = json.Marshal(js.signatures)
+	}
+	if marshallErr != nil {
+		return nil, marshallErr
+	}
+
+	buf := bytes.NewBuffer(make([]byte, 0, len(payload)+len(marshalled)+34))
+	buf.Write(payload)
+	buf.WriteByte(',')
+	if js.indent != "" {
+		buf.WriteByte('\n')
+		buf.WriteString(js.indent)
+		buf.WriteByte('"')
+		buf.WriteString(signatureKey)
+		buf.WriteString("\": ")
+		buf.Write(marshalled)
+		buf.WriteByte('\n')
+	} else {
+		buf.WriteByte('"')
+		buf.WriteString(signatureKey)
+		buf.WriteString("\":")
+		buf.Write(marshalled)
+	}
+	buf.WriteByte('}')
+
+	return buf.Bytes(), nil
+}
+
+// Signatures provides the signatures on this JWS as opaque blobs, sorted by
+// keyID. These blobs can be stored and reassembled with payloads. Internally,
+// they are simply marshaled json web signatures but implementations should
+// not rely on this.
+func (js *JSONSignature) Signatures() ([][]byte, error) {
+	sort.Sort(jsSignaturesSorted(js.signatures))
+
+	var sb [][]byte
+	for _, jsig := range js.signatures {
+		p, err := json.Marshal(jsig)
+		if err != nil {
+			return nil, err
+		}
+
+		sb = append(sb, p)
+	}
+
+	return sb, nil
+}
+
+// Merge combines the signatures from one or more other signatures into the
+// method receiver. If the payloads differ for any argument, an error will be
+// returned and the receiver will not be modified.
+func (js *JSONSignature) Merge(others ...*JSONSignature) error {
+	merged := js.signatures
+	for _, other := range others {
+		if js.payload != other.payload {
+			return fmt.Errorf("payloads differ from merge target")
+		}
+		merged = append(merged, other.signatures...)
+	}
+
+	js.signatures = merged
+	return nil
+}
