diff --git a/unum/vendor/github.com/docker/libtrust/LICENSE b/unum/vendor/github.com/docker/libtrust/LICENSE
new file mode 100644
index 0000000..2744858
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/LICENSE
@@ -0,0 +1,191 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   Copyright 2014 Docker, Inc.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/unum/vendor/github.com/docker/libtrust/README.md b/unum/vendor/github.com/docker/libtrust/README.md
new file mode 100644
index 0000000..8e7db38
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/README.md
@@ -0,0 +1,18 @@
+# libtrust
+
+Libtrust is library for managing authentication and authorization using public key cryptography.
+
+Authentication is handled using the identity attached to the public key.
+Libtrust provides multiple methods to prove possession of the private key associated with an identity.
+ - TLS x509 certificates
+ - Signature verification
+ - Key Challenge
+
+Authorization and access control is managed through a distributed trust graph.
+Trust servers are used as the authorities of the trust graph and allow caching portions of the graph for faster access.
+
+## Copyright and license
+
+Code and documentation copyright 2014 Docker, inc. Code released under the Apache 2.0 license.
+Docs released under Creative commons.
+
diff --git a/unum/vendor/github.com/docker/libtrust/certificates.go b/unum/vendor/github.com/docker/libtrust/certificates.go
new file mode 100644
index 0000000..3dcca33
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/certificates.go
@@ -0,0 +1,175 @@
+package libtrust
+
+import (
+	"crypto/rand"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/pem"
+	"fmt"
+	"io/ioutil"
+	"math/big"
+	"net"
+	"time"
+)
+
+type certTemplateInfo struct {
+	commonName  string
+	domains     []string
+	ipAddresses []net.IP
+	isCA        bool
+	clientAuth  bool
+	serverAuth  bool
+}
+
+func generateCertTemplate(info *certTemplateInfo) *x509.Certificate {
+	// Generate a certificate template which is valid from the past week to
+	// 10 years from now. The usage of the certificate depends on the
+	// specified fields in the given certTempInfo object.
+	var (
+		keyUsage    x509.KeyUsage
+		extKeyUsage []x509.ExtKeyUsage
+	)
+
+	if info.isCA {
+		keyUsage = x509.KeyUsageCertSign
+	}
+
+	if info.clientAuth {
+		extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageClientAuth)
+	}
+
+	if info.serverAuth {
+		extKeyUsage = append(extKeyUsage, x509.ExtKeyUsageServerAuth)
+	}
+
+	return &x509.Certificate{
+		SerialNumber: big.NewInt(0),
+		Subject: pkix.Name{
+			CommonName: info.commonName,
+		},
+		NotBefore:             time.Now().Add(-time.Hour * 24 * 7),
+		NotAfter:              time.Now().Add(time.Hour * 24 * 365 * 10),
+		DNSNames:              info.domains,
+		IPAddresses:           info.ipAddresses,
+		IsCA:                  info.isCA,
+		KeyUsage:              keyUsage,
+		ExtKeyUsage:           extKeyUsage,
+		BasicConstraintsValid: info.isCA,
+	}
+}
+
+func generateCert(pub PublicKey, priv PrivateKey, subInfo, issInfo *certTemplateInfo) (cert *x509.Certificate, err error) {
+	pubCertTemplate := generateCertTemplate(subInfo)
+	privCertTemplate := generateCertTemplate(issInfo)
+
+	certDER, err := x509.CreateCertificate(
+		rand.Reader, pubCertTemplate, privCertTemplate,
+		pub.CryptoPublicKey(), priv.CryptoPrivateKey(),
+	)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create certificate: %s", err)
+	}
+
+	cert, err = x509.ParseCertificate(certDER)
+	if err != nil {
+		return nil, fmt.Errorf("failed to parse certificate: %s", err)
+	}
+
+	return
+}
+
+// GenerateSelfSignedServerCert creates a self-signed certificate for the
+// given key which is to be used for TLS servers with the given domains and
+// IP addresses.
+func GenerateSelfSignedServerCert(key PrivateKey, domains []string, ipAddresses []net.IP) (*x509.Certificate, error) {
+	info := &certTemplateInfo{
+		commonName:  key.KeyID(),
+		domains:     domains,
+		ipAddresses: ipAddresses,
+		serverAuth:  true,
+	}
+
+	return generateCert(key.PublicKey(), key, info, info)
+}
+
+// GenerateSelfSignedClientCert creates a self-signed certificate for the
+// given key which is to be used for TLS clients.
+func GenerateSelfSignedClientCert(key PrivateKey) (*x509.Certificate, error) {
+	info := &certTemplateInfo{
+		commonName: key.KeyID(),
+		clientAuth: true,
+	}
+
+	return generateCert(key.PublicKey(), key, info, info)
+}
+
+// GenerateCACert creates a certificate which can be used as a trusted
+// certificate authority.
+func GenerateCACert(signer PrivateKey, trustedKey PublicKey) (*x509.Certificate, error) {
+	subjectInfo := &certTemplateInfo{
+		commonName: trustedKey.KeyID(),
+		isCA:       true,
+	}
+	issuerInfo := &certTemplateInfo{
+		commonName: signer.KeyID(),
+	}
+
+	return generateCert(trustedKey, signer, subjectInfo, issuerInfo)
+}
+
+// GenerateCACertPool creates a certificate authority pool to be used for a
+// TLS configuration. Any self-signed certificates issued by the specified
+// trusted keys will be verified during a TLS handshake
+func GenerateCACertPool(signer PrivateKey, trustedKeys []PublicKey) (*x509.CertPool, error) {
+	certPool := x509.NewCertPool()
+
+	for _, trustedKey := range trustedKeys {
+		cert, err := GenerateCACert(signer, trustedKey)
+		if err != nil {
+			return nil, fmt.Errorf("failed to generate CA certificate: %s", err)
+		}
+
+		certPool.AddCert(cert)
+	}
+
+	return certPool, nil
+}
+
+// LoadCertificateBundle loads certificates from the given file.  The file should be pem encoded
+// containing one or more certificates.  The expected pem type is "CERTIFICATE".
+func LoadCertificateBundle(filename string) ([]*x509.Certificate, error) {
+	b, err := ioutil.ReadFile(filename)
+	if err != nil {
+		return nil, err
+	}
+	certificates := []*x509.Certificate{}
+	var block *pem.Block
+	block, b = pem.Decode(b)
+	for ; block != nil; block, b = pem.Decode(b) {
+		if block.Type == "CERTIFICATE" {
+			cert, err := x509.ParseCertificate(block.Bytes)
+			if err != nil {
+				return nil, err
+			}
+			certificates = append(certificates, cert)
+		} else {
+			return nil, fmt.Errorf("invalid pem block type: %s", block.Type)
+		}
+	}
+
+	return certificates, nil
+}
+
+// LoadCertificatePool loads a CA pool from the given file.  The file should be pem encoded
+// containing one or more certificates. The expected pem type is "CERTIFICATE".
+func LoadCertificatePool(filename string) (*x509.CertPool, error) {
+	certs, err := LoadCertificateBundle(filename)
+	if err != nil {
+		return nil, err
+	}
+	pool := x509.NewCertPool()
+	for _, cert := range certs {
+		pool.AddCert(cert)
+	}
+	return pool, nil
+}
diff --git a/unum/vendor/github.com/docker/libtrust/doc.go b/unum/vendor/github.com/docker/libtrust/doc.go
new file mode 100644
index 0000000..ec5d215
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/doc.go
@@ -0,0 +1,9 @@
+/*
+Package libtrust provides an interface for managing authentication and
+authorization using public key cryptography. Authentication is handled
+using the identity attached to the public key and verified through TLS
+x509 certificates, a key challenge, or signature. Authorization and
+access control is managed through a trust graph distributed between
+both remote trust servers and locally cached and managed data.
+*/
+package libtrust
diff --git a/unum/vendor/github.com/docker/libtrust/ec_key.go b/unum/vendor/github.com/docker/libtrust/ec_key.go
new file mode 100644
index 0000000..00bbe4b
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/ec_key.go
@@ -0,0 +1,428 @@
+package libtrust
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/x509"
+	"encoding/json"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"io"
+	"math/big"
+)
+
+/*
+ * EC DSA PUBLIC KEY
+ */
+
+// ecPublicKey implements a libtrust.PublicKey using elliptic curve digital
+// signature algorithms.
+type ecPublicKey struct {
+	*ecdsa.PublicKey
+	curveName          string
+	signatureAlgorithm *signatureAlgorithm
+	extended           map[string]interface{}
+}
+
+func fromECPublicKey(cryptoPublicKey *ecdsa.PublicKey) (*ecPublicKey, error) {
+	curve := cryptoPublicKey.Curve
+
+	switch {
+	case curve == elliptic.P256():
+		return &ecPublicKey{cryptoPublicKey, "P-256", es256, map[string]interface{}{}}, nil
+	case curve == elliptic.P384():
+		return &ecPublicKey{cryptoPublicKey, "P-384", es384, map[string]interface{}{}}, nil
+	case curve == elliptic.P521():
+		return &ecPublicKey{cryptoPublicKey, "P-521", es512, map[string]interface{}{}}, nil
+	default:
+		return nil, errors.New("unsupported elliptic curve")
+	}
+}
+
+// KeyType returns the key type for elliptic curve keys, i.e., "EC".
+func (k *ecPublicKey) KeyType() string {
+	return "EC"
+}
+
+// CurveName returns the elliptic curve identifier.
+// Possible values are "P-256", "P-384", and "P-521".
+func (k *ecPublicKey) CurveName() string {
+	return k.curveName
+}
+
+// KeyID returns a distinct identifier which is unique to this Public Key.
+func (k *ecPublicKey) KeyID() string {
+	return keyIDFromCryptoKey(k)
+}
+
+func (k *ecPublicKey) String() string {
+	return fmt.Sprintf("EC Public Key <%s>", k.KeyID())
+}
+
+// Verify verifyies the signature of the data in the io.Reader using this
+// PublicKey. The alg parameter should identify the digital signature
+// algorithm which was used to produce the signature and should be supported
+// by this public key. Returns a nil error if the signature is valid.
+func (k *ecPublicKey) Verify(data io.Reader, alg string, signature []byte) error {
+	// For EC keys there is only one supported signature algorithm depending
+	// on the curve parameters.
+	if k.signatureAlgorithm.HeaderParam() != alg {
+		return fmt.Errorf("unable to verify signature: EC Public Key with curve %q does not support signature algorithm %q", k.curveName, alg)
+	}
+
+	// signature is the concatenation of (r, s), base64Url encoded.
+	sigLength := len(signature)
+	expectedOctetLength := 2 * ((k.Params().BitSize + 7) >> 3)
+	if sigLength != expectedOctetLength {
+		return fmt.Errorf("signature length is %d octets long, should be %d", sigLength, expectedOctetLength)
+	}
+
+	rBytes, sBytes := signature[:sigLength/2], signature[sigLength/2:]
+	r := new(big.Int).SetBytes(rBytes)
+	s := new(big.Int).SetBytes(sBytes)
+
+	hasher := k.signatureAlgorithm.HashID().New()
+	_, err := io.Copy(hasher, data)
+	if err != nil {
+		return fmt.Errorf("error reading data to sign: %s", err)
+	}
+	hash := hasher.Sum(nil)
+
+	if !ecdsa.Verify(k.PublicKey, hash, r, s) {
+		return errors.New("invalid signature")
+	}
+
+	return nil
+}
+
+// CryptoPublicKey returns the internal object which can be used as a
+// crypto.PublicKey for use with other standard library operations. The type
+// is either *rsa.PublicKey or *ecdsa.PublicKey
+func (k *ecPublicKey) CryptoPublicKey() crypto.PublicKey {
+	return k.PublicKey
+}
+
+func (k *ecPublicKey) toMap() map[string]interface{} {
+	jwk := make(map[string]interface{})
+	for k, v := range k.extended {
+		jwk[k] = v
+	}
+	jwk["kty"] = k.KeyType()
+	jwk["kid"] = k.KeyID()
+	jwk["crv"] = k.CurveName()
+
+	xBytes := k.X.Bytes()
+	yBytes := k.Y.Bytes()
+	octetLength := (k.Params().BitSize + 7) >> 3
+	// MUST include leading zeros in the output so that x, y are each
+	// *octetLength* bytes long.
+	xBuf := make([]byte, octetLength-len(xBytes), octetLength)
+	yBuf := make([]byte, octetLength-len(yBytes), octetLength)
+	xBuf = append(xBuf, xBytes...)
+	yBuf = append(yBuf, yBytes...)
+
+	jwk["x"] = joseBase64UrlEncode(xBuf)
+	jwk["y"] = joseBase64UrlEncode(yBuf)
+
+	return jwk
+}
+
+// MarshalJSON serializes this Public Key using the JWK JSON serialization format for
+// elliptic curve keys.
+func (k *ecPublicKey) MarshalJSON() (data []byte, err error) {
+	return json.Marshal(k.toMap())
+}
+
+// PEMBlock serializes this Public Key to DER-encoded PKIX format.
+func (k *ecPublicKey) PEMBlock() (*pem.Block, error) {
+	derBytes, err := x509.MarshalPKIXPublicKey(k.PublicKey)
+	if err != nil {
+		return nil, fmt.Errorf("unable to serialize EC PublicKey to DER-encoded PKIX format: %s", err)
+	}
+	k.extended["kid"] = k.KeyID() // For display purposes.
+	return createPemBlock("PUBLIC KEY", derBytes, k.extended)
+}
+
+func (k *ecPublicKey) AddExtendedField(field string, value interface{}) {
+	k.extended[field] = value
+}
+
+func (k *ecPublicKey) GetExtendedField(field string) interface{} {
+	v, ok := k.extended[field]
+	if !ok {
+		return nil
+	}
+	return v
+}
+
+func ecPublicKeyFromMap(jwk map[string]interface{}) (*ecPublicKey, error) {
+	// JWK key type (kty) has already been determined to be "EC".
+	// Need to extract 'crv', 'x', 'y', and 'kid' and check for
+	// consistency.
+
+	// Get the curve identifier value.
+	crv, err := stringFromMap(jwk, "crv")
+	if err != nil {
+		return nil, fmt.Errorf("JWK EC Public Key curve identifier: %s", err)
+	}
+
+	var (
+		curve  elliptic.Curve
+		sigAlg *signatureAlgorithm
+	)
+
+	switch {
+	case crv == "P-256":
+		curve = elliptic.P256()
+		sigAlg = es256
+	case crv == "P-384":
+		curve = elliptic.P384()
+		sigAlg = es384
+	case crv == "P-521":
+		curve = elliptic.P521()
+		sigAlg = es512
+	default:
+		return nil, fmt.Errorf("JWK EC Public Key curve identifier not supported: %q\n", crv)
+	}
+
+	// Get the X and Y coordinates for the public key point.
+	xB64Url, err := stringFromMap(jwk, "x")
+	if err != nil {
+		return nil, fmt.Errorf("JWK EC Public Key x-coordinate: %s", err)
+	}
+	x, err := parseECCoordinate(xB64Url, curve)
+	if err != nil {
+		return nil, fmt.Errorf("JWK EC Public Key x-coordinate: %s", err)
+	}
+
+	yB64Url, err := stringFromMap(jwk, "y")
+	if err != nil {
+		return nil, fmt.Errorf("JWK EC Public Key y-coordinate: %s", err)
+	}
+	y, err := parseECCoordinate(yB64Url, curve)
+	if err != nil {
+		return nil, fmt.Errorf("JWK EC Public Key y-coordinate: %s", err)
+	}
+
+	key := &ecPublicKey{
+		PublicKey: &ecdsa.PublicKey{Curve: curve, X: x, Y: y},
+		curveName: crv, signatureAlgorithm: sigAlg,
+	}
+
+	// Key ID is optional too, but if it exists, it should match the key.
+	_, ok := jwk["kid"]
+	if ok {
+		kid, err := stringFromMap(jwk, "kid")
+		if err != nil {
+			return nil, fmt.Errorf("JWK EC Public Key ID: %s", err)
+		}
+		if kid != key.KeyID() {
+			return nil, fmt.Errorf("JWK EC Public Key ID does not match: %s", kid)
+		}
+	}
+
+	key.extended = jwk
+
+	return key, nil
+}
+
+/*
+ * EC DSA PRIVATE KEY
+ */
+
+// ecPrivateKey implements a JWK Private Key using elliptic curve digital signature
+// algorithms.
+type ecPrivateKey struct {
+	ecPublicKey
+	*ecdsa.PrivateKey
+}
+
+func fromECPrivateKey(cryptoPrivateKey *ecdsa.PrivateKey) (*ecPrivateKey, error) {
+	publicKey, err := fromECPublicKey(&cryptoPrivateKey.PublicKey)
+	if err != nil {
+		return nil, err
+	}
+
+	return &ecPrivateKey{*publicKey, cryptoPrivateKey}, nil
+}
+
+// PublicKey returns the Public Key data associated with this Private Key.
+func (k *ecPrivateKey) PublicKey() PublicKey {
+	return &k.ecPublicKey
+}
+
+func (k *ecPrivateKey) String() string {
+	return fmt.Sprintf("EC Private Key <%s>", k.KeyID())
+}
+
+// Sign signs the data read from the io.Reader using a signature algorithm supported
+// by the elliptic curve private key. If the specified hashing algorithm is
+// supported by this key, that hash function is used to generate the signature
+// otherwise the the default hashing algorithm for this key is used. Returns
+// the signature and the name of the JWK signature algorithm used, e.g.,
+// "ES256", "ES384", "ES512".
+func (k *ecPrivateKey) Sign(data io.Reader, hashID crypto.Hash) (signature []byte, alg string, err error) {
+	// Generate a signature of the data using the internal alg.
+	// The given hashId is only a suggestion, and since EC keys only support
+	// on signature/hash algorithm given the curve name, we disregard it for
+	// the elliptic curve JWK signature implementation.
+	hasher := k.signatureAlgorithm.HashID().New()
+	_, err = io.Copy(hasher, data)
+	if err != nil {
+		return nil, "", fmt.Errorf("error reading data to sign: %s", err)
+	}
+	hash := hasher.Sum(nil)
+
+	r, s, err := ecdsa.Sign(rand.Reader, k.PrivateKey, hash)
+	if err != nil {
+		return nil, "", fmt.Errorf("error producing signature: %s", err)
+	}
+	rBytes, sBytes := r.Bytes(), s.Bytes()
+	octetLength := (k.ecPublicKey.Params().BitSize + 7) >> 3
+	// MUST include leading zeros in the output
+	rBuf := make([]byte, octetLength-len(rBytes), octetLength)
+	sBuf := make([]byte, octetLength-len(sBytes), octetLength)
+
+	rBuf = append(rBuf, rBytes...)
+	sBuf = append(sBuf, sBytes...)
+
+	signature = append(rBuf, sBuf...)
+	alg = k.signatureAlgorithm.HeaderParam()
+
+	return
+}
+
+// CryptoPrivateKey returns the internal object which can be used as a
+// crypto.PublicKey for use with other standard library operations. The type
+// is either *rsa.PublicKey or *ecdsa.PublicKey
+func (k *ecPrivateKey) CryptoPrivateKey() crypto.PrivateKey {
+	return k.PrivateKey
+}
+
+func (k *ecPrivateKey) toMap() map[string]interface{} {
+	jwk := k.ecPublicKey.toMap()
+
+	dBytes := k.D.Bytes()
+	// The length of this octet string MUST be ceiling(log-base-2(n)/8)
+	// octets (where n is the order of the curve). This is because the private
+	// key d must be in the interval [1, n-1] so the bitlength of d should be
+	// no larger than the bitlength of n-1. The easiest way to find the octet
+	// length is to take bitlength(n-1), add 7 to force a carry, and shift this
+	// bit sequence right by 3, which is essentially dividing by 8 and adding
+	// 1 if there is any remainder. Thus, the private key value d should be
+	// output to (bitlength(n-1)+7)>>3 octets.
+	n := k.ecPublicKey.Params().N
+	octetLength := (new(big.Int).Sub(n, big.NewInt(1)).BitLen() + 7) >> 3
+	// Create a buffer with the necessary zero-padding.
+	dBuf := make([]byte, octetLength-len(dBytes), octetLength)
+	dBuf = append(dBuf, dBytes...)
+
+	jwk["d"] = joseBase64UrlEncode(dBuf)
+
+	return jwk
+}
+
+// MarshalJSON serializes this Private Key using the JWK JSON serialization format for
+// elliptic curve keys.
+func (k *ecPrivateKey) MarshalJSON() (data []byte, err error) {
+	return json.Marshal(k.toMap())
+}
+
+// PEMBlock serializes this Private Key to DER-encoded PKIX format.
+func (k *ecPrivateKey) PEMBlock() (*pem.Block, error) {
+	derBytes, err := x509.MarshalECPrivateKey(k.PrivateKey)
+	if err != nil {
+		return nil, fmt.Errorf("unable to serialize EC PrivateKey to DER-encoded PKIX format: %s", err)
+	}
+	k.extended["keyID"] = k.KeyID() // For display purposes.
+	return createPemBlock("EC PRIVATE KEY", derBytes, k.extended)
+}
+
+func ecPrivateKeyFromMap(jwk map[string]interface{}) (*ecPrivateKey, error) {
+	dB64Url, err := stringFromMap(jwk, "d")
+	if err != nil {
+		return nil, fmt.Errorf("JWK EC Private Key: %s", err)
+	}
+
+	// JWK key type (kty) has already been determined to be "EC".
+	// Need to extract the public key information, then extract the private
+	// key value 'd'.
+	publicKey, err := ecPublicKeyFromMap(jwk)
+	if err != nil {
+		return nil, err
+	}
+
+	d, err := parseECPrivateParam(dB64Url, publicKey.Curve)
+	if err != nil {
+		return nil, fmt.Errorf("JWK EC Private Key d-param: %s", err)
+	}
+
+	key := &ecPrivateKey{
+		ecPublicKey: *publicKey,
+		PrivateKey: &ecdsa.PrivateKey{
+			PublicKey: *publicKey.PublicKey,
+			D:         d,
+		},
+	}
+
+	return key, nil
+}
+
+/*
+ *	Key Generation Functions.
+ */
+
+func generateECPrivateKey(curve elliptic.Curve) (k *ecPrivateKey, err error) {
+	k = new(ecPrivateKey)
+	k.PrivateKey, err = ecdsa.GenerateKey(curve, rand.Reader)
+	if err != nil {
+		return nil, err
+	}
+
+	k.ecPublicKey.PublicKey = &k.PrivateKey.PublicKey
+	k.extended = make(map[string]interface{})
+
+	return
+}
+
+// GenerateECP256PrivateKey generates a key pair using elliptic curve P-256.
+func GenerateECP256PrivateKey() (PrivateKey, error) {
+	k, err := generateECPrivateKey(elliptic.P256())
+	if err != nil {
+		return nil, fmt.Errorf("error generating EC P-256 key: %s", err)
+	}
+
+	k.curveName = "P-256"
+	k.signatureAlgorithm = es256
+
+	return k, nil
+}
+
+// GenerateECP384PrivateKey generates a key pair using elliptic curve P-384.
+func GenerateECP384PrivateKey() (PrivateKey, error) {
+	k, err := generateECPrivateKey(elliptic.P384())
+	if err != nil {
+		return nil, fmt.Errorf("error generating EC P-384 key: %s", err)
+	}
+
+	k.curveName = "P-384"
+	k.signatureAlgorithm = es384
+
+	return k, nil
+}
+
+// GenerateECP521PrivateKey generates aß key pair using elliptic curve P-521.
+func GenerateECP521PrivateKey() (PrivateKey, error) {
+	k, err := generateECPrivateKey(elliptic.P521())
+	if err != nil {
+		return nil, fmt.Errorf("error generating EC P-521 key: %s", err)
+	}
+
+	k.curveName = "P-521"
+	k.signatureAlgorithm = es512
+
+	return k, nil
+}
diff --git a/unum/vendor/github.com/docker/libtrust/filter.go b/unum/vendor/github.com/docker/libtrust/filter.go
new file mode 100644
index 0000000..5b2b4fc
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/filter.go
@@ -0,0 +1,50 @@
+package libtrust
+
+import (
+	"path/filepath"
+)
+
+// FilterByHosts filters the list of PublicKeys to only those which contain a
+// 'hosts' pattern which matches the given host. If *includeEmpty* is true,
+// then keys which do not specify any hosts are also returned.
+func FilterByHosts(keys []PublicKey, host string, includeEmpty bool) ([]PublicKey, error) {
+	filtered := make([]PublicKey, 0, len(keys))
+
+	for _, pubKey := range keys {
+		var hosts []string
+		switch v := pubKey.GetExtendedField("hosts").(type) {
+		case []string:
+			hosts = v
+		case []interface{}:
+			for _, value := range v {
+				h, ok := value.(string)
+				if !ok {
+					continue
+				}
+				hosts = append(hosts, h)
+			}
+		}
+
+		if len(hosts) == 0 {
+			if includeEmpty {
+				filtered = append(filtered, pubKey)
+			}
+			continue
+		}
+
+		// Check if any hosts match pattern
+		for _, hostPattern := range hosts {
+			match, err := filepath.Match(hostPattern, host)
+			if err != nil {
+				return nil, err
+			}
+
+			if match {
+				filtered = append(filtered, pubKey)
+				continue
+			}
+		}
+	}
+
+	return filtered, nil
+}
diff --git a/unum/vendor/github.com/docker/libtrust/hash.go b/unum/vendor/github.com/docker/libtrust/hash.go
new file mode 100644
index 0000000..a2df787
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/hash.go
@@ -0,0 +1,56 @@
+package libtrust
+
+import (
+	"crypto"
+	_ "crypto/sha256" // Registrer SHA224 and SHA256
+	_ "crypto/sha512" // Registrer SHA384 and SHA512
+	"fmt"
+)
+
+type signatureAlgorithm struct {
+	algHeaderParam string
+	hashID         crypto.Hash
+}
+
+func (h *signatureAlgorithm) HeaderParam() string {
+	return h.algHeaderParam
+}
+
+func (h *signatureAlgorithm) HashID() crypto.Hash {
+	return h.hashID
+}
+
+var (
+	rs256 = &signatureAlgorithm{"RS256", crypto.SHA256}
+	rs384 = &signatureAlgorithm{"RS384", crypto.SHA384}
+	rs512 = &signatureAlgorithm{"RS512", crypto.SHA512}
+	es256 = &signatureAlgorithm{"ES256", crypto.SHA256}
+	es384 = &signatureAlgorithm{"ES384", crypto.SHA384}
+	es512 = &signatureAlgorithm{"ES512", crypto.SHA512}
+)
+
+func rsaSignatureAlgorithmByName(alg string) (*signatureAlgorithm, error) {
+	switch {
+	case alg == "RS256":
+		return rs256, nil
+	case alg == "RS384":
+		return rs384, nil
+	case alg == "RS512":
+		return rs512, nil
+	default:
+		return nil, fmt.Errorf("RSA Digital Signature Algorithm %q not supported", alg)
+	}
+}
+
+func rsaPKCS1v15SignatureAlgorithmForHashID(hashID crypto.Hash) *signatureAlgorithm {
+	switch {
+	case hashID == crypto.SHA512:
+		return rs512
+	case hashID == crypto.SHA384:
+		return rs384
+	case hashID == crypto.SHA256:
+		fallthrough
+	default:
+		return rs256
+	}
+}
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
+}
diff --git a/unum/vendor/github.com/docker/libtrust/key.go b/unum/vendor/github.com/docker/libtrust/key.go
new file mode 100644
index 0000000..73642db
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/key.go
@@ -0,0 +1,253 @@
+package libtrust
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/x509"
+	"encoding/json"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"io"
+)
+
+// PublicKey is a generic interface for a Public Key.
+type PublicKey interface {
+	// KeyType returns the key type for this key. For elliptic curve keys,
+	// this value should be "EC". For RSA keys, this value should be "RSA".
+	KeyType() string
+	// KeyID returns a distinct identifier which is unique to this Public Key.
+	// The format generated by this library is a base32 encoding of a 240 bit
+	// hash of the public key data divided into 12 groups like so:
+	//    ABCD:EFGH:IJKL:MNOP:QRST:UVWX:YZ23:4567:ABCD:EFGH:IJKL:MNOP
+	KeyID() string
+	// Verify verifyies the signature of the data in the io.Reader using this
+	// Public Key. The alg parameter should identify the digital signature
+	// algorithm which was used to produce the signature and should be
+	// supported by this public key. Returns a nil error if the signature
+	// is valid.
+	Verify(data io.Reader, alg string, signature []byte) error
+	// CryptoPublicKey returns the internal object which can be used as a
+	// crypto.PublicKey for use with other standard library operations. The type
+	// is either *rsa.PublicKey or *ecdsa.PublicKey
+	CryptoPublicKey() crypto.PublicKey
+	// These public keys can be serialized to the standard JSON encoding for
+	// JSON Web Keys. See section 6 of the IETF draft RFC for JOSE JSON Web
+	// Algorithms.
+	MarshalJSON() ([]byte, error)
+	// These keys can also be serialized to the standard PEM encoding.
+	PEMBlock() (*pem.Block, error)
+	// The string representation of a key is its key type and ID.
+	String() string
+	AddExtendedField(string, interface{})
+	GetExtendedField(string) interface{}
+}
+
+// PrivateKey is a generic interface for a Private Key.
+type PrivateKey interface {
+	// A PrivateKey contains all fields and methods of a PublicKey of the
+	// same type. The MarshalJSON method also outputs the private key as a
+	// JSON Web Key, and the PEMBlock method outputs the private key as a
+	// PEM block.
+	PublicKey
+	// PublicKey returns the PublicKey associated with this PrivateKey.
+	PublicKey() PublicKey
+	// Sign signs the data read from the io.Reader using a signature algorithm
+	// supported by the private key. If the specified hashing algorithm is
+	// supported by this key, that hash function is used to generate the
+	// signature otherwise the the default hashing algorithm for this key is
+	// used. Returns the signature and identifier of the algorithm used.
+	Sign(data io.Reader, hashID crypto.Hash) (signature []byte, alg string, err error)
+	// CryptoPrivateKey returns the internal object which can be used as a
+	// crypto.PublicKey for use with other standard library operations. The
+	// type is either *rsa.PublicKey or *ecdsa.PublicKey
+	CryptoPrivateKey() crypto.PrivateKey
+}
+
+// FromCryptoPublicKey returns a libtrust PublicKey representation of the given
+// *ecdsa.PublicKey or *rsa.PublicKey. Returns a non-nil error when the given
+// key is of an unsupported type.
+func FromCryptoPublicKey(cryptoPublicKey crypto.PublicKey) (PublicKey, error) {
+	switch cryptoPublicKey := cryptoPublicKey.(type) {
+	case *ecdsa.PublicKey:
+		return fromECPublicKey(cryptoPublicKey)
+	case *rsa.PublicKey:
+		return fromRSAPublicKey(cryptoPublicKey), nil
+	default:
+		return nil, fmt.Errorf("public key type %T is not supported", cryptoPublicKey)
+	}
+}
+
+// FromCryptoPrivateKey returns a libtrust PrivateKey representation of the given
+// *ecdsa.PrivateKey or *rsa.PrivateKey. Returns a non-nil error when the given
+// key is of an unsupported type.
+func FromCryptoPrivateKey(cryptoPrivateKey crypto.PrivateKey) (PrivateKey, error) {
+	switch cryptoPrivateKey := cryptoPrivateKey.(type) {
+	case *ecdsa.PrivateKey:
+		return fromECPrivateKey(cryptoPrivateKey)
+	case *rsa.PrivateKey:
+		return fromRSAPrivateKey(cryptoPrivateKey), nil
+	default:
+		return nil, fmt.Errorf("private key type %T is not supported", cryptoPrivateKey)
+	}
+}
+
+// UnmarshalPublicKeyPEM parses the PEM encoded data and returns a libtrust
+// PublicKey or an error if there is a problem with the encoding.
+func UnmarshalPublicKeyPEM(data []byte) (PublicKey, error) {
+	pemBlock, _ := pem.Decode(data)
+	if pemBlock == nil {
+		return nil, errors.New("unable to find PEM encoded data")
+	} else if pemBlock.Type != "PUBLIC KEY" {
+		return nil, fmt.Errorf("unable to get PublicKey from PEM type: %s", pemBlock.Type)
+	}
+
+	return pubKeyFromPEMBlock(pemBlock)
+}
+
+// UnmarshalPublicKeyPEMBundle parses the PEM encoded data as a bundle of
+// PEM blocks appended one after the other and returns a slice of PublicKey
+// objects that it finds.
+func UnmarshalPublicKeyPEMBundle(data []byte) ([]PublicKey, error) {
+	pubKeys := []PublicKey{}
+
+	for {
+		var pemBlock *pem.Block
+		pemBlock, data = pem.Decode(data)
+		if pemBlock == nil {
+			break
+		} else if pemBlock.Type != "PUBLIC KEY" {
+			return nil, fmt.Errorf("unable to get PublicKey from PEM type: %s", pemBlock.Type)
+		}
+
+		pubKey, err := pubKeyFromPEMBlock(pemBlock)
+		if err != nil {
+			return nil, err
+		}
+
+		pubKeys = append(pubKeys, pubKey)
+	}
+
+	return pubKeys, nil
+}
+
+// UnmarshalPrivateKeyPEM parses the PEM encoded data and returns a libtrust
+// PrivateKey or an error if there is a problem with the encoding.
+func UnmarshalPrivateKeyPEM(data []byte) (PrivateKey, error) {
+	pemBlock, _ := pem.Decode(data)
+	if pemBlock == nil {
+		return nil, errors.New("unable to find PEM encoded data")
+	}
+
+	var key PrivateKey
+
+	switch {
+	case pemBlock.Type == "RSA PRIVATE KEY":
+		rsaPrivateKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
+		if err != nil {
+			return nil, fmt.Errorf("unable to decode RSA Private Key PEM data: %s", err)
+		}
+		key = fromRSAPrivateKey(rsaPrivateKey)
+	case pemBlock.Type == "EC PRIVATE KEY":
+		ecPrivateKey, err := x509.ParseECPrivateKey(pemBlock.Bytes)
+		if err != nil {
+			return nil, fmt.Errorf("unable to decode EC Private Key PEM data: %s", err)
+		}
+		key, err = fromECPrivateKey(ecPrivateKey)
+		if err != nil {
+			return nil, err
+		}
+	default:
+		return nil, fmt.Errorf("unable to get PrivateKey from PEM type: %s", pemBlock.Type)
+	}
+
+	addPEMHeadersToKey(pemBlock, key.PublicKey())
+
+	return key, nil
+}
+
+// UnmarshalPublicKeyJWK unmarshals the given JSON Web Key into a generic
+// Public Key to be used with libtrust.
+func UnmarshalPublicKeyJWK(data []byte) (PublicKey, error) {
+	jwk := make(map[string]interface{})
+
+	err := json.Unmarshal(data, &jwk)
+	if err != nil {
+		return nil, fmt.Errorf(
+			"decoding JWK Public Key JSON data: %s\n", err,
+		)
+	}
+
+	// Get the Key Type value.
+	kty, err := stringFromMap(jwk, "kty")
+	if err != nil {
+		return nil, fmt.Errorf("JWK Public Key type: %s", err)
+	}
+
+	switch {
+	case kty == "EC":
+		// Call out to unmarshal EC public key.
+		return ecPublicKeyFromMap(jwk)
+	case kty == "RSA":
+		// Call out to unmarshal RSA public key.
+		return rsaPublicKeyFromMap(jwk)
+	default:
+		return nil, fmt.Errorf(
+			"JWK Public Key type not supported: %q\n", kty,
+		)
+	}
+}
+
+// UnmarshalPublicKeyJWKSet parses the JSON encoded data as a JSON Web Key Set
+// and returns a slice of Public Key objects.
+func UnmarshalPublicKeyJWKSet(data []byte) ([]PublicKey, error) {
+	rawKeys, err := loadJSONKeySetRaw(data)
+	if err != nil {
+		return nil, err
+	}
+
+	pubKeys := make([]PublicKey, 0, len(rawKeys))
+
+	for _, rawKey := range rawKeys {
+		pubKey, err := UnmarshalPublicKeyJWK(rawKey)
+		if err != nil {
+			return nil, err
+		}
+		pubKeys = append(pubKeys, pubKey)
+	}
+
+	return pubKeys, nil
+}
+
+// UnmarshalPrivateKeyJWK unmarshals the given JSON Web Key into a generic
+// Private Key to be used with libtrust.
+func UnmarshalPrivateKeyJWK(data []byte) (PrivateKey, error) {
+	jwk := make(map[string]interface{})
+
+	err := json.Unmarshal(data, &jwk)
+	if err != nil {
+		return nil, fmt.Errorf(
+			"decoding JWK Private Key JSON data: %s\n", err,
+		)
+	}
+
+	// Get the Key Type value.
+	kty, err := stringFromMap(jwk, "kty")
+	if err != nil {
+		return nil, fmt.Errorf("JWK Private Key type: %s", err)
+	}
+
+	switch {
+	case kty == "EC":
+		// Call out to unmarshal EC private key.
+		return ecPrivateKeyFromMap(jwk)
+	case kty == "RSA":
+		// Call out to unmarshal RSA private key.
+		return rsaPrivateKeyFromMap(jwk)
+	default:
+		return nil, fmt.Errorf(
+			"JWK Private Key type not supported: %q\n", kty,
+		)
+	}
+}
diff --git a/unum/vendor/github.com/docker/libtrust/key_files.go b/unum/vendor/github.com/docker/libtrust/key_files.go
new file mode 100644
index 0000000..c526de5
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/key_files.go
@@ -0,0 +1,255 @@
+package libtrust
+
+import (
+	"encoding/json"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"strings"
+)
+
+var (
+	// ErrKeyFileDoesNotExist indicates that the private key file does not exist.
+	ErrKeyFileDoesNotExist = errors.New("key file does not exist")
+)
+
+func readKeyFileBytes(filename string) ([]byte, error) {
+	data, err := ioutil.ReadFile(filename)
+	if err != nil {
+		if os.IsNotExist(err) {
+			err = ErrKeyFileDoesNotExist
+		} else {
+			err = fmt.Errorf("unable to read key file %s: %s", filename, err)
+		}
+
+		return nil, err
+	}
+
+	return data, nil
+}
+
+/*
+	Loading and Saving of Public and Private Keys in either PEM or JWK format.
+*/
+
+// LoadKeyFile opens the given filename and attempts to read a Private Key
+// encoded in either PEM or JWK format (if .json or .jwk file extension).
+func LoadKeyFile(filename string) (PrivateKey, error) {
+	contents, err := readKeyFileBytes(filename)
+	if err != nil {
+		return nil, err
+	}
+
+	var key PrivateKey
+
+	if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") {
+		key, err = UnmarshalPrivateKeyJWK(contents)
+		if err != nil {
+			return nil, fmt.Errorf("unable to decode private key JWK: %s", err)
+		}
+	} else {
+		key, err = UnmarshalPrivateKeyPEM(contents)
+		if err != nil {
+			return nil, fmt.Errorf("unable to decode private key PEM: %s", err)
+		}
+	}
+
+	return key, nil
+}
+
+// LoadPublicKeyFile opens the given filename and attempts to read a Public Key
+// encoded in either PEM or JWK format (if .json or .jwk file extension).
+func LoadPublicKeyFile(filename string) (PublicKey, error) {
+	contents, err := readKeyFileBytes(filename)
+	if err != nil {
+		return nil, err
+	}
+
+	var key PublicKey
+
+	if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") {
+		key, err = UnmarshalPublicKeyJWK(contents)
+		if err != nil {
+			return nil, fmt.Errorf("unable to decode public key JWK: %s", err)
+		}
+	} else {
+		key, err = UnmarshalPublicKeyPEM(contents)
+		if err != nil {
+			return nil, fmt.Errorf("unable to decode public key PEM: %s", err)
+		}
+	}
+
+	return key, nil
+}
+
+// SaveKey saves the given key to a file using the provided filename.
+// This process will overwrite any existing file at the provided location.
+func SaveKey(filename string, key PrivateKey) error {
+	var encodedKey []byte
+	var err error
+
+	if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") {
+		// Encode in JSON Web Key format.
+		encodedKey, err = json.MarshalIndent(key, "", "    ")
+		if err != nil {
+			return fmt.Errorf("unable to encode private key JWK: %s", err)
+		}
+	} else {
+		// Encode in PEM format.
+		pemBlock, err := key.PEMBlock()
+		if err != nil {
+			return fmt.Errorf("unable to encode private key PEM: %s", err)
+		}
+		encodedKey = pem.EncodeToMemory(pemBlock)
+	}
+
+	err = ioutil.WriteFile(filename, encodedKey, os.FileMode(0600))
+	if err != nil {
+		return fmt.Errorf("unable to write private key file %s: %s", filename, err)
+	}
+
+	return nil
+}
+
+// SavePublicKey saves the given public key to the file.
+func SavePublicKey(filename string, key PublicKey) error {
+	var encodedKey []byte
+	var err error
+
+	if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") {
+		// Encode in JSON Web Key format.
+		encodedKey, err = json.MarshalIndent(key, "", "    ")
+		if err != nil {
+			return fmt.Errorf("unable to encode public key JWK: %s", err)
+		}
+	} else {
+		// Encode in PEM format.
+		pemBlock, err := key.PEMBlock()
+		if err != nil {
+			return fmt.Errorf("unable to encode public key PEM: %s", err)
+		}
+		encodedKey = pem.EncodeToMemory(pemBlock)
+	}
+
+	err = ioutil.WriteFile(filename, encodedKey, os.FileMode(0644))
+	if err != nil {
+		return fmt.Errorf("unable to write public key file %s: %s", filename, err)
+	}
+
+	return nil
+}
+
+// Public Key Set files
+
+type jwkSet struct {
+	Keys []json.RawMessage `json:"keys"`
+}
+
+// LoadKeySetFile loads a key set
+func LoadKeySetFile(filename string) ([]PublicKey, error) {
+	if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") {
+		return loadJSONKeySetFile(filename)
+	}
+
+	// Must be a PEM format file
+	return loadPEMKeySetFile(filename)
+}
+
+func loadJSONKeySetRaw(data []byte) ([]json.RawMessage, error) {
+	if len(data) == 0 {
+		// This is okay, just return an empty slice.
+		return []json.RawMessage{}, nil
+	}
+
+	keySet := jwkSet{}
+
+	err := json.Unmarshal(data, &keySet)
+	if err != nil {
+		return nil, fmt.Errorf("unable to decode JSON Web Key Set: %s", err)
+	}
+
+	return keySet.Keys, nil
+}
+
+func loadJSONKeySetFile(filename string) ([]PublicKey, error) {
+	contents, err := readKeyFileBytes(filename)
+	if err != nil && err != ErrKeyFileDoesNotExist {
+		return nil, err
+	}
+
+	return UnmarshalPublicKeyJWKSet(contents)
+}
+
+func loadPEMKeySetFile(filename string) ([]PublicKey, error) {
+	data, err := readKeyFileBytes(filename)
+	if err != nil && err != ErrKeyFileDoesNotExist {
+		return nil, err
+	}
+
+	return UnmarshalPublicKeyPEMBundle(data)
+}
+
+// AddKeySetFile adds a key to a key set
+func AddKeySetFile(filename string, key PublicKey) error {
+	if strings.HasSuffix(filename, ".json") || strings.HasSuffix(filename, ".jwk") {
+		return addKeySetJSONFile(filename, key)
+	}
+
+	// Must be a PEM format file
+	return addKeySetPEMFile(filename, key)
+}
+
+func addKeySetJSONFile(filename string, key PublicKey) error {
+	encodedKey, err := json.Marshal(key)
+	if err != nil {
+		return fmt.Errorf("unable to encode trusted client key: %s", err)
+	}
+
+	contents, err := readKeyFileBytes(filename)
+	if err != nil && err != ErrKeyFileDoesNotExist {
+		return err
+	}
+
+	rawEntries, err := loadJSONKeySetRaw(contents)
+	if err != nil {
+		return err
+	}
+
+	rawEntries = append(rawEntries, json.RawMessage(encodedKey))
+	entriesWrapper := jwkSet{Keys: rawEntries}
+
+	encodedEntries, err := json.MarshalIndent(entriesWrapper, "", "    ")
+	if err != nil {
+		return fmt.Errorf("unable to encode trusted client keys: %s", err)
+	}
+
+	err = ioutil.WriteFile(filename, encodedEntries, os.FileMode(0644))
+	if err != nil {
+		return fmt.Errorf("unable to write trusted client keys file %s: %s", filename, err)
+	}
+
+	return nil
+}
+
+func addKeySetPEMFile(filename string, key PublicKey) error {
+	// Encode to PEM, open file for appending, write PEM.
+	file, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, os.FileMode(0644))
+	if err != nil {
+		return fmt.Errorf("unable to open trusted client keys file %s: %s", filename, err)
+	}
+	defer file.Close()
+
+	pemBlock, err := key.PEMBlock()
+	if err != nil {
+		return fmt.Errorf("unable to encoded trusted key: %s", err)
+	}
+
+	_, err = file.Write(pem.EncodeToMemory(pemBlock))
+	if err != nil {
+		return fmt.Errorf("unable to write trusted keys file: %s", err)
+	}
+
+	return nil
+}
diff --git a/unum/vendor/github.com/docker/libtrust/key_manager.go b/unum/vendor/github.com/docker/libtrust/key_manager.go
new file mode 100644
index 0000000..9a98ae3
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/key_manager.go
@@ -0,0 +1,175 @@
+package libtrust
+
+import (
+	"crypto/tls"
+	"crypto/x509"
+	"fmt"
+	"io/ioutil"
+	"net"
+	"os"
+	"path"
+	"sync"
+)
+
+// ClientKeyManager manages client keys on the filesystem
+type ClientKeyManager struct {
+	key        PrivateKey
+	clientFile string
+	clientDir  string
+
+	clientLock sync.RWMutex
+	clients    []PublicKey
+
+	configLock sync.Mutex
+	configs    []*tls.Config
+}
+
+// NewClientKeyManager loads a new manager from a set of key files
+// and managed by the given private key.
+func NewClientKeyManager(trustKey PrivateKey, clientFile, clientDir string) (*ClientKeyManager, error) {
+	m := &ClientKeyManager{
+		key:        trustKey,
+		clientFile: clientFile,
+		clientDir:  clientDir,
+	}
+	if err := m.loadKeys(); err != nil {
+		return nil, err
+	}
+	// TODO Start watching file and directory
+
+	return m, nil
+}
+
+func (c *ClientKeyManager) loadKeys() (err error) {
+	// Load authorized keys file
+	var clients []PublicKey
+	if c.clientFile != "" {
+		clients, err = LoadKeySetFile(c.clientFile)
+		if err != nil {
+			return fmt.Errorf("unable to load authorized keys: %s", err)
+		}
+	}
+
+	// Add clients from authorized keys directory
+	files, err := ioutil.ReadDir(c.clientDir)
+	if err != nil && !os.IsNotExist(err) {
+		return fmt.Errorf("unable to open authorized keys directory: %s", err)
+	}
+	for _, f := range files {
+		if !f.IsDir() {
+			publicKey, err := LoadPublicKeyFile(path.Join(c.clientDir, f.Name()))
+			if err != nil {
+				return fmt.Errorf("unable to load authorized key file: %s", err)
+			}
+			clients = append(clients, publicKey)
+		}
+	}
+
+	c.clientLock.Lock()
+	c.clients = clients
+	c.clientLock.Unlock()
+
+	return nil
+}
+
+// RegisterTLSConfig registers a tls configuration to manager
+// such that any changes to the keys may be reflected in
+// the tls client CA pool
+func (c *ClientKeyManager) RegisterTLSConfig(tlsConfig *tls.Config) error {
+	c.clientLock.RLock()
+	certPool, err := GenerateCACertPool(c.key, c.clients)
+	if err != nil {
+		return fmt.Errorf("CA pool generation error: %s", err)
+	}
+	c.clientLock.RUnlock()
+
+	tlsConfig.ClientCAs = certPool
+
+	c.configLock.Lock()
+	c.configs = append(c.configs, tlsConfig)
+	c.configLock.Unlock()
+
+	return nil
+}
+
+// NewIdentityAuthTLSConfig creates a tls.Config for the server to use for
+// libtrust identity authentication for the domain specified
+func NewIdentityAuthTLSConfig(trustKey PrivateKey, clients *ClientKeyManager, addr string, domain string) (*tls.Config, error) {
+	tlsConfig := newTLSConfig()
+
+	tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
+	if err := clients.RegisterTLSConfig(tlsConfig); err != nil {
+		return nil, err
+	}
+
+	// Generate cert
+	ips, domains, err := parseAddr(addr)
+	if err != nil {
+		return nil, err
+	}
+	// add domain that it expects clients to use
+	domains = append(domains, domain)
+	x509Cert, err := GenerateSelfSignedServerCert(trustKey, domains, ips)
+	if err != nil {
+		return nil, fmt.Errorf("certificate generation error: %s", err)
+	}
+	tlsConfig.Certificates = []tls.Certificate{{
+		Certificate: [][]byte{x509Cert.Raw},
+		PrivateKey:  trustKey.CryptoPrivateKey(),
+		Leaf:        x509Cert,
+	}}
+
+	return tlsConfig, nil
+}
+
+// NewCertAuthTLSConfig creates a tls.Config for the server to use for
+// certificate authentication
+func NewCertAuthTLSConfig(caPath, certPath, keyPath string) (*tls.Config, error) {
+	tlsConfig := newTLSConfig()
+
+	cert, err := tls.LoadX509KeyPair(certPath, keyPath)
+	if err != nil {
+		return nil, fmt.Errorf("Couldn't load X509 key pair (%s, %s): %s. Key encrypted?", certPath, keyPath, err)
+	}
+	tlsConfig.Certificates = []tls.Certificate{cert}
+
+	// Verify client certificates against a CA?
+	if caPath != "" {
+		certPool := x509.NewCertPool()
+		file, err := ioutil.ReadFile(caPath)
+		if err != nil {
+			return nil, fmt.Errorf("Couldn't read CA certificate: %s", err)
+		}
+		certPool.AppendCertsFromPEM(file)
+
+		tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
+		tlsConfig.ClientCAs = certPool
+	}
+
+	return tlsConfig, nil
+}
+
+func newTLSConfig() *tls.Config {
+	return &tls.Config{
+		NextProtos: []string{"http/1.1"},
+		// Avoid fallback on insecure SSL protocols
+		MinVersion: tls.VersionTLS10,
+	}
+}
+
+// parseAddr parses an address into an array of IPs and domains
+func parseAddr(addr string) ([]net.IP, []string, error) {
+	host, _, err := net.SplitHostPort(addr)
+	if err != nil {
+		return nil, nil, err
+	}
+	var domains []string
+	var ips []net.IP
+	ip := net.ParseIP(host)
+	if ip != nil {
+		ips = []net.IP{ip}
+	} else {
+		domains = []string{host}
+	}
+	return ips, domains, nil
+}
diff --git a/unum/vendor/github.com/docker/libtrust/rsa_key.go b/unum/vendor/github.com/docker/libtrust/rsa_key.go
new file mode 100644
index 0000000..dac4cac
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/rsa_key.go
@@ -0,0 +1,427 @@
+package libtrust
+
+import (
+	"crypto"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/x509"
+	"encoding/json"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"io"
+	"math/big"
+)
+
+/*
+ * RSA DSA PUBLIC KEY
+ */
+
+// rsaPublicKey implements a JWK Public Key using RSA digital signature algorithms.
+type rsaPublicKey struct {
+	*rsa.PublicKey
+	extended map[string]interface{}
+}
+
+func fromRSAPublicKey(cryptoPublicKey *rsa.PublicKey) *rsaPublicKey {
+	return &rsaPublicKey{cryptoPublicKey, map[string]interface{}{}}
+}
+
+// KeyType returns the JWK key type for RSA keys, i.e., "RSA".
+func (k *rsaPublicKey) KeyType() string {
+	return "RSA"
+}
+
+// KeyID returns a distinct identifier which is unique to this Public Key.
+func (k *rsaPublicKey) KeyID() string {
+	return keyIDFromCryptoKey(k)
+}
+
+func (k *rsaPublicKey) String() string {
+	return fmt.Sprintf("RSA Public Key <%s>", k.KeyID())
+}
+
+// Verify verifyies the signature of the data in the io.Reader using this Public Key.
+// The alg parameter should be the name of the JWA digital signature algorithm
+// which was used to produce the signature and should be supported by this
+// public key. Returns a nil error if the signature is valid.
+func (k *rsaPublicKey) Verify(data io.Reader, alg string, signature []byte) error {
+	// Verify the signature of the given date, return non-nil error if valid.
+	sigAlg, err := rsaSignatureAlgorithmByName(alg)
+	if err != nil {
+		return fmt.Errorf("unable to verify Signature: %s", err)
+	}
+
+	hasher := sigAlg.HashID().New()
+	_, err = io.Copy(hasher, data)
+	if err != nil {
+		return fmt.Errorf("error reading data to sign: %s", err)
+	}
+	hash := hasher.Sum(nil)
+
+	err = rsa.VerifyPKCS1v15(k.PublicKey, sigAlg.HashID(), hash, signature)
+	if err != nil {
+		return fmt.Errorf("invalid %s signature: %s", sigAlg.HeaderParam(), err)
+	}
+
+	return nil
+}
+
+// CryptoPublicKey returns the internal object which can be used as a
+// crypto.PublicKey for use with other standard library operations. The type
+// is either *rsa.PublicKey or *ecdsa.PublicKey
+func (k *rsaPublicKey) CryptoPublicKey() crypto.PublicKey {
+	return k.PublicKey
+}
+
+func (k *rsaPublicKey) toMap() map[string]interface{} {
+	jwk := make(map[string]interface{})
+	for k, v := range k.extended {
+		jwk[k] = v
+	}
+	jwk["kty"] = k.KeyType()
+	jwk["kid"] = k.KeyID()
+	jwk["n"] = joseBase64UrlEncode(k.N.Bytes())
+	jwk["e"] = joseBase64UrlEncode(serializeRSAPublicExponentParam(k.E))
+
+	return jwk
+}
+
+// MarshalJSON serializes this Public Key using the JWK JSON serialization format for
+// RSA keys.
+func (k *rsaPublicKey) MarshalJSON() (data []byte, err error) {
+	return json.Marshal(k.toMap())
+}
+
+// PEMBlock serializes this Public Key to DER-encoded PKIX format.
+func (k *rsaPublicKey) PEMBlock() (*pem.Block, error) {
+	derBytes, err := x509.MarshalPKIXPublicKey(k.PublicKey)
+	if err != nil {
+		return nil, fmt.Errorf("unable to serialize RSA PublicKey to DER-encoded PKIX format: %s", err)
+	}
+	k.extended["kid"] = k.KeyID() // For display purposes.
+	return createPemBlock("PUBLIC KEY", derBytes, k.extended)
+}
+
+func (k *rsaPublicKey) AddExtendedField(field string, value interface{}) {
+	k.extended[field] = value
+}
+
+func (k *rsaPublicKey) GetExtendedField(field string) interface{} {
+	v, ok := k.extended[field]
+	if !ok {
+		return nil
+	}
+	return v
+}
+
+func rsaPublicKeyFromMap(jwk map[string]interface{}) (*rsaPublicKey, error) {
+	// JWK key type (kty) has already been determined to be "RSA".
+	// Need to extract 'n', 'e', and 'kid' and check for
+	// consistency.
+
+	// Get the modulus parameter N.
+	nB64Url, err := stringFromMap(jwk, "n")
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Public Key modulus: %s", err)
+	}
+
+	n, err := parseRSAModulusParam(nB64Url)
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Public Key modulus: %s", err)
+	}
+
+	// Get the public exponent E.
+	eB64Url, err := stringFromMap(jwk, "e")
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Public Key exponent: %s", err)
+	}
+
+	e, err := parseRSAPublicExponentParam(eB64Url)
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Public Key exponent: %s", err)
+	}
+
+	key := &rsaPublicKey{
+		PublicKey: &rsa.PublicKey{N: n, E: e},
+	}
+
+	// Key ID is optional, but if it exists, it should match the key.
+	_, ok := jwk["kid"]
+	if ok {
+		kid, err := stringFromMap(jwk, "kid")
+		if err != nil {
+			return nil, fmt.Errorf("JWK RSA Public Key ID: %s", err)
+		}
+		if kid != key.KeyID() {
+			return nil, fmt.Errorf("JWK RSA Public Key ID does not match: %s", kid)
+		}
+	}
+
+	if _, ok := jwk["d"]; ok {
+		return nil, fmt.Errorf("JWK RSA Public Key cannot contain private exponent")
+	}
+
+	key.extended = jwk
+
+	return key, nil
+}
+
+/*
+ * RSA DSA PRIVATE KEY
+ */
+
+// rsaPrivateKey implements a JWK Private Key using RSA digital signature algorithms.
+type rsaPrivateKey struct {
+	rsaPublicKey
+	*rsa.PrivateKey
+}
+
+func fromRSAPrivateKey(cryptoPrivateKey *rsa.PrivateKey) *rsaPrivateKey {
+	return &rsaPrivateKey{
+		*fromRSAPublicKey(&cryptoPrivateKey.PublicKey),
+		cryptoPrivateKey,
+	}
+}
+
+// PublicKey returns the Public Key data associated with this Private Key.
+func (k *rsaPrivateKey) PublicKey() PublicKey {
+	return &k.rsaPublicKey
+}
+
+func (k *rsaPrivateKey) String() string {
+	return fmt.Sprintf("RSA Private Key <%s>", k.KeyID())
+}
+
+// Sign signs the data read from the io.Reader using a signature algorithm supported
+// by the RSA private key. If the specified hashing algorithm is supported by
+// this key, that hash function is used to generate the signature otherwise the
+// the default hashing algorithm for this key is used. Returns the signature
+// and the name of the JWK signature algorithm used, e.g., "RS256", "RS384",
+// "RS512".
+func (k *rsaPrivateKey) Sign(data io.Reader, hashID crypto.Hash) (signature []byte, alg string, err error) {
+	// Generate a signature of the data using the internal alg.
+	sigAlg := rsaPKCS1v15SignatureAlgorithmForHashID(hashID)
+	hasher := sigAlg.HashID().New()
+
+	_, err = io.Copy(hasher, data)
+	if err != nil {
+		return nil, "", fmt.Errorf("error reading data to sign: %s", err)
+	}
+	hash := hasher.Sum(nil)
+
+	signature, err = rsa.SignPKCS1v15(rand.Reader, k.PrivateKey, sigAlg.HashID(), hash)
+	if err != nil {
+		return nil, "", fmt.Errorf("error producing signature: %s", err)
+	}
+
+	alg = sigAlg.HeaderParam()
+
+	return
+}
+
+// CryptoPrivateKey returns the internal object which can be used as a
+// crypto.PublicKey for use with other standard library operations. The type
+// is either *rsa.PublicKey or *ecdsa.PublicKey
+func (k *rsaPrivateKey) CryptoPrivateKey() crypto.PrivateKey {
+	return k.PrivateKey
+}
+
+func (k *rsaPrivateKey) toMap() map[string]interface{} {
+	k.Precompute() // Make sure the precomputed values are stored.
+	jwk := k.rsaPublicKey.toMap()
+
+	jwk["d"] = joseBase64UrlEncode(k.D.Bytes())
+	jwk["p"] = joseBase64UrlEncode(k.Primes[0].Bytes())
+	jwk["q"] = joseBase64UrlEncode(k.Primes[1].Bytes())
+	jwk["dp"] = joseBase64UrlEncode(k.Precomputed.Dp.Bytes())
+	jwk["dq"] = joseBase64UrlEncode(k.Precomputed.Dq.Bytes())
+	jwk["qi"] = joseBase64UrlEncode(k.Precomputed.Qinv.Bytes())
+
+	otherPrimes := k.Primes[2:]
+
+	if len(otherPrimes) > 0 {
+		otherPrimesInfo := make([]interface{}, len(otherPrimes))
+		for i, r := range otherPrimes {
+			otherPrimeInfo := make(map[string]string, 3)
+			otherPrimeInfo["r"] = joseBase64UrlEncode(r.Bytes())
+			crtVal := k.Precomputed.CRTValues[i]
+			otherPrimeInfo["d"] = joseBase64UrlEncode(crtVal.Exp.Bytes())
+			otherPrimeInfo["t"] = joseBase64UrlEncode(crtVal.Coeff.Bytes())
+			otherPrimesInfo[i] = otherPrimeInfo
+		}
+		jwk["oth"] = otherPrimesInfo
+	}
+
+	return jwk
+}
+
+// MarshalJSON serializes this Private Key using the JWK JSON serialization format for
+// RSA keys.
+func (k *rsaPrivateKey) MarshalJSON() (data []byte, err error) {
+	return json.Marshal(k.toMap())
+}
+
+// PEMBlock serializes this Private Key to DER-encoded PKIX format.
+func (k *rsaPrivateKey) PEMBlock() (*pem.Block, error) {
+	derBytes := x509.MarshalPKCS1PrivateKey(k.PrivateKey)
+	k.extended["keyID"] = k.KeyID() // For display purposes.
+	return createPemBlock("RSA PRIVATE KEY", derBytes, k.extended)
+}
+
+func rsaPrivateKeyFromMap(jwk map[string]interface{}) (*rsaPrivateKey, error) {
+	// The JWA spec for RSA Private Keys (draft rfc section 5.3.2) states that
+	// only the private key exponent 'd' is REQUIRED, the others are just for
+	// signature/decryption optimizations and SHOULD be included when the JWK
+	// is produced. We MAY choose to accept a JWK which only includes 'd', but
+	// we're going to go ahead and not choose to accept it without the extra
+	// fields. Only the 'oth' field will be optional (for multi-prime keys).
+	privateExponent, err := parseRSAPrivateKeyParamFromMap(jwk, "d")
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Private Key exponent: %s", err)
+	}
+	firstPrimeFactor, err := parseRSAPrivateKeyParamFromMap(jwk, "p")
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Private Key prime factor: %s", err)
+	}
+	secondPrimeFactor, err := parseRSAPrivateKeyParamFromMap(jwk, "q")
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Private Key prime factor: %s", err)
+	}
+	firstFactorCRT, err := parseRSAPrivateKeyParamFromMap(jwk, "dp")
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Private Key CRT exponent: %s", err)
+	}
+	secondFactorCRT, err := parseRSAPrivateKeyParamFromMap(jwk, "dq")
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Private Key CRT exponent: %s", err)
+	}
+	crtCoeff, err := parseRSAPrivateKeyParamFromMap(jwk, "qi")
+	if err != nil {
+		return nil, fmt.Errorf("JWK RSA Private Key CRT coefficient: %s", err)
+	}
+
+	var oth interface{}
+	if _, ok := jwk["oth"]; ok {
+		oth = jwk["oth"]
+		delete(jwk, "oth")
+	}
+
+	// JWK key type (kty) has already been determined to be "RSA".
+	// Need to extract the public key information, then extract the private
+	// key values.
+	publicKey, err := rsaPublicKeyFromMap(jwk)
+	if err != nil {
+		return nil, err
+	}
+
+	privateKey := &rsa.PrivateKey{
+		PublicKey: *publicKey.PublicKey,
+		D:         privateExponent,
+		Primes:    []*big.Int{firstPrimeFactor, secondPrimeFactor},
+		Precomputed: rsa.PrecomputedValues{
+			Dp:   firstFactorCRT,
+			Dq:   secondFactorCRT,
+			Qinv: crtCoeff,
+		},
+	}
+
+	if oth != nil {
+		// Should be an array of more JSON objects.
+		otherPrimesInfo, ok := oth.([]interface{})
+		if !ok {
+			return nil, errors.New("JWK RSA Private Key: Invalid other primes info: must be an array")
+		}
+		numOtherPrimeFactors := len(otherPrimesInfo)
+		if numOtherPrimeFactors == 0 {
+			return nil, errors.New("JWK RSA Privake Key: Invalid other primes info: must be absent or non-empty")
+		}
+		otherPrimeFactors := make([]*big.Int, numOtherPrimeFactors)
+		productOfPrimes := new(big.Int).Mul(firstPrimeFactor, secondPrimeFactor)
+		crtValues := make([]rsa.CRTValue, numOtherPrimeFactors)
+
+		for i, val := range otherPrimesInfo {
+			otherPrimeinfo, ok := val.(map[string]interface{})
+			if !ok {
+				return nil, errors.New("JWK RSA Private Key: Invalid other prime info: must be a JSON object")
+			}
+
+			otherPrimeFactor, err := parseRSAPrivateKeyParamFromMap(otherPrimeinfo, "r")
+			if err != nil {
+				return nil, fmt.Errorf("JWK RSA Private Key prime factor: %s", err)
+			}
+			otherFactorCRT, err := parseRSAPrivateKeyParamFromMap(otherPrimeinfo, "d")
+			if err != nil {
+				return nil, fmt.Errorf("JWK RSA Private Key CRT exponent: %s", err)
+			}
+			otherCrtCoeff, err := parseRSAPrivateKeyParamFromMap(otherPrimeinfo, "t")
+			if err != nil {
+				return nil, fmt.Errorf("JWK RSA Private Key CRT coefficient: %s", err)
+			}
+
+			crtValue := crtValues[i]
+			crtValue.Exp = otherFactorCRT
+			crtValue.Coeff = otherCrtCoeff
+			crtValue.R = productOfPrimes
+			otherPrimeFactors[i] = otherPrimeFactor
+			productOfPrimes = new(big.Int).Mul(productOfPrimes, otherPrimeFactor)
+		}
+
+		privateKey.Primes = append(privateKey.Primes, otherPrimeFactors...)
+		privateKey.Precomputed.CRTValues = crtValues
+	}
+
+	key := &rsaPrivateKey{
+		rsaPublicKey: *publicKey,
+		PrivateKey:   privateKey,
+	}
+
+	return key, nil
+}
+
+/*
+ *	Key Generation Functions.
+ */
+
+func generateRSAPrivateKey(bits int) (k *rsaPrivateKey, err error) {
+	k = new(rsaPrivateKey)
+	k.PrivateKey, err = rsa.GenerateKey(rand.Reader, bits)
+	if err != nil {
+		return nil, err
+	}
+
+	k.rsaPublicKey.PublicKey = &k.PrivateKey.PublicKey
+	k.extended = make(map[string]interface{})
+
+	return
+}
+
+// GenerateRSA2048PrivateKey generates a key pair using 2048-bit RSA.
+func GenerateRSA2048PrivateKey() (PrivateKey, error) {
+	k, err := generateRSAPrivateKey(2048)
+	if err != nil {
+		return nil, fmt.Errorf("error generating RSA 2048-bit key: %s", err)
+	}
+
+	return k, nil
+}
+
+// GenerateRSA3072PrivateKey generates a key pair using 3072-bit RSA.
+func GenerateRSA3072PrivateKey() (PrivateKey, error) {
+	k, err := generateRSAPrivateKey(3072)
+	if err != nil {
+		return nil, fmt.Errorf("error generating RSA 3072-bit key: %s", err)
+	}
+
+	return k, nil
+}
+
+// GenerateRSA4096PrivateKey generates a key pair using 4096-bit RSA.
+func GenerateRSA4096PrivateKey() (PrivateKey, error) {
+	k, err := generateRSAPrivateKey(4096)
+	if err != nil {
+		return nil, fmt.Errorf("error generating RSA 4096-bit key: %s", err)
+	}
+
+	return k, nil
+}
diff --git a/unum/vendor/github.com/docker/libtrust/util.go b/unum/vendor/github.com/docker/libtrust/util.go
new file mode 100644
index 0000000..d88176c
--- /dev/null
+++ b/unum/vendor/github.com/docker/libtrust/util.go
@@ -0,0 +1,363 @@
+package libtrust
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/elliptic"
+	"crypto/tls"
+	"crypto/x509"
+	"encoding/base32"
+	"encoding/base64"
+	"encoding/binary"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"math/big"
+	"net/url"
+	"os"
+	"path/filepath"
+	"strings"
+	"time"
+)
+
+// LoadOrCreateTrustKey will load a PrivateKey from the specified path
+func LoadOrCreateTrustKey(trustKeyPath string) (PrivateKey, error) {
+	if err := os.MkdirAll(filepath.Dir(trustKeyPath), 0700); err != nil {
+		return nil, err
+	}
+
+	trustKey, err := LoadKeyFile(trustKeyPath)
+	if err == ErrKeyFileDoesNotExist {
+		trustKey, err = GenerateECP256PrivateKey()
+		if err != nil {
+			return nil, fmt.Errorf("error generating key: %s", err)
+		}
+
+		if err := SaveKey(trustKeyPath, trustKey); err != nil {
+			return nil, fmt.Errorf("error saving key file: %s", err)
+		}
+
+		dir, file := filepath.Split(trustKeyPath)
+		if err := SavePublicKey(filepath.Join(dir, "public-"+file), trustKey.PublicKey()); err != nil {
+			return nil, fmt.Errorf("error saving public key file: %s", err)
+		}
+	} else if err != nil {
+		return nil, fmt.Errorf("error loading key file: %s", err)
+	}
+	return trustKey, nil
+}
+
+// NewIdentityAuthTLSClientConfig returns a tls.Config configured to use identity
+// based authentication from the specified dockerUrl, the rootConfigPath and
+// the server name to which it is connecting.
+// If trustUnknownHosts is true it will automatically add the host to the
+// known-hosts.json in rootConfigPath.
+func NewIdentityAuthTLSClientConfig(dockerUrl string, trustUnknownHosts bool, rootConfigPath string, serverName string) (*tls.Config, error) {
+	tlsConfig := newTLSConfig()
+
+	trustKeyPath := filepath.Join(rootConfigPath, "key.json")
+	knownHostsPath := filepath.Join(rootConfigPath, "known-hosts.json")
+
+	u, err := url.Parse(dockerUrl)
+	if err != nil {
+		return nil, fmt.Errorf("unable to parse machine url")
+	}
+
+	if u.Scheme == "unix" {
+		return nil, nil
+	}
+
+	addr := u.Host
+	proto := "tcp"
+
+	trustKey, err := LoadOrCreateTrustKey(trustKeyPath)
+	if err != nil {
+		return nil, fmt.Errorf("unable to load trust key: %s", err)
+	}
+
+	knownHosts, err := LoadKeySetFile(knownHostsPath)
+	if err != nil {
+		return nil, fmt.Errorf("could not load trusted hosts file: %s", err)
+	}
+
+	allowedHosts, err := FilterByHosts(knownHosts, addr, false)
+	if err != nil {
+		return nil, fmt.Errorf("error filtering hosts: %s", err)
+	}
+
+	certPool, err := GenerateCACertPool(trustKey, allowedHosts)
+	if err != nil {
+		return nil, fmt.Errorf("Could not create CA pool: %s", err)
+	}
+
+	tlsConfig.ServerName = serverName
+	tlsConfig.RootCAs = certPool
+
+	x509Cert, err := GenerateSelfSignedClientCert(trustKey)
+	if err != nil {
+		return nil, fmt.Errorf("certificate generation error: %s", err)
+	}
+
+	tlsConfig.Certificates = []tls.Certificate{{
+		Certificate: [][]byte{x509Cert.Raw},
+		PrivateKey:  trustKey.CryptoPrivateKey(),
+		Leaf:        x509Cert,
+	}}
+
+	tlsConfig.InsecureSkipVerify = true
+
+	testConn, err := tls.Dial(proto, addr, tlsConfig)
+	if err != nil {
+		return nil, fmt.Errorf("tls Handshake error: %s", err)
+	}
+
+	opts := x509.VerifyOptions{
+		Roots:         tlsConfig.RootCAs,
+		CurrentTime:   time.Now(),
+		DNSName:       tlsConfig.ServerName,
+		Intermediates: x509.NewCertPool(),
+	}
+
+	certs := testConn.ConnectionState().PeerCertificates
+	for i, cert := range certs {
+		if i == 0 {
+			continue
+		}
+		opts.Intermediates.AddCert(cert)
+	}
+
+	if _, err := certs[0].Verify(opts); err != nil {
+		if _, ok := err.(x509.UnknownAuthorityError); ok {
+			if trustUnknownHosts {
+				pubKey, err := FromCryptoPublicKey(certs[0].PublicKey)
+				if err != nil {
+					return nil, fmt.Errorf("error extracting public key from cert: %s", err)
+				}
+
+				pubKey.AddExtendedField("hosts", []string{addr})
+
+				if err := AddKeySetFile(knownHostsPath, pubKey); err != nil {
+					return nil, fmt.Errorf("error adding machine to known hosts: %s", err)
+				}
+			} else {
+				return nil, fmt.Errorf("unable to connect.  unknown host: %s", addr)
+			}
+		}
+	}
+
+	testConn.Close()
+	tlsConfig.InsecureSkipVerify = false
+
+	return tlsConfig, nil
+}
+
+// joseBase64UrlEncode encodes the given data using the standard base64 url
+// encoding format but with all trailing '=' characters ommitted in accordance
+// with the jose specification.
+// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-2
+func joseBase64UrlEncode(b []byte) string {
+	return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
+}
+
+// joseBase64UrlDecode decodes the given string using the standard base64 url
+// decoder but first adds the appropriate number of trailing '=' characters in
+// accordance with the jose specification.
+// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-2
+func joseBase64UrlDecode(s string) ([]byte, error) {
+	s = strings.Replace(s, "\n", "", -1)
+	s = strings.Replace(s, " ", "", -1)
+	switch len(s) % 4 {
+	case 0:
+	case 2:
+		s += "=="
+	case 3:
+		s += "="
+	default:
+		return nil, errors.New("illegal base64url string")
+	}
+	return base64.URLEncoding.DecodeString(s)
+}
+
+func keyIDEncode(b []byte) string {
+	s := strings.TrimRight(base32.StdEncoding.EncodeToString(b), "=")
+	var buf bytes.Buffer
+	var i int
+	for i = 0; i < len(s)/4-1; i++ {
+		start := i * 4
+		end := start + 4
+		buf.WriteString(s[start:end] + ":")
+	}
+	buf.WriteString(s[i*4:])
+	return buf.String()
+}
+
+func keyIDFromCryptoKey(pubKey PublicKey) string {
+	// Generate and return a 'libtrust' fingerprint of the public key.
+	// For an RSA key this should be:
+	//   SHA256(DER encoded ASN1)
+	// Then truncated to 240 bits and encoded into 12 base32 groups like so:
+	//   ABCD:EFGH:IJKL:MNOP:QRST:UVWX:YZ23:4567:ABCD:EFGH:IJKL:MNOP
+	derBytes, err := x509.MarshalPKIXPublicKey(pubKey.CryptoPublicKey())
+	if err != nil {
+		return ""
+	}
+	hasher := crypto.SHA256.New()
+	hasher.Write(derBytes)
+	return keyIDEncode(hasher.Sum(nil)[:30])
+}
+
+func stringFromMap(m map[string]interface{}, key string) (string, error) {
+	val, ok := m[key]
+	if !ok {
+		return "", fmt.Errorf("%q value not specified", key)
+	}
+
+	str, ok := val.(string)
+	if !ok {
+		return "", fmt.Errorf("%q value must be a string", key)
+	}
+	delete(m, key)
+
+	return str, nil
+}
+
+func parseECCoordinate(cB64Url string, curve elliptic.Curve) (*big.Int, error) {
+	curveByteLen := (curve.Params().BitSize + 7) >> 3
+
+	cBytes, err := joseBase64UrlDecode(cB64Url)
+	if err != nil {
+		return nil, fmt.Errorf("invalid base64 URL encoding: %s", err)
+	}
+	cByteLength := len(cBytes)
+	if cByteLength != curveByteLen {
+		return nil, fmt.Errorf("invalid number of octets: got %d, should be %d", cByteLength, curveByteLen)
+	}
+	return new(big.Int).SetBytes(cBytes), nil
+}
+
+func parseECPrivateParam(dB64Url string, curve elliptic.Curve) (*big.Int, error) {
+	dBytes, err := joseBase64UrlDecode(dB64Url)
+	if err != nil {
+		return nil, fmt.Errorf("invalid base64 URL encoding: %s", err)
+	}
+
+	// The length of this octet string MUST be ceiling(log-base-2(n)/8)
+	// octets (where n is the order of the curve). This is because the private
+	// key d must be in the interval [1, n-1] so the bitlength of d should be
+	// no larger than the bitlength of n-1. The easiest way to find the octet
+	// length is to take bitlength(n-1), add 7 to force a carry, and shift this
+	// bit sequence right by 3, which is essentially dividing by 8 and adding
+	// 1 if there is any remainder. Thus, the private key value d should be
+	// output to (bitlength(n-1)+7)>>3 octets.
+	n := curve.Params().N
+	octetLength := (new(big.Int).Sub(n, big.NewInt(1)).BitLen() + 7) >> 3
+	dByteLength := len(dBytes)
+
+	if dByteLength != octetLength {
+		return nil, fmt.Errorf("invalid number of octets: got %d, should be %d", dByteLength, octetLength)
+	}
+
+	return new(big.Int).SetBytes(dBytes), nil
+}
+
+func parseRSAModulusParam(nB64Url string) (*big.Int, error) {
+	nBytes, err := joseBase64UrlDecode(nB64Url)
+	if err != nil {
+		return nil, fmt.Errorf("invalid base64 URL encoding: %s", err)
+	}
+
+	return new(big.Int).SetBytes(nBytes), nil
+}
+
+func serializeRSAPublicExponentParam(e int) []byte {
+	// We MUST use the minimum number of octets to represent E.
+	// E is supposed to be 65537 for performance and security reasons
+	// and is what golang's rsa package generates, but it might be
+	// different if imported from some other generator.
+	buf := make([]byte, 4)
+	binary.BigEndian.PutUint32(buf, uint32(e))
+	var i int
+	for i = 0; i < 8; i++ {
+		if buf[i] != 0 {
+			break
+		}
+	}
+	return buf[i:]
+}
+
+func parseRSAPublicExponentParam(eB64Url string) (int, error) {
+	eBytes, err := joseBase64UrlDecode(eB64Url)
+	if err != nil {
+		return 0, fmt.Errorf("invalid base64 URL encoding: %s", err)
+	}
+	// Only the minimum number of bytes were used to represent E, but
+	// binary.BigEndian.Uint32 expects at least 4 bytes, so we need
+	// to add zero padding if necassary.
+	byteLen := len(eBytes)
+	buf := make([]byte, 4-byteLen, 4)
+	eBytes = append(buf, eBytes...)
+
+	return int(binary.BigEndian.Uint32(eBytes)), nil
+}
+
+func parseRSAPrivateKeyParamFromMap(m map[string]interface{}, key string) (*big.Int, error) {
+	b64Url, err := stringFromMap(m, key)
+	if err != nil {
+		return nil, err
+	}
+
+	paramBytes, err := joseBase64UrlDecode(b64Url)
+	if err != nil {
+		return nil, fmt.Errorf("invaled base64 URL encoding: %s", err)
+	}
+
+	return new(big.Int).SetBytes(paramBytes), nil
+}
+
+func createPemBlock(name string, derBytes []byte, headers map[string]interface{}) (*pem.Block, error) {
+	pemBlock := &pem.Block{Type: name, Bytes: derBytes, Headers: map[string]string{}}
+	for k, v := range headers {
+		switch val := v.(type) {
+		case string:
+			pemBlock.Headers[k] = val
+		case []string:
+			if k == "hosts" {
+				pemBlock.Headers[k] = strings.Join(val, ",")
+			} else {
+				// Return error, non-encodable type
+			}
+		default:
+			// Return error, non-encodable type
+		}
+	}
+
+	return pemBlock, nil
+}
+
+func pubKeyFromPEMBlock(pemBlock *pem.Block) (PublicKey, error) {
+	cryptoPublicKey, err := x509.ParsePKIXPublicKey(pemBlock.Bytes)
+	if err != nil {
+		return nil, fmt.Errorf("unable to decode Public Key PEM data: %s", err)
+	}
+
+	pubKey, err := FromCryptoPublicKey(cryptoPublicKey)
+	if err != nil {
+		return nil, err
+	}
+
+	addPEMHeadersToKey(pemBlock, pubKey)
+
+	return pubKey, nil
+}
+
+func addPEMHeadersToKey(pemBlock *pem.Block, pubKey PublicKey) {
+	for key, value := range pemBlock.Headers {
+		var safeVal interface{}
+		if key == "hosts" {
+			safeVal = strings.Split(value, ",")
+		} else {
+			safeVal = value
+		}
+		pubKey.AddExtendedField(key, safeVal)
+	}
+}
