summaryrefslogtreecommitdiff
path: root/vendor/github.com/docker/libtrust
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/docker/libtrust')
-rw-r--r--vendor/github.com/docker/libtrust/CONTRIBUTING.md13
-rw-r--r--vendor/github.com/docker/libtrust/LICENSE191
-rw-r--r--vendor/github.com/docker/libtrust/MAINTAINERS3
-rw-r--r--vendor/github.com/docker/libtrust/README.md22
-rw-r--r--vendor/github.com/docker/libtrust/certificates.go175
-rw-r--r--vendor/github.com/docker/libtrust/doc.go9
-rw-r--r--vendor/github.com/docker/libtrust/ec_key.go428
-rw-r--r--vendor/github.com/docker/libtrust/filter.go50
-rw-r--r--vendor/github.com/docker/libtrust/hash.go56
-rw-r--r--vendor/github.com/docker/libtrust/jsonsign.go657
-rw-r--r--vendor/github.com/docker/libtrust/key.go253
-rw-r--r--vendor/github.com/docker/libtrust/key_files.go255
-rw-r--r--vendor/github.com/docker/libtrust/key_manager.go175
-rw-r--r--vendor/github.com/docker/libtrust/rsa_key.go427
-rw-r--r--vendor/github.com/docker/libtrust/util.go363
15 files changed, 0 insertions, 3077 deletions
diff --git a/vendor/github.com/docker/libtrust/CONTRIBUTING.md b/vendor/github.com/docker/libtrust/CONTRIBUTING.md
deleted file mode 100644
index 05be0f8ab..000000000
--- a/vendor/github.com/docker/libtrust/CONTRIBUTING.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Contributing to libtrust
-
-Want to hack on libtrust? Awesome! Here are instructions to get you
-started.
-
-libtrust is a part of the [Docker](https://www.docker.com) project, and follows
-the same rules and principles. If you're already familiar with the way
-Docker does things, you'll feel right at home.
-
-Otherwise, go read
-[Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md).
-
-Happy hacking!
diff --git a/vendor/github.com/docker/libtrust/LICENSE b/vendor/github.com/docker/libtrust/LICENSE
deleted file mode 100644
index 27448585a..000000000
--- a/vendor/github.com/docker/libtrust/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-
- 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/vendor/github.com/docker/libtrust/MAINTAINERS b/vendor/github.com/docker/libtrust/MAINTAINERS
deleted file mode 100644
index 9768175fe..000000000
--- a/vendor/github.com/docker/libtrust/MAINTAINERS
+++ /dev/null
@@ -1,3 +0,0 @@
-Solomon Hykes <solomon@docker.com>
-Josh Hawn <josh@docker.com> (github: jlhawn)
-Derek McGowan <derek@docker.com> (github: dmcgowan)
diff --git a/vendor/github.com/docker/libtrust/README.md b/vendor/github.com/docker/libtrust/README.md
deleted file mode 100644
index dcffb31ae..000000000
--- a/vendor/github.com/docker/libtrust/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# libtrust
-
-> **WARNING** this library is no longer actively developed, and will be integrated
-> in the [docker/distribution][https://www.github.com/docker/distribution]
-> repository in future.
-
-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/vendor/github.com/docker/libtrust/certificates.go b/vendor/github.com/docker/libtrust/certificates.go
deleted file mode 100644
index 3dcca33cb..000000000
--- a/vendor/github.com/docker/libtrust/certificates.go
+++ /dev/null
@@ -1,175 +0,0 @@
-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/vendor/github.com/docker/libtrust/doc.go b/vendor/github.com/docker/libtrust/doc.go
deleted file mode 100644
index ec5d2159c..000000000
--- a/vendor/github.com/docker/libtrust/doc.go
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-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/vendor/github.com/docker/libtrust/ec_key.go b/vendor/github.com/docker/libtrust/ec_key.go
deleted file mode 100644
index 00bbe4b3c..000000000
--- a/vendor/github.com/docker/libtrust/ec_key.go
+++ /dev/null
@@ -1,428 +0,0 @@
-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/vendor/github.com/docker/libtrust/filter.go b/vendor/github.com/docker/libtrust/filter.go
deleted file mode 100644
index 5b2b4fca6..000000000
--- a/vendor/github.com/docker/libtrust/filter.go
+++ /dev/null
@@ -1,50 +0,0 @@
-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/vendor/github.com/docker/libtrust/hash.go b/vendor/github.com/docker/libtrust/hash.go
deleted file mode 100644
index a2df787dd..000000000
--- a/vendor/github.com/docker/libtrust/hash.go
+++ /dev/null
@@ -1,56 +0,0 @@
-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/vendor/github.com/docker/libtrust/jsonsign.go b/vendor/github.com/docker/libtrust/jsonsign.go
deleted file mode 100644
index cb2ca9a76..000000000
--- a/vendor/github.com/docker/libtrust/jsonsign.go
+++ /dev/null
@@ -1,657 +0,0 @@
-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/vendor/github.com/docker/libtrust/key.go b/vendor/github.com/docker/libtrust/key.go
deleted file mode 100644
index 73642db2a..000000000
--- a/vendor/github.com/docker/libtrust/key.go
+++ /dev/null
@@ -1,253 +0,0 @@
-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/vendor/github.com/docker/libtrust/key_files.go b/vendor/github.com/docker/libtrust/key_files.go
deleted file mode 100644
index c526de545..000000000
--- a/vendor/github.com/docker/libtrust/key_files.go
+++ /dev/null
@@ -1,255 +0,0 @@
-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/vendor/github.com/docker/libtrust/key_manager.go b/vendor/github.com/docker/libtrust/key_manager.go
deleted file mode 100644
index 9a98ae357..000000000
--- a/vendor/github.com/docker/libtrust/key_manager.go
+++ /dev/null
@@ -1,175 +0,0 @@
-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/vendor/github.com/docker/libtrust/rsa_key.go b/vendor/github.com/docker/libtrust/rsa_key.go
deleted file mode 100644
index dac4cacf2..000000000
--- a/vendor/github.com/docker/libtrust/rsa_key.go
+++ /dev/null
@@ -1,427 +0,0 @@
-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/vendor/github.com/docker/libtrust/util.go b/vendor/github.com/docker/libtrust/util.go
deleted file mode 100644
index a5a101d3f..000000000
--- a/vendor/github.com/docker/libtrust/util.go
+++ /dev/null
@@ -1,363 +0,0 @@
-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 omitted 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)
- }
-}