mirror of https://github.com/docker/docs.git
Fixing Godeps
This commit is contained in:
parent
6805f290f0
commit
26f694196e
|
@ -2,8 +2,7 @@
|
|||
"ImportPath": "github.com/docker/vetinari",
|
||||
"GoVersion": "go1.4.2",
|
||||
"Packages": [
|
||||
"github.com/docker/vetinari/cmd/notary",
|
||||
"github.com/docker/vetinari/cmd/vetinari-server"
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
|
@ -11,10 +10,6 @@
|
|||
"Comment": "null-15",
|
||||
"Rev": "35bc42037350f0078e3c974c6ea690f1926603ab"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/Sirupsen/logrus",
|
||||
"Rev": "55eb11d21d2a31a3cc93838241d04800f52e823d"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/BurntSushi/toml",
|
||||
"Rev": "bd2bdf7f18f849530ef7a1c29a4290217cab32a1"
|
||||
|
@ -34,18 +29,13 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/distribution/context",
|
||||
"Comment": "v2.0.0-228-gb230183",
|
||||
"Rev": "b230183b0fe8b8ed3c9ae2898c47c8c8618dc80f"
|
||||
"Comment": "v2.0.0-rc.3-2-g75919b7",
|
||||
"Rev": "75919b7dcc5d53894d7e8f1584e91ae148335f3a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/distribution/registry/auth",
|
||||
"Comment": "v2.0.0-228-gb230183",
|
||||
"Rev": "b230183b0fe8b8ed3c9ae2898c47c8c8618dc80f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/distribution/uuid",
|
||||
"Comment": "v2.0.0-228-gb230183",
|
||||
"Rev": "b230183b0fe8b8ed3c9ae2898c47c8c8618dc80f"
|
||||
"Comment": "v2.0.0-rc.3-2-g75919b7",
|
||||
"Rev": "75919b7dcc5d53894d7e8f1584e91ae148335f3a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/libtrust",
|
||||
|
@ -56,12 +46,25 @@
|
|||
"Rev": "61b53384b24bfa83e8e0a5f11f28ae83457fd80c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/endophage/gotuf/data",
|
||||
"Rev": "930a4e1cc71f866a412aea60c960ee4345f0c76a"
|
||||
"ImportPath": "github.com/endophage/gotuf",
|
||||
"Rev": "c7154b63cf6e8485ea4af4c7f299ccbea6731d43"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/endophage/gotuf/errors",
|
||||
"Rev": "930a4e1cc71f866a412aea60c960ee4345f0c76a"
|
||||
"ImportPath": "github.com/go-sql-driver/mysql",
|
||||
"Comment": "v1.2-97-g0cc29e9",
|
||||
"Rev": "0cc29e9fe8e25c2c58cf47bcab566e029bbaa88b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/proto",
|
||||
"Rev": "655cdfa588ea190e901bc5590e65d5621688847c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/context",
|
||||
"Rev": "14f550f51af52180c2eefed15e5fd18d63c0a64a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/mux",
|
||||
"Rev": "e444e69cbd2e2e3e0749a2f3c717cec491552bbf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/inconshreveable/mousetrap",
|
||||
|
@ -105,31 +108,6 @@
|
|||
"ImportPath": "github.com/spf13/viper",
|
||||
"Rev": "be5ff3e4840cf692388bde7a057595a474ef379e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/endophage/gotuf/keys",
|
||||
"Rev": "930a4e1cc71f866a412aea60c960ee4345f0c76a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/endophage/gotuf/signed",
|
||||
"Rev": "930a4e1cc71f866a412aea60c960ee4345f0c76a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/go-sql-driver/mysql",
|
||||
"Comment": "v1.2-108-g66b7d5c",
|
||||
"Rev": "66b7d5c4956096efd4c945494d64ad73f1d9ec39"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/golang/protobuf/proto",
|
||||
"Rev": "655cdfa588ea190e901bc5590e65d5621688847c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/context",
|
||||
"Rev": "14f550f51af52180c2eefed15e5fd18d63c0a64a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gorilla/mux",
|
||||
"Rev": "e444e69cbd2e2e3e0749a2f3c717cec491552bbf"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/tent/canonical-json-go",
|
||||
"Rev": "96e4ba3a7613a1216cbd1badca4efe382adea337"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package context
|
||||
|
||||
import (
|
||||
"github.com/docker/distribution/uuid"
|
||||
"code.google.com/p/go-uuid/uuid"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
@ -27,7 +27,7 @@ func (ic *instanceContext) Value(key interface{}) interface{} {
|
|||
|
||||
var background = &instanceContext{
|
||||
Context: context.Background(),
|
||||
id: uuid.Generate().String(),
|
||||
id: uuid.New(),
|
||||
}
|
||||
|
||||
// Background returns a non-nil, empty Context. The background context
|
||||
|
|
|
@ -8,15 +8,14 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"code.google.com/p/go-uuid/uuid"
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/docker/distribution/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// Common errors used with this package.
|
||||
var (
|
||||
ErrNoRequestContext = errors.New("no http request in context")
|
||||
ErrNoResponseWriterContext = errors.New("no http response in context")
|
||||
)
|
||||
|
||||
func parseIP(ipStr string) net.IP {
|
||||
|
@ -79,7 +78,7 @@ func WithRequest(ctx Context, r *http.Request) Context {
|
|||
return &httpRequestContext{
|
||||
Context: ctx,
|
||||
startedAt: time.Now(),
|
||||
id: uuid.Generate().String(),
|
||||
id: uuid.New(), // assign the request a unique.
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
@ -111,20 +110,6 @@ func WithResponseWriter(ctx Context, w http.ResponseWriter) (Context, http.Respo
|
|||
return irw, irw
|
||||
}
|
||||
|
||||
// GetResponseWriter returns the http.ResponseWriter from the provided
|
||||
// context. If not present, ErrNoResponseWriterContext is returned. The
|
||||
// returned instance provides instrumentation in the context.
|
||||
func GetResponseWriter(ctx Context) (http.ResponseWriter, error) {
|
||||
v := ctx.Value("http.response")
|
||||
|
||||
rw, ok := v.(http.ResponseWriter)
|
||||
if !ok || rw == nil {
|
||||
return nil, ErrNoResponseWriterContext
|
||||
}
|
||||
|
||||
return rw, nil
|
||||
}
|
||||
|
||||
// getVarsFromRequest let's us change request vars implementation for testing
|
||||
// and maybe future changes.
|
||||
var getVarsFromRequest = mux.Vars
|
||||
|
@ -302,7 +287,7 @@ func (irw *instrumentedResponseWriter) Flush() {
|
|||
func (irw *instrumentedResponseWriter) Value(key interface{}) interface{} {
|
||||
if keyStr, ok := key.(string); ok {
|
||||
if keyStr == "http.response" {
|
||||
return irw
|
||||
return irw.ResponseWriter
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(keyStr, "http.response.") {
|
||||
|
@ -322,7 +307,9 @@ func (irw *instrumentedResponseWriter) Value(key interface{}) interface{} {
|
|||
case "written":
|
||||
return irw.written
|
||||
case "status":
|
||||
if irw.status != 0 {
|
||||
return irw.status
|
||||
}
|
||||
case "contenttype":
|
||||
contentType := irw.Header().Get("Content-Type")
|
||||
if contentType != "" {
|
||||
|
|
|
@ -132,21 +132,8 @@ func TestWithResponseWriter(t *testing.T) {
|
|||
trw := testResponseWriter{}
|
||||
ctx, rw := WithResponseWriter(Background(), &trw)
|
||||
|
||||
if ctx.Value("http.response") != rw {
|
||||
t.Fatalf("response not available in context: %v != %v", ctx.Value("http.response"), rw)
|
||||
}
|
||||
|
||||
grw, err := GetResponseWriter(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("error getting response writer: %v", err)
|
||||
}
|
||||
|
||||
if grw != rw {
|
||||
t.Fatalf("unexpected response writer returned: %#v != %#v", grw, rw)
|
||||
}
|
||||
|
||||
if ctx.Value("http.response.status") != 0 {
|
||||
t.Fatalf("response status should always be a number and should be zero here: %v != 0", ctx.Value("http.response.status"))
|
||||
if ctx.Value("http.response") != &trw {
|
||||
t.Fatalf("response not available in context: %v != %v", ctx.Value("http.response"), &trw)
|
||||
}
|
||||
|
||||
if n, err := rw.Write(make([]byte, 1024)); err != nil {
|
||||
|
|
|
@ -3,8 +3,6 @@ package context
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/distribution/uuid"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -101,8 +99,3 @@ func getLogrusLogger(ctx Context, keys ...interface{}) *logrus.Entry {
|
|||
|
||||
return logger.WithFields(fields)
|
||||
}
|
||||
|
||||
func init() {
|
||||
// inject a logger into the uuid library.
|
||||
uuid.Loggerf = GetLogger(Background()).Warnf
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/uuid"
|
||||
"code.google.com/p/go-uuid/uuid"
|
||||
)
|
||||
|
||||
// WithTrace allocates a traced timing span in a new context. This allows a
|
||||
|
@ -45,7 +45,7 @@ func WithTrace(ctx Context) (Context, func(format string, a ...interface{})) {
|
|||
f := runtime.FuncForPC(pc)
|
||||
ctx = &traced{
|
||||
Context: ctx,
|
||||
id: uuid.Generate().String(),
|
||||
id: uuid.New(),
|
||||
start: time.Now(),
|
||||
parent: GetStringValue(ctx, "trace.id"),
|
||||
fnname: f.Name(),
|
||||
|
@ -54,14 +54,9 @@ func WithTrace(ctx Context) (Context, func(format string, a ...interface{})) {
|
|||
}
|
||||
|
||||
return ctx, func(format string, a ...interface{}) {
|
||||
GetLogger(ctx,
|
||||
"trace.duration",
|
||||
"trace.id",
|
||||
"trace.parent.id",
|
||||
"trace.func",
|
||||
"trace.file",
|
||||
"trace.line").
|
||||
Debugf(format, a...)
|
||||
GetLogger(ctx, "trace.duration", "trace.id", "trace.parent.id",
|
||||
"trace.func", "trace.file", "trace.line").
|
||||
Infof(format, a...) // info may be too chatty.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// An access controller has a simple interface with a single `Authorized`
|
||||
// method which checks that a given request is authorized to perform one or
|
||||
// more actions on one or more resources. This method should return a non-nil
|
||||
// error if the request is not authorized.
|
||||
// error if the requset is not authorized.
|
||||
//
|
||||
// An implementation registers its access controller by name with a constructor
|
||||
// which accepts an options map for configuring the access controller.
|
||||
|
@ -50,7 +50,7 @@ type Resource struct {
|
|||
}
|
||||
|
||||
// Access describes a specific action that is
|
||||
// requested or allowed for a given resource.
|
||||
// requested or allowed for a given recource.
|
||||
type Access struct {
|
||||
Resource
|
||||
Action string
|
||||
|
|
2
Godeps/_workspace/src/github.com/docker/distribution/registry/auth/silly/access.go
generated
vendored
2
Godeps/_workspace/src/github.com/docker/distribution/registry/auth/silly/access.go
generated
vendored
|
@ -66,7 +66,7 @@ func (ac *accessController) Authorized(ctx context.Context, accessRecords ...aut
|
|||
return nil, &challenge
|
||||
}
|
||||
|
||||
return auth.WithUser(ctx, auth.UserInfo{Name: "silly"}), nil
|
||||
return context.WithValue(ctx, "auth.user", auth.UserInfo{Name: "silly"}), nil
|
||||
}
|
||||
|
||||
type challenge struct {
|
||||
|
|
2
Godeps/_workspace/src/github.com/docker/distribution/registry/auth/token/util.go
generated
vendored
2
Godeps/_workspace/src/github.com/docker/distribution/registry/auth/token/util.go
generated
vendored
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
// joseBase64UrlEncode encodes the given data using the standard base64 url
|
||||
// encoding format but with all trailing '=' characters omitted in accordance
|
||||
// encoding format but with all trailing '=' characters ommitted in accordance
|
||||
// with the jose specification.
|
||||
// http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-31#section-2
|
||||
func joseBase64UrlEncode(b []byte) string {
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
// Package uuid provides simple UUID generation. Only version 4 style UUIDs
|
||||
// can be generated.
|
||||
//
|
||||
// Please see http://tools.ietf.org/html/rfc4122 for details on UUIDs.
|
||||
package uuid
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// Bits is the number of bits in a UUID
|
||||
Bits = 128
|
||||
|
||||
// Size is the number of bytes in a UUID
|
||||
Size = Bits / 8
|
||||
|
||||
format = "%08x-%04x-%04x-%04x-%012x"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrUUIDInvalid indicates a parsed string is not a valid uuid.
|
||||
ErrUUIDInvalid = fmt.Errorf("invalid uuid")
|
||||
|
||||
// Loggerf can be used to override the default logging destination. Such
|
||||
// log messages in this library should be logged at warning or higher.
|
||||
Loggerf = log.Printf
|
||||
)
|
||||
|
||||
// UUID represents a UUID value. UUIDs can be compared and set to other values
|
||||
// and accessed by byte.
|
||||
type UUID [Size]byte
|
||||
|
||||
// Generate creates a new, version 4 uuid.
|
||||
func Generate() (u UUID) {
|
||||
const (
|
||||
// ensures we backoff for less than 450ms total. Use the following to
|
||||
// select new value, in units of 10ms:
|
||||
// n*(n+1)/2 = d -> n^2 + n - 2d -> n = (sqrt(8d + 1) - 1)/2
|
||||
maxretries = 9
|
||||
backoff = time.Millisecond * 10
|
||||
)
|
||||
|
||||
var (
|
||||
totalBackoff time.Duration
|
||||
retries int
|
||||
)
|
||||
|
||||
for {
|
||||
// This should never block but the read may fail. Because of this,
|
||||
// we just try to read the random number generator until we get
|
||||
// something. This is a very rare condition but may happen.
|
||||
b := time.Duration(retries) * backoff
|
||||
time.Sleep(b)
|
||||
totalBackoff += b
|
||||
|
||||
_, err := io.ReadFull(rand.Reader, u[:])
|
||||
if err != nil {
|
||||
if err == syscall.EPERM {
|
||||
// EPERM represents an entropy pool exhaustion, a condition under
|
||||
// which we backoff and retry.
|
||||
if retries < maxretries {
|
||||
retries++
|
||||
Loggerf("error generating version 4 uuid, retrying: %v", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Any other errors represent a system problem. What did someone
|
||||
// do to /dev/urandom?
|
||||
panic(fmt.Errorf("error reading random number generator, retried for %v: %v", totalBackoff, err))
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
u[6] = (u[6] & 0x0f) | 0x40 // set version byte
|
||||
u[8] = (u[8] & 0x3f) | 0x80 // set high order byte 0b10{8,9,a,b}
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
// Parse attempts to extract a uuid from the string or returns an error.
|
||||
func Parse(s string) (u UUID, err error) {
|
||||
if len(s) != 36 {
|
||||
return UUID{}, ErrUUIDInvalid
|
||||
}
|
||||
|
||||
// create stack addresses for each section of the uuid.
|
||||
p := make([][]byte, 5)
|
||||
|
||||
if _, err := fmt.Sscanf(s, format, &p[0], &p[1], &p[2], &p[3], &p[4]); err != nil {
|
||||
return u, err
|
||||
}
|
||||
|
||||
copy(u[0:4], p[0])
|
||||
copy(u[4:6], p[1])
|
||||
copy(u[6:8], p[2])
|
||||
copy(u[8:10], p[3])
|
||||
copy(u[10:16], p[4])
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (u UUID) String() string {
|
||||
return fmt.Sprintf(format, u[:4], u[4:6], u[6:8], u[8:10], u[10:])
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package uuid
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
const iterations = 1000
|
||||
|
||||
func TestUUID4Generation(t *testing.T) {
|
||||
for i := 0; i < iterations; i++ {
|
||||
u := Generate()
|
||||
|
||||
if u[6]&0xf0 != 0x40 {
|
||||
t.Fatalf("version byte not correctly set: %v, %08b %08b", u, u[6], u[6]&0xf0)
|
||||
}
|
||||
|
||||
if u[8]&0xc0 != 0x80 {
|
||||
t.Fatalf("top order 8th byte not correctly set: %v, %b", u, u[8])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAndEquality(t *testing.T) {
|
||||
for i := 0; i < iterations; i++ {
|
||||
u := Generate()
|
||||
|
||||
parsed, err := Parse(u.String())
|
||||
if err != nil {
|
||||
t.Fatalf("error parsing uuid %v: %v", u, err)
|
||||
}
|
||||
|
||||
if parsed != u {
|
||||
t.Fatalf("parsing round trip failed: %v != %v", parsed, u)
|
||||
}
|
||||
}
|
||||
|
||||
for _, c := range []string{
|
||||
"bad",
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", // correct length, incorrect format
|
||||
" 20cc7775-2671-43c7-8742-51d1cfa23258", // leading space
|
||||
"20cc7775-2671-43c7-8742-51d1cfa23258 ", // trailing space
|
||||
"00000000-0000-0000-0000-x00000000000", // out of range character
|
||||
} {
|
||||
if _, err := Parse(c); err == nil {
|
||||
t.Fatalf("parsing %q should have failed", c)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,560 +0,0 @@
|
|||
This describes the protocol used by OpenSSH's ssh-agent.
|
||||
|
||||
OpenSSH's agent supports managing keys for the standard SSH protocol
|
||||
2 as well as the legacy SSH protocol 1. Support for these key types
|
||||
is almost completely disjoint - in all but a few cases, operations on
|
||||
protocol 2 keys cannot see or affect protocol 1 keys and vice-versa.
|
||||
|
||||
Protocol 1 and protocol 2 keys are separated because of the differing
|
||||
cryptographic usage: protocol 1 private RSA keys are used to decrypt
|
||||
challenges that were encrypted with the corresponding public key,
|
||||
whereas protocol 2 RSA private keys are used to sign challenges with
|
||||
a private key for verification with the corresponding public key. It
|
||||
is considered unsound practice to use the same key for signing and
|
||||
encryption.
|
||||
|
||||
With a couple of exceptions, the protocol message names used in this
|
||||
document indicate which type of key the message relates to. SSH_*
|
||||
messages refer to protocol 1 keys only. SSH2_* messages refer to
|
||||
protocol 2 keys. Furthermore, the names also indicate whether the
|
||||
message is a request to the agent (*_AGENTC_*) or a reply from the
|
||||
agent (*_AGENT_*). Section 3 below contains the mapping of the
|
||||
protocol message names to their integer values.
|
||||
|
||||
1. Data types
|
||||
|
||||
Because of support for legacy SSH protocol 1 keys, OpenSSH's agent
|
||||
protocol makes use of some data types not defined in RFC 4251.
|
||||
|
||||
1.1 uint16
|
||||
|
||||
The "uint16" data type is a simple MSB-first 16 bit unsigned integer
|
||||
encoded in two bytes.
|
||||
|
||||
1.2 mpint1
|
||||
|
||||
The "mpint1" type represents an arbitrary precision integer (bignum).
|
||||
Its format is as follows:
|
||||
|
||||
uint16 bits
|
||||
byte[(bits + 7) / 8] bignum
|
||||
|
||||
"bignum" contains an unsigned arbitrary precision integer encoded as
|
||||
eight bits per byte in big-endian (MSB first) format.
|
||||
|
||||
Note the difference between the "mpint1" encoding and the "mpint"
|
||||
encoding defined in RFC 4251. Also note that the length of the encoded
|
||||
integer is specified in bits, not bytes and that the byte length of
|
||||
the integer must be calculated by rounding up the number of bits to the
|
||||
nearest eight.
|
||||
|
||||
2. Protocol Messages
|
||||
|
||||
All protocol messages are prefixed with their length in bytes, encoded
|
||||
as a 32 bit unsigned integer. Specifically:
|
||||
|
||||
uint32 message_length
|
||||
byte[message_length] message
|
||||
|
||||
The following message descriptions refer only to the content the
|
||||
"message" field.
|
||||
|
||||
2.1 Generic server responses
|
||||
|
||||
The following generic messages may be sent by the server in response to
|
||||
requests from the client. On success the agent may reply either with:
|
||||
|
||||
byte SSH_AGENT_SUCCESS
|
||||
|
||||
or a request-specific success message.
|
||||
|
||||
On failure, the agent may reply with:
|
||||
|
||||
byte SSH_AGENT_FAILURE
|
||||
|
||||
SSH_AGENT_FAILURE messages are also sent in reply to unknown request
|
||||
types.
|
||||
|
||||
2.2 Adding keys to the agent
|
||||
|
||||
Keys are added to the agent using the SSH_AGENTC_ADD_RSA_IDENTITY and
|
||||
SSH2_AGENTC_ADD_IDENTITY requests for protocol 1 and protocol 2 keys
|
||||
respectively.
|
||||
|
||||
Two variants of these requests are SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
|
||||
and SSH2_AGENTC_ADD_ID_CONSTRAINED - these add keys with optional
|
||||
"constraints" on their usage.
|
||||
|
||||
OpenSSH may be built with support for keys hosted on a smartcard
|
||||
or other hardware security module. These keys may be added
|
||||
to the agent using the SSH_AGENTC_ADD_SMARTCARD_KEY and
|
||||
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED requests.
|
||||
|
||||
2.2.1 Key constraints
|
||||
|
||||
The OpenSSH agent supports some basic optional constraints on key usage.
|
||||
At present there are two constraints defined.
|
||||
|
||||
The first constraint limits the validity duration of a key. It is
|
||||
encoded as:
|
||||
|
||||
byte SSH_AGENT_CONSTRAIN_LIFETIME
|
||||
uint32 seconds
|
||||
|
||||
Where "seconds" contains the number of seconds that the key shall remain
|
||||
valid measured from the moment that the agent receives it. After the
|
||||
validity period has expired, OpenSSH's agent will erase these keys from
|
||||
memory.
|
||||
|
||||
The second constraint requires the agent to seek explicit user
|
||||
confirmation before performing private key operations with the loaded
|
||||
key. This constraint is encoded as:
|
||||
|
||||
byte SSH_AGENT_CONSTRAIN_CONFIRM
|
||||
|
||||
Zero or more constraints may be specified when adding a key with one
|
||||
of the *_CONSTRAINED requests. Multiple constraints are appended
|
||||
consecutively to the end of the request:
|
||||
|
||||
byte constraint1_type
|
||||
.... constraint1_data
|
||||
byte constraint2_type
|
||||
.... constraint2_data
|
||||
....
|
||||
byte constraintN_type
|
||||
.... constraintN_data
|
||||
|
||||
Such a sequence of zero or more constraints will be referred to below
|
||||
as "constraint[]". Agents may determine whether there are constraints
|
||||
by checking whether additional data exists in the "add key" request
|
||||
after the key data itself. OpenSSH will refuse to add a key if it
|
||||
contains unknown constraints.
|
||||
|
||||
2.2.2 Add protocol 1 key
|
||||
|
||||
A client may add a protocol 1 key to an agent with the following
|
||||
request:
|
||||
|
||||
byte SSH_AGENTC_ADD_RSA_IDENTITY or
|
||||
SSH_AGENTC_ADD_RSA_ID_CONSTRAINED
|
||||
uint32 ignored
|
||||
mpint1 rsa_n
|
||||
mpint1 rsa_e
|
||||
mpint1 rsa_d
|
||||
mpint1 rsa_iqmp
|
||||
mpint1 rsa_q
|
||||
mpint1 rsa_p
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
Note that there is some redundancy in the key parameters; a key could be
|
||||
fully specified using just rsa_q, rsa_p and rsa_e at the cost of extra
|
||||
computation.
|
||||
|
||||
"key_constraints" may only be present if the request type is
|
||||
SSH_AGENTC_ADD_RSA_ID_CONSTRAINED.
|
||||
|
||||
The agent will reply with a SSH_AGENT_SUCCESS if the key has been
|
||||
successfully added or a SSH_AGENT_FAILURE if an error occurred.
|
||||
|
||||
2.2.3 Add protocol 2 key
|
||||
|
||||
The OpenSSH agent supports DSA, ECDSA and RSA keys for protocol 2. DSA
|
||||
keys may be added using the following request
|
||||
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED
|
||||
string "ssh-dss"
|
||||
mpint dsa_p
|
||||
mpint dsa_q
|
||||
mpint dsa_g
|
||||
mpint dsa_public_key
|
||||
mpint dsa_private_key
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
DSA certificates may be added with:
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED
|
||||
string "ssh-dss-cert-v00@openssh.com"
|
||||
string certificate
|
||||
mpint dsa_private_key
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
ECDSA keys may be added using the following request
|
||||
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED
|
||||
string "ecdsa-sha2-nistp256" |
|
||||
"ecdsa-sha2-nistp384" |
|
||||
"ecdsa-sha2-nistp521"
|
||||
string ecdsa_curve_name
|
||||
string ecdsa_public_key
|
||||
mpint ecdsa_private
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
ECDSA certificates may be added with:
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED
|
||||
string "ecdsa-sha2-nistp256-cert-v01@openssh.com" |
|
||||
"ecdsa-sha2-nistp384-cert-v01@openssh.com" |
|
||||
"ecdsa-sha2-nistp521-cert-v01@openssh.com"
|
||||
string certificate
|
||||
mpint ecdsa_private_key
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
RSA keys may be added with this request:
|
||||
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED
|
||||
string "ssh-rsa"
|
||||
mpint rsa_n
|
||||
mpint rsa_e
|
||||
mpint rsa_d
|
||||
mpint rsa_iqmp
|
||||
mpint rsa_p
|
||||
mpint rsa_q
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
RSA certificates may be added with this request:
|
||||
|
||||
byte SSH2_AGENTC_ADD_IDENTITY or
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED
|
||||
string "ssh-rsa-cert-v00@openssh.com"
|
||||
string certificate
|
||||
mpint rsa_d
|
||||
mpint rsa_iqmp
|
||||
mpint rsa_p
|
||||
mpint rsa_q
|
||||
string key_comment
|
||||
constraint[] key_constraints
|
||||
|
||||
Note that the 'rsa_p' and 'rsa_q' parameters are sent in the reverse
|
||||
order to the protocol 1 add keys message. As with the corresponding
|
||||
protocol 1 "add key" request, the private key is overspecified to avoid
|
||||
redundant processing.
|
||||
|
||||
For DSA, ECDSA and RSA key add requests, "key_constraints" may only be
|
||||
present if the request type is SSH2_AGENTC_ADD_ID_CONSTRAINED.
|
||||
|
||||
The agent will reply with a SSH_AGENT_SUCCESS if the key has been
|
||||
successfully added or a SSH_AGENT_FAILURE if an error occurred.
|
||||
|
||||
2.2.4 Loading keys from a smartcard
|
||||
|
||||
The OpenSSH agent may have optional smartcard support built in to it. If
|
||||
so, it supports an operation to load keys from a smartcard. Technically,
|
||||
only the public components of the keys are loaded into the agent so
|
||||
this operation really arranges for future private key operations to be
|
||||
delegated to the smartcard.
|
||||
|
||||
byte SSH_AGENTC_ADD_SMARTCARD_KEY or
|
||||
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED
|
||||
string reader_id
|
||||
string pin
|
||||
constraint[] key_constraints
|
||||
|
||||
"reader_id" is an identifier to a smartcard reader and "pin"
|
||||
is a PIN or passphrase used to unlock the private key(s) on the
|
||||
device. "key_constraints" may only be present if the request type is
|
||||
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED.
|
||||
|
||||
This operation may load all SSH keys that are unlocked using the
|
||||
"pin" on the specified reader. The type of key loaded (protocol 1
|
||||
or protocol 2) will be specified by the smartcard itself, it is not
|
||||
client-specified.
|
||||
|
||||
The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
|
||||
been successfully loaded or a SSH_AGENT_FAILURE if an error occurred.
|
||||
The agent will also return SSH_AGENT_FAILURE if it does not support
|
||||
smartcards.
|
||||
|
||||
2.3 Removing multiple keys
|
||||
|
||||
A client may request that an agent delete all protocol 1 keys using the
|
||||
following request:
|
||||
|
||||
byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES
|
||||
|
||||
This message requests the deletion of all protocol 2 keys:
|
||||
|
||||
byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES
|
||||
|
||||
On success, the agent will delete all keys of the requested type and
|
||||
reply with a SSH_AGENT_SUCCESS message. If an error occurred, the agent
|
||||
will reply with SSH_AGENT_FAILURE.
|
||||
|
||||
Note that, to delete all keys (both protocol 1 and 2), a client
|
||||
must send both a SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES and a
|
||||
SSH2_AGENTC_REMOVE_ALL_IDENTITIES request.
|
||||
|
||||
2.4 Removing specific keys
|
||||
|
||||
2.4.1 Removing a protocol 1 key
|
||||
|
||||
Removal of a protocol 1 key may be requested with the following message:
|
||||
|
||||
byte SSH_AGENTC_REMOVE_RSA_IDENTITY
|
||||
uint32 key_bits
|
||||
mpint1 rsa_e
|
||||
mpint1 rsa_n
|
||||
|
||||
Note that key_bits is strictly redundant, as it may be inferred by the
|
||||
length of rsa_n.
|
||||
|
||||
The agent will delete any private key matching the specified public key
|
||||
and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
|
||||
return SSH_AGENT_FAILURE.
|
||||
|
||||
2.4.2 Removing a protocol 2 key
|
||||
|
||||
Protocol 2 keys may be removed with the following request:
|
||||
|
||||
byte SSH2_AGENTC_REMOVE_IDENTITY
|
||||
string key_blob
|
||||
|
||||
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
|
||||
Algorithms" for any of the supported protocol 2 key types.
|
||||
|
||||
The agent will delete any private key matching the specified public key
|
||||
and return SSH_AGENT_SUCCESS. If no such key was found, the agent will
|
||||
return SSH_AGENT_FAILURE.
|
||||
|
||||
2.4.3 Removing keys loaded from a smartcard
|
||||
|
||||
A client may request that a server remove one or more smartcard-hosted
|
||||
keys using this message:
|
||||
|
||||
byte SSH_AGENTC_REMOVE_SMARTCARD_KEY
|
||||
string reader_id
|
||||
string pin
|
||||
|
||||
"reader_id" the an identifier to a smartcard reader and "pin" is a PIN
|
||||
or passphrase used to unlock the private key(s) on the device.
|
||||
|
||||
When this message is received, and if the agent supports
|
||||
smartcard-hosted keys, it will delete all keys that are hosted on the
|
||||
specified smartcard that may be accessed with the given "pin".
|
||||
|
||||
The agent will reply with a SSH_AGENT_SUCCESS if one or more keys have
|
||||
been successfully removed or a SSH_AGENT_FAILURE if an error occurred.
|
||||
The agent will also return SSH_AGENT_FAILURE if it does not support
|
||||
smartcards.
|
||||
|
||||
2.5 Requesting a list of known keys
|
||||
|
||||
An agent may be requested to list which keys it holds. Different
|
||||
requests exist for protocol 1 and protocol 2 keys.
|
||||
|
||||
2.5.1 Requesting a list of protocol 1 keys
|
||||
|
||||
To request a list of protocol 1 keys that are held in the agent, a
|
||||
client may send the following message:
|
||||
|
||||
byte SSH_AGENTC_REQUEST_RSA_IDENTITIES
|
||||
|
||||
The agent will reply with the following message:
|
||||
|
||||
byte SSH_AGENT_RSA_IDENTITIES_ANSWER
|
||||
uint32 num_keys
|
||||
|
||||
Followed by zero or more consecutive keys, encoded as:
|
||||
|
||||
uint32 bits
|
||||
mpint1 rsa_e
|
||||
mpint1 rsa_n
|
||||
string key_comment
|
||||
|
||||
2.5.2 Requesting a list of protocol 2 keys
|
||||
|
||||
A client may send the following message to request a list of
|
||||
protocol 2 keys that are stored in the agent:
|
||||
|
||||
byte SSH2_AGENTC_REQUEST_IDENTITIES
|
||||
|
||||
The agent will reply with the following message header:
|
||||
|
||||
byte SSH2_AGENT_IDENTITIES_ANSWER
|
||||
uint32 num_keys
|
||||
|
||||
Followed by zero or more consecutive keys, encoded as:
|
||||
|
||||
string key_blob
|
||||
string key_comment
|
||||
|
||||
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
|
||||
Algorithms" for any of the supported protocol 2 key types.
|
||||
|
||||
2.6 Private key operations
|
||||
|
||||
The purpose of the agent is to perform private key operations, such as
|
||||
signing and encryption without requiring a passphrase to unlock the
|
||||
key and without allowing the private key itself to be exposed. There
|
||||
are separate requests for the protocol 1 and protocol 2 private key
|
||||
operations.
|
||||
|
||||
2.6.1 Protocol 1 private key challenge
|
||||
|
||||
The private key operation used in version 1 of the SSH protocol is
|
||||
decrypting a challenge that has been encrypted with a public key.
|
||||
It may be requested using this message:
|
||||
|
||||
byte SSH_AGENTC_RSA_CHALLENGE
|
||||
uint32 ignored
|
||||
mpint1 rsa_e
|
||||
mpint1 rsa_n
|
||||
mpint1 encrypted_challenge
|
||||
byte[16] session_id
|
||||
uint32 response_type /* must be 1 */
|
||||
|
||||
"rsa_e" and "rsa_n" are used to identify which private key to use.
|
||||
"encrypted_challenge" is a challenge blob that has (presumably)
|
||||
been encrypted with the public key and must be in the range
|
||||
1 <= encrypted_challenge < 2^256. "session_id" is the SSH protocol 1
|
||||
session ID (computed from the server host key, the server semi-ephemeral
|
||||
key and the session cookie).
|
||||
|
||||
"ignored" and "response_type" exist for compatibility with legacy
|
||||
implementations. "response_type" must be equal to 1; other response
|
||||
types are not supported.
|
||||
|
||||
On receiving this request, the server decrypts the "encrypted_challenge"
|
||||
using the private key matching the supplied (rsa_e, rsa_n) values. For
|
||||
the response derivation, the decrypted challenge is represented as an
|
||||
unsigned, big-endian integer encoded in a 32 byte buffer (i.e. values
|
||||
smaller than 2^248 will have leading 0 bytes).
|
||||
|
||||
The response value is then calculated as:
|
||||
|
||||
response = MD5(decrypted_challenge || session_id)
|
||||
|
||||
and returned in the following message
|
||||
|
||||
byte SSH_AGENT_RSA_RESPONSE
|
||||
byte[16] response
|
||||
|
||||
If the agent cannot find the key specified by the supplied (rsa_e,
|
||||
rsa_n) then it will return SSH_AGENT_FAILURE.
|
||||
|
||||
2.6.2 Protocol 2 private key signature request
|
||||
|
||||
A client may use the following message to request signing of data using
|
||||
a protocol 2 key:
|
||||
|
||||
byte SSH2_AGENTC_SIGN_REQUEST
|
||||
string key_blob
|
||||
string data
|
||||
uint32 flags
|
||||
|
||||
Where "key_blob" is encoded as per RFC 4253 section 6.6 "Public Key
|
||||
Algorithms" for any of the supported protocol 2 key types. "flags" is
|
||||
a bit-mask, but at present only one possible value is defined (see below
|
||||
for its meaning):
|
||||
|
||||
SSH_AGENT_OLD_SIGNATURE 1
|
||||
|
||||
Upon receiving this request, the agent will look up the private key that
|
||||
corresponds to the public key contained in key_blob. It will use this
|
||||
private key to sign the "data" and produce a signature blob using the
|
||||
key type-specific method described in RFC 4253 section 6.6 "Public Key
|
||||
Algorithms".
|
||||
|
||||
An exception to this is for "ssh-dss" keys where the "flags" word
|
||||
contains the value SSH_AGENT_OLD_SIGNATURE. In this case, a legacy
|
||||
signature encoding is used in lieu of the standard one. In this case,
|
||||
the DSA signature blob is encoded as:
|
||||
|
||||
byte[40] signature
|
||||
|
||||
The signature will be returned in the response message:
|
||||
|
||||
byte SSH2_AGENT_SIGN_RESPONSE
|
||||
string signature_blob
|
||||
|
||||
If the agent cannot find the key specified by the supplied key_blob then
|
||||
it will return SSH_AGENT_FAILURE.
|
||||
|
||||
2.7 Locking or unlocking an agent
|
||||
|
||||
The agent supports temporary locking with a passphrase to suspend
|
||||
processing of sensitive operations until it has been unlocked with the
|
||||
same passphrase. To lock an agent, a client send the following request:
|
||||
|
||||
byte SSH_AGENTC_LOCK
|
||||
string passphrase
|
||||
|
||||
Upon receipt of this message and if the agent is not already locked,
|
||||
it will suspend processing requests and return a SSH_AGENT_SUCCESS
|
||||
reply. If the agent is already locked, it will return SSH_AGENT_FAILURE.
|
||||
|
||||
While locked, the agent will refuse all requests except
|
||||
SSH_AGENTC_UNLOCK, SSH_AGENTC_REQUEST_RSA_IDENTITIES and
|
||||
SSH2_AGENTC_REQUEST_IDENTITIES. The "request identities" requests are
|
||||
treated specially by a locked agent: it will always return an empty list
|
||||
of keys.
|
||||
|
||||
To unlock an agent, a client may request:
|
||||
|
||||
byte SSH_AGENTC_UNLOCK
|
||||
string passphrase
|
||||
|
||||
If the passphrase matches and the agent is locked, then it will resume
|
||||
processing all requests and return SSH_AGENT_SUCCESS. If the agent
|
||||
is not locked or the passphrase does not match then it will return
|
||||
SSH_AGENT_FAILURE.
|
||||
|
||||
Locking and unlocking affects both protocol 1 and protocol 2 keys.
|
||||
|
||||
3. Protocol message numbers
|
||||
|
||||
3.1 Requests from client to agent for protocol 1 key operations
|
||||
|
||||
SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
|
||||
SSH_AGENTC_RSA_CHALLENGE 3
|
||||
SSH_AGENTC_ADD_RSA_IDENTITY 7
|
||||
SSH_AGENTC_REMOVE_RSA_IDENTITY 8
|
||||
SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
|
||||
SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
|
||||
|
||||
3.2 Requests from client to agent for protocol 2 key operations
|
||||
|
||||
SSH2_AGENTC_REQUEST_IDENTITIES 11
|
||||
SSH2_AGENTC_SIGN_REQUEST 13
|
||||
SSH2_AGENTC_ADD_IDENTITY 17
|
||||
SSH2_AGENTC_REMOVE_IDENTITY 18
|
||||
SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
|
||||
SSH2_AGENTC_ADD_ID_CONSTRAINED 25
|
||||
|
||||
3.3 Key-type independent requests from client to agent
|
||||
|
||||
SSH_AGENTC_ADD_SMARTCARD_KEY 20
|
||||
SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
|
||||
SSH_AGENTC_LOCK 22
|
||||
SSH_AGENTC_UNLOCK 23
|
||||
SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
|
||||
|
||||
3.4 Generic replies from agent to client
|
||||
|
||||
SSH_AGENT_FAILURE 5
|
||||
SSH_AGENT_SUCCESS 6
|
||||
|
||||
3.5 Replies from agent to client for protocol 1 key operations
|
||||
|
||||
SSH_AGENT_RSA_IDENTITIES_ANSWER 2
|
||||
SSH_AGENT_RSA_RESPONSE 4
|
||||
|
||||
3.6 Replies from agent to client for protocol 2 key operations
|
||||
|
||||
SSH2_AGENT_IDENTITIES_ANSWER 12
|
||||
SSH2_AGENT_SIGN_RESPONSE 14
|
||||
|
||||
3.7 Key constraint identifiers
|
||||
|
||||
SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
|
||||
$OpenBSD: PROTOCOL.agent,v 1.7 2013/01/02 00:33:49 djm Exp $
|
Binary file not shown.
|
@ -1,31 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"code.google.com/p/go.crypto/ssh/agent"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
agent := agent.NewClient(c)
|
||||
|
||||
log.Println("Listing agent keys")
|
||||
|
||||
log.Println("SSH")
|
||||
keys, err := agent.List()
|
||||
if err != nil {
|
||||
log.Fatalf("Error listing keys: %s", err)
|
||||
}
|
||||
for _, k := range keys {
|
||||
log.Printf("Key: %s", k.String())
|
||||
log.Printf("Type: %s", k.Type())
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAttE00a4G72DrFCOUhxlfxpTGCoIapwXlaTD3xUqNsjEPIkBg
|
||||
4egRWIfLNThA89SaFoe0nAHzpvmVzDzLqiV1dlQZG9NQjudmAu/lRBTp26MLQgT9
|
||||
yl7xFthyTOmkkysTwyS300DXrMjew9rjd7hc4qqxTorLI47lZtZPxdGh+jProOKW
|
||||
KnVJfXw3hfRkp9Y3TAarhcV8brRdlzoroWgxPEiZETRrAkGD+o4DmJozOPoL6L05
|
||||
ZAQ6PIY5IQ+oy0h9rkZ7hwAyUdqzod4EogD9mIAp4UrMQemYgMkxPGwSKHN/1KjU
|
||||
70AcKDayNti8/sGbBig8w35Ju7YuJKWPDBiEFQIDAQABAoIBAAGZ53qGqazjDmwI
|
||||
u75LLJmSqAFjjlQ0KwQ215S0yHTtFRLZuX+BBtXdqpv2uCrqi8byvVQ4eCfYO8Wk
|
||||
Kqx804CL0AR8X1JBGJWiAEIOZNX1oZ2caZSiLD5k+utNiJF5aRzmb228PadXwwu4
|
||||
GRHtXXLmx9LGSG0xTTUPX3d+FIsacYTuukgp73JF2YhNl1N1ThwCZINcYjyfOBHK
|
||||
geDisw8yLIKLb5QCrMKWl1kS3Z6104JfBq00sjm3Yi7JjPfObepP9HXvUB8p0J6d
|
||||
QYeHnqqqr2AkUiUBNXSt6GaxW0Mc5E/mnVzPa+jrKlIe2bmmQZt/lHJZsLT6F4Q0
|
||||
OUdA2cECgYEAz6R7/B0VTLX4PdZ15vU4ao5bSxu3Gxe3IxVB1+PQLJklpBCc6npk
|
||||
akrrt3STYgiWG+Dcz3cD3SKVs9oei5t8s2Db83XVfsBRNFFf9GIVncNc1ia+cJ7/
|
||||
PDcLmmY1U0oByJr4xoyA4wYARuxS5MP3PljFoDCeaU4APX8GQgBgc7kCgYEA4WSn
|
||||
LNUVPAR8CMf3926LQsnu7z3y6HkgmX/txUspb7ji3X1+eL/yKhIKsDFPppAUc/Tn
|
||||
+W6ef7RtcZPFhA1HAiqvwvzAh6YUvnQ6NVzXqb1X73Ub1wf/kBK4pbuP9trOvR2f
|
||||
b95iIq6qt22uDYaeGBqR6VDOdRe5Sbavlmv++T0CgYEAjE2NRWZ1bPcMPOR7mEqc
|
||||
C0wTneWlTRYyNe94JSOXF3uH9psPHFUFItlq+vQ3XieFHmNLcJfvsW1cEEHTH+w5
|
||||
T4+kL5awYswaUqqllqDsEETgpwdY6QpWVl6vZW2onJXGLMGiVa68rCny5/lpbZCI
|
||||
sMUVDE+tymPdP7BkDxboFWkCgYEAwmf9pba41QaNMUnBgGKRrW7dLu+A57EqRBvK
|
||||
qwR0Xg/bZe2LO31b05uyKlyt9d2KNqYDu+oEveOTDobFs2t8VssYxJcbPSUr+UXo
|
||||
uwQ0ZAyTn0+kTqlwbgUnzJNlzibWcNnvHh9zB7UePI5WtQXqsKGiPtra6LYotALl
|
||||
mlnWF4UCgYEAjFJG9KRuIUe9IzXI2XxA22/seaji9qy7/ojHHlo9iwQeb/OPJyp4
|
||||
sCHS/qiMAfMU6r7OyOfnI51TsP3gr92/VKo/RoXn3mxCjFUXe3sIxsArOZ8f38DM
|
||||
ww46KDGHFemUCeycnbjoZcnqO1V8Vdj6FFENPuq0UxS7NW+4dcxlfJE=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC1jCCAcCgAwIBAgIRAOH/6qnnXARR27iWmrzfGAAwCwYJKoZIhvcNAQEFMBYx
|
||||
FDASBgNVBAoTC0Jvb3QyRG9ja2VyMB4XDTE0MDgwNTA3MDc1NFoXDTE3MDcyMDA3
|
||||
MDc1NFowFjEUMBIGA1UEChMLQm9vdDJEb2NrZXIwggEiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDwAwggEKAoIBAQC20TTRrgbvYOsUI5SHGV/GlMYKghqnBeVpMPfFSo2yMQ8i
|
||||
QGDh6BFYh8s1OEDz1JoWh7ScAfOm+ZXMPMuqJXV2VBkb01CO52YC7+VEFOnbowtC
|
||||
BP3KXvEW2HJM6aSTKxPDJLfTQNesyN7D2uN3uFziqrFOissjjuVm1k/F0aH6M+ug
|
||||
4pYqdUl9fDeF9GSn1jdMBquFxXxutF2XOiuhaDE8SJkRNGsCQYP6jgOYmjM4+gvo
|
||||
vTlkBDo8hjkhD6jLSH2uRnuHADJR2rOh3gSiAP2YgCnhSsxB6ZiAyTE8bBIoc3/U
|
||||
qNTvQBwoNrI22Lz+wZsGKDzDfkm7ti4kpY8MGIQVAgMBAAGjIzAhMA4GA1UdDwEB
|
||||
/wQEAwIApDAPBgNVHRMBAf8EBTADAQH/MAsGCSqGSIb3DQEBBQOCAQEAqtoYLEuU
|
||||
unbLo48zOHVSit3tIAnZ775HDy1WWK7zL1AzbB0WwT1nrB+SzR8lGzYmmPJB8sCH
|
||||
rHBPpCF8MNqpZI8NOkS4ZcLF+WJhcZRnIsSz64lzFQThu2rAK7fhheAo3ONZYAYJ
|
||||
DkZZrF7IMH3vMaQGZESBKuYiTstz+xMRTXxDQdgdpKZ1q2XB9wBeHLu6HRSh0cR4
|
||||
0Ehs+NCFj50JkgzrxdXgSOlrSk2Icztb1MH89CuRPZNEbJbd1cU/kekxtkLzDtmX
|
||||
Kai2FoHdonB1m5IfBJ7n2h5sexs73Qymohc4W81OZivdB/I+OixMjbc3Pn65KmWA
|
||||
foD/K4Atw1090w==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC+DCCAeKgAwIBAgIQHxTMkfKCDjxUR1lji0Hs/TALBgkqhkiG9w0BAQUwFjEU
|
||||
MBIGA1UEChMLQm9vdDJEb2NrZXIwHhcNMTQwODA1MDYwMTU0WhcNMTcwNzIwMDYw
|
||||
MTU0WjAWMRQwEgYDVQQKEwtCb290MkRvY2tlcjCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBALgW92LOxgrH59EoMJTsBDuKp2w2vOaY+WT4UduqxWTtPaQv
|
||||
aeGmK4/1T562prRIG/dH9IR/wYR3fYXKUkcHP6FaPTUnGEhUcnjg8vFMwoYnGLUo
|
||||
nCBK0HiZMPKkjnWzkiVJgdpQt3pLIRAomT0ehtP6LfMsrJoof8MCI+anu450hV/6
|
||||
VATtmxy8FnivfiLFlroolPXKp5kQck7nJBhsIOY4BDT8qgehGXtpJuqZaBrhCY2S
|
||||
7sAzIZtemWYFQNvwJDsMmsMNBMur4SwA/kST0kTlczH2vI423CeTa2PsrZmoFQvt
|
||||
whohfdLTH1Ul3bbtCPnDD2StkqUs9/JTigyEaj8CAwEAAaNGMEQwDgYDVR0PAQH/
|
||||
BAQDAgCgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDwYDVR0R
|
||||
BAgwBocEfwAAATALBgkqhkiG9w0BAQUDggEBAISM38fkqTAg5lP/fpgW6vmNNW+U
|
||||
VeQ/ZlXwQxzu+gmIli+PgPy/QM98xxs+SR3NwWTlh5yHDKHYPbmc1FRV5q8U1zvf
|
||||
DqDmyDEQTMCwWMOBRKwfGcmzV4WlZvxR96XQEpo0zfP61eMo7ditRraDD1PMBNGv
|
||||
4QqGJADKKHfqm53eS1tzd0MSBteah59OYLzF0hjXT/NL9P00XaotRznFmsjmura6
|
||||
0Xs6EKrudPTAdfCWBwundclq7d9BofU8/kBKwE8J7zCI6KA3fpGMutMojVIopIFO
|
||||
Bowka1TKV+2+8Nt1gqIvpvlX4E119BemIA/m9uZiSdYahffHniKBFiXsr8Y=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAvv7GjStV0fiOc1wf1hm2B3YGwTp6W0gCpYpOqEotetVOBf5c
|
||||
/9qbn4ihOZJK2GY69z6SchttmAL87EfhzFQjDifv0skjKHJkspyi80OJYeM+Tlj8
|
||||
4kHI3WXkD9K9UPO3JGkeNrTjOKIXbcQDOgYkDl6wYW6bdSIEyjxQ4+0jTZX0wYD4
|
||||
anSNJJXYA9UWq8B0GiwIrRF1378AjZzGyOuBhw1nj6AfAgsgVmNPu+Dh/5nteKEe
|
||||
HVz+iUOsiUmzZQ/4y+XxyFqe00+6gzF7dN18cRLatj9ifIsiSyEZUeF0vsqKyzG4
|
||||
HVG9o2R5uZoBOvyNMpUlxv9dVaSqCjHB3rELmwIDAQABAoIBAQCS6072lug8TXPe
|
||||
v3Xp7vs8QAkwKHiosPsANiUNhYn4nA6Zw7HsSlA95w8GR0d1sSYYvLRQPFMQhPPk
|
||||
GeNSl0IkCIqN3ZVC7sQRNTaP5FrQxspN4Fwe+7W0wUUu+tAQbnlp88Z/FKRZEy7s
|
||||
i8RjpQelWidZu4iwEMwYeU9MFUV7ztK5U+9NScu8d4svVbqZuBDrZiofBD++MYN4
|
||||
SvIzXCku+r67W2nN1a94/87MWGTUr8oGWbkvRIJ/23ifnvL7cQeqJ08VPr8BIj5w
|
||||
4su14xpITXEH02WpgTruEDrk2DO6wfoqAGJ/fZHRkDVIFSXd5miwurKQmL1Iursk
|
||||
FU98mPsBAoGBAOldZ9HDFX69+XGW4u80qkkaCHGrrKRDSHA1HfNEOu1nhyMD1vXW
|
||||
8xwOJ5H8yBrEMTSP2N8bdeEp8m/aKuleUpzIjxNyIbiw0m4v3p+lpbgEVKfC8L/B
|
||||
umU4HtRYgujvOfUFWEnvonQh9k1J/N5Ym93xXgs4WXzRG2ABeEmlsjGBAoGBANGF
|
||||
Ti2MdQYXf51Hgsw9oADiyEimbw6wEsLvK1sSA+lscTCyBdZyD+5PntnC5jcUtg1p
|
||||
moVFxHkyatVE3TffchTwjPgKAv0zKh3e6w9mJhRd1c9vNaTiIqPr0MyaftrZ1tSH
|
||||
DnAK8Lisd3zODaVawbPyOBPFfUnqWzYqIsPpWVMbAoGBAJOuWr8yV+4HR06NEDwU
|
||||
9hag9OsKm4ywT61C0Btc+HW46JpOGcEmMF92za/jarcVpZX/2l0GwcimhRgn1rQs
|
||||
ztcNTQ4fUhvROrokbRxW9dLIWtJ32WdgsBbSNyBmiyHiEqluonrXvdUEkRxEUFRd
|
||||
evYvgzZSiL8mjc5p37ertmMBAoGAWAuAsrtXYdv2EI3AdTtgRX8HUyA9gxqSh8Ah
|
||||
o/+KDUk4t5HXyincb/SdeDziqTrW1gQOnvqWeaeqJTzvCU+ojQwY8RKj9urNRAgt
|
||||
FyeB0QUtmCHPlR5CGEg8Uf6KWEU6dczbUFIInlI7VALy0Q22YHvk/Mn8wFbvRW+n
|
||||
dFRW6QkCgYEAtOoFUZSlJkU6LleX+M7dS6Jbd44SbCb+acirbl6eHKxEDLL2+MRM
|
||||
qZui45SqnCFnyWo8cgW4xqFeJVGoeTDFZK65Qup1IsBlrPODmTes5cSMPGdZ3brG
|
||||
BVCVcmuygGkMC/tGOmydVStZx0Spt0va96p/Na2x4akdscZKVTCCap4=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC4DCCAcqgAwIBAgIRAJ6X6zjqpxM03GqlIXCYtpIwCwYJKoZIhvcNAQEFMBYx
|
||||
FDASBgNVBAoTC0Jvb3QyRG9ja2VyMB4XDTE0MDgwNTA3MDc1OFoXDTE3MDcyMDA3
|
||||
MDc1OFowFjEUMBIGA1UEChMLQm9vdDJEb2NrZXIwggEiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDwAwggEKAoIBAQC+/saNK1XR+I5zXB/WGbYHdgbBOnpbSAKlik6oSi161U4F
|
||||
/lz/2pufiKE5kkrYZjr3PpJyG22YAvzsR+HMVCMOJ+/SySMocmSynKLzQ4lh4z5O
|
||||
WPziQcjdZeQP0r1Q87ckaR42tOM4ohdtxAM6BiQOXrBhbpt1IgTKPFDj7SNNlfTB
|
||||
gPhqdI0kldgD1RarwHQaLAitEXXfvwCNnMbI64GHDWePoB8CCyBWY0+74OH/me14
|
||||
oR4dXP6JQ6yJSbNlD/jL5fHIWp7TT7qDMXt03XxxEtq2P2J8iyJLIRlR4XS+yorL
|
||||
MbgdUb2jZHm5mgE6/I0ylSXG/11VpKoKMcHesQubAgMBAAGjLTArMA4GA1UdDwEB
|
||||
/wQEAwIAoDAMBgNVHRMBAf8EAjAAMAsGA1UdEQQEMAKCADALBgkqhkiG9w0BAQUD
|
||||
ggEBAKXqTtDj/F2AJj55trGsk/fc3LtYTOeq0I9JB45hNOjpixpBdsS1VxkxdTM5
|
||||
3wgUVEUyjQzBWtSBO5jRrDjOHsXqtqh83+Jh+GwUAf3mncGSss7JJ78kYe4zBxSi
|
||||
tgMc3KUi82ppoeiB0xsaEXfBRf6U+wJNVATpabJPeveMhaRVAd9gE5aLWrkZ09+b
|
||||
wR5y4YXZ0LncqWYnq03BAPn0eTDWgzJvXaSSyE9wFF847T9XRicwzsgTNXzqb4PU
|
||||
5s23GHfkIIv6PQzOUSpYTyCVWBdOk2qnhyUkeYCX+ZfwvJlb2NIwQjMwaysX6ZdJ
|
||||
T2q+prcDXnzOhwpsqUbTOD8RxOM=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,173 +0,0 @@
|
|||
// Usage:
|
||||
// Generate CA
|
||||
// ./generate_cert --cert ca.pem --key ca-key.pem
|
||||
// Generate signed certificate
|
||||
// ./generate_cert --host 127.0.0.1 --cert cert.pem --key key.pem --ca ca.pem --ca-key ca-key.pem
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"flag"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for")
|
||||
certFile = flag.String("cert", "", "Output file for certificate")
|
||||
keyFile = flag.String("key", "", "Output file for key")
|
||||
ca = flag.String("ca", "", "Certificate authority file to sign with")
|
||||
caKey = flag.String("ca-key", "", "Certificate authority key file to sign with")
|
||||
)
|
||||
|
||||
const (
|
||||
RSABITS = 2048
|
||||
VALIDFOR = 1080 * 24 * time.Hour
|
||||
ORG = "Boot2Docker"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *certFile == "" {
|
||||
log.Fatalf("Missing required parameter: --cert")
|
||||
}
|
||||
|
||||
if *keyFile == "" {
|
||||
log.Fatalf("Missing required parameter: --key")
|
||||
}
|
||||
|
||||
if *ca == "" {
|
||||
if *caKey != "" {
|
||||
log.Fatalf("Must provide both --ca and --ca-key")
|
||||
}
|
||||
if err := GenerateCA(*certFile, *keyFile); err != nil {
|
||||
log.Fatalf("Failured to generate CA: %s", err)
|
||||
}
|
||||
} else {
|
||||
if err := GenerateCert(strings.Split(*host, ","), *certFile, *keyFile, *ca, *caKey); err != nil {
|
||||
log.Fatalf("Failured to generate cert: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// newCertificate creates a new template
|
||||
func newCertificate() *x509.Certificate {
|
||||
notBefore := time.Now()
|
||||
notAfter := notBefore.Add(time.Hour * 24 * 1080)
|
||||
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to generate serial number: %s", err)
|
||||
}
|
||||
|
||||
return &x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{ORG},
|
||||
},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
//ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateCA generates a new certificate authority
|
||||
// and stores the resulting certificate and key file
|
||||
// in the arguments.
|
||||
func GenerateCA(certFile, keyFile string) error {
|
||||
template := newCertificate()
|
||||
template.IsCA = true
|
||||
template.KeyUsage |= x509.KeyUsageCertSign
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, RSABITS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
certOut, err := os.Create(certFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||
certOut.Close()
|
||||
|
||||
keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||||
keyOut.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateCert generates a new certificate signed using the provided
|
||||
// certificate authority files and stores the result in the certificate
|
||||
// file and key provided. The provided host names are set to the
|
||||
// appropriate certificate fields.
|
||||
func GenerateCert(hosts []string, certFile, keyFile, caFile, caKeyFile string) error {
|
||||
template := newCertificate()
|
||||
for _, h := range hosts {
|
||||
if ip := net.ParseIP(h); ip != nil {
|
||||
template.IPAddresses = append(template.IPAddresses, ip)
|
||||
} else {
|
||||
template.DNSNames = append(template.DNSNames, h)
|
||||
}
|
||||
}
|
||||
|
||||
tlsCert, err := tls.LoadX509KeyPair(caFile, caKeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, RSABITS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
x509Cert, err := x509.ParseCertificate(tlsCert.Certificate[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, template, x509Cert, &priv.PublicKey, tlsCert.PrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
certOut, err := os.Create(certFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||
certOut.Close()
|
||||
|
||||
keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||||
keyOut.Close()
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAuBb3Ys7GCsfn0SgwlOwEO4qnbDa85pj5ZPhR26rFZO09pC9p
|
||||
4aYrj/VPnramtEgb90f0hH/BhHd9hcpSRwc/oVo9NScYSFRyeODy8UzChicYtSic
|
||||
IErQeJkw8qSOdbOSJUmB2lC3ekshECiZPR6G0/ot8yysmih/wwIj5qe7jnSFX/pU
|
||||
BO2bHLwWeK9+IsWWuiiU9cqnmRByTuckGGwg5jgENPyqB6EZe2km6ploGuEJjZLu
|
||||
wDMhm16ZZgVA2/AkOwyaww0Ey6vhLAD+RJPSROVzMfa8jjbcJ5NrY+ytmagVC+3C
|
||||
GiF90tMfVSXdtu0I+cMPZK2SpSz38lOKDIRqPwIDAQABAoIBAC6B9tvqm1Pr7yAD
|
||||
RErLWcJlJCkNpymm6hLdPWj+usHlwdXx+JD+dzD2a7gQMwuG0DHn5tl2oUBDI94i
|
||||
ICk7ppKwBpigGN1lIEpzokzd9KMJy48xBEiQPhzJrvkOI8OOq1RqPrkV/VSTGHZJ
|
||||
m3U6ehuhr+wolC6aHrT4nHNQWu0BCqnLqbiwo1cDfH8bgKD+EF6uRZHuZOITFkY2
|
||||
rMhhI/gkVwVjDbyyJhIDALUkV3ovpZ4L+P9+8XJd7s6Y8gZjI9Ti2z8X2sUny4NS
|
||||
zbLuWYOaeHdFuGzTvFf48YNnB1sf8R/f/n3DkgDos+FkPLmTO0MNnXPmBB3R+B6R
|
||||
KzuLdikCgYEA85rRBuUsp3rNxxck4rNYIVg4/TcGUcQ959MrSadnB8QOJdBGUash
|
||||
XitPzHaAMYwsFAyb36qdhGtmqTQHtjYIl6alehN5g1g/clFceFu4riocdd/KKvVe
|
||||
qe6GagJx8BVDR8Oon61CRbi4/0LhYYfbf4ezN1PKbxlkfa5WMDtoH3MCgYEAwXTo
|
||||
7RH8ue9J5cSmtImX9Q3YVZy4gooYp4/teFX+da7cT2RbAsDoxFMY9Ka0ORHOFl1c
|
||||
74UIlqB2VdUhitgLWuqLhcaFFPyTbsJsuKi8RcP7sAA1YviweOsehBq7zpmaR7oF
|
||||
Ldb8It2W37PjIt1C2M5muyztd5FRLP63c5CnvwUCgYAK17g4C1lKdw/TrbcJlBv3
|
||||
F/spYhqY5xguSlrh416VnOdYTYXjuq84hsr9ecTI78lCdzE06l4qd7FRFKzHMm59
|
||||
eYBiB53f97yTNQXdoY99yQgNQxG3icZV3/UBoOw7WGbvOck2mjqZ6dfqHKr1cVuW
|
||||
uI6Ehuk6urGbWnghm3NN+wKBgQCkuSJYMleqDnkyvsZftUUBcP+CrkZhSKsDikbe
|
||||
jwJzPCf1JfNkndPUzxjRwFx2t5Vub6Lhg7ozX4BDR44fBiRtDocsqkPJAeObjMs8
|
||||
VNiy4tSdISBUHINPAoxiWc0OdrXqWxdr18GrAlkkM6y0lAgGSYEp4XB1vfOLx3t3
|
||||
WHWs7QKBgQCkTGUse1vFTfCzA5rTFzBWJM7bdaUCIymU2BQPbRFSgdx3kKbmnrab
|
||||
fOLOaVxMWAOAJ7PF1LlOyUlesLEJzqO+pYgRgnG3d6qz99Ytz3sk7uzVr3n/Ic68
|
||||
TwYlXLHGQmP7OyR2tMPVI0rSb5g5lbRdCOqMbHN+6ce10KcibdBF/g==
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAqS5MaKMuR9OWhPbGw/tc1JmJgtEtNp5dSx5hlPEkSY8dsi5Z
|
||||
uFZvCqYK7uaNUlap4/ytlFDIozOnZs+MrgcM5Ek/nPNtol+pts777H3Xo3oChRnc
|
||||
X1/JXQ1tdVTT//LvUJmtkg6V6+iORuMnTMpia+Sl+7cgdW3EElfzPMY8J9RIUPBE
|
||||
NyedJyp3K+RM/m+KOzmYqkHcrKhhblbjLOr5a0zu+D8ilCG87QDAUUf1gbXOUi/S
|
||||
CYH/9v20sUbPqHr8Z1wuJLeNvKPFrdC2+mtJyhqyMaH7tgsyKOmqeHxQlkNbril2
|
||||
tvZRAzqaTDDYMfJDKAwEk345CJW1avkk6GBc2wIDAQABAoIBAHJGn74eW2iQ958g
|
||||
weono/DHNSdz+8Jk/kd7YhalPAmj7j8pJ9loKOFcfw4YFWWEvIUPbIA+gQgcH/tG
|
||||
PpRelsqs35c4ptmDHLQq4+g+qKX4CDO34C9cGDwOkd0rS3gbtKMQ6zk5OPN8xn4D
|
||||
ecxY+FpAvA1nCTnIxyRM3DQ1AvUzSe+UpLtdc/vliCJiFVpAtpok6fVo/Cxevf51
|
||||
dU1BIgZcJjsmro2/GR7e7l4c0C+ZHV0Perkdfw1fqZvpj0u3ca1dfwuWUVGc7VYf
|
||||
v7D5aFH8tw5bGHdM2ajPn3mpgJ+BNuIOdG1ipiUmrv4NoWNmyd2on9+Jy+2tILOx
|
||||
dcPKqwECgYEAz5/Y6qUuhp+23t4hynbD1YCX4RZtwtuqUef7BxeaRSocQrK15zlZ
|
||||
iOYeZe7/F6b/ueuN9q64lQBy8HvtWphNifhaXAW7SVwrzNDnbZWFVaQB7+Srj53u
|
||||
/sOgEKDgi5LoEUH4aQV1prMyajWNGkBX0lmdGELkyisTvvsu/BN8S/sCgYEA0Jlp
|
||||
lO0rT5xUsM0EsQvPmgSz3/+bGEgmmNoBt2Fnp7JuVsfJQDujFUvi2tQ2seDbVupc
|
||||
+LSbPudIUIdPch450IGQSZFLiN7fAePMXIUdUuZ6amHEz6+dtdl+kjlzUmmE7/VP
|
||||
M/o8A0F0Qkn3LoU6yH8fesJ9p6JCzIpJSJuFfKECgYA0v32Sj4i0dxs0n+ah026J
|
||||
bXQooVQdb0VkLbWe5aYx8DLh1xlTt0RB/YS3jPKOBcVubKPSii0m3chVxIZWv97j
|
||||
MI90VZhxWNNf46sIMjZ/vX0of0X+5Lb1Tqn5z4V8sEP5LnN36wUq5tfmF9jTVIl7
|
||||
TX0Vztjla/BGUvZq4GBxxQKBgEyXN5QN7OwjK1lrPYDAJG6ZsW3ajRjCTSGsUhsB
|
||||
8aw6MJc+bd9exkdogJf2eUqglAh6rr5GmgXjp8KhnAL7pCCxocfRSFmt81XfTUbf
|
||||
PWAV7fanhTr4cUC25elMnNIymjP87yLXizdqzgQU4mQ7WNULEATj6n0lb79oOvYk
|
||||
3ENhAoGBAKjsl7MDi7WokpshGkEIPTxccefWPPx6wtdvDw1Yy6nrc/4KapsIvRZc
|
||||
u9r9GBEodxOFbuPKFqsTehpMuSMaWuPhHs6txP3/q1q58rpeqmXD29zcdDTuHJoS
|
||||
ZKqBPsot328/q38DwqavP9PZsuLQ/M95uXwYR4tnNnbbQwDqn61B
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC5DCCAc6gAwIBAgIRAL3D43hlFPxMmrICmKJjxn4wCwYJKoZIhvcNAQEFMBYx
|
||||
FDASBgNVBAoTC0Jvb3QyRG9ja2VyMB4XDTE0MDgwNTA3MTAwM1oXDTE3MDcyMDA3
|
||||
MTAwM1owFjEUMBIGA1UEChMLQm9vdDJEb2NrZXIwggEiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDwAwggEKAoIBAQCpLkxooy5H05aE9sbD+1zUmYmC0S02nl1LHmGU8SRJjx2y
|
||||
Llm4Vm8Kpgru5o1SVqnj/K2UUMijM6dmz4yuBwzkST+c822iX6m2zvvsfdejegKF
|
||||
GdxfX8ldDW11VNP/8u9Qma2SDpXr6I5G4ydMymJr5KX7tyB1bcQSV/M8xjwn1EhQ
|
||||
8EQ3J50nKncr5Ez+b4o7OZiqQdysqGFuVuMs6vlrTO74PyKUIbztAMBRR/WBtc5S
|
||||
L9IJgf/2/bSxRs+oevxnXC4kt428o8Wt0Lb6a0nKGrIxofu2CzIo6ap4fFCWQ1uu
|
||||
KXa29lEDOppMMNgx8kMoDASTfjkIlbVq+SToYFzbAgMBAAGjMTAvMA4GA1UdDwEB
|
||||
/wQEAwIAoDAMBgNVHRMBAf8EAjAAMA8GA1UdEQQIMAaHBMCoO2gwCwYJKoZIhvcN
|
||||
AQEFA4IBAQC0ttuFbfSrzGdDcO/442nfpzQdO9wN0nee5OazHHTZlA+SaQ4VyZoS
|
||||
LeCdP+rRPIX0qmJ0Bf95nvkL7Mideg6IQsTTWz3e2pfcIdSZ1Gc9Bzx4cGf2yWWt
|
||||
mwi2uLAbAOKznNh8Ndc45zG614QYo3Cli/p91y+zJyDhS3ucERGCwC9ru+ngHBp4
|
||||
KrAfH4AUNRi5JRt0vHn3MXbl8Xmymt5FHeOtEM9iXCFBMtejYcngceOz8bRPXke2
|
||||
86TExl86jIHjAItEqydANhG7wNIylNOdXGCgQ4yQX1ImNiY2I4n7FeLh8vu8nCbR
|
||||
zwPv/s2m4xsr4ilA6xLq9Ur8K7FK4Q4a
|
||||
-----END CERTIFICATE-----
|
Binary file not shown.
9
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/ca.pem
generated
vendored
9
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/ca.pem
generated
vendored
|
@ -1,9 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBNTCB3KADAgECAgEAMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMTB0NBIFJvb3Qw
|
||||
HhcNMTQwOTIyMTYzNzU4WhcNMTQwOTI5MTYzNzU5WjASMRAwDgYDVQQDEwdDQSBS
|
||||
b290MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEaS6UJn72kZaD1U1+9wXVFtk/
|
||||
lqSOzq+snB6qslXpLE2C+6N1NjDoivZ87CPzJt6VYgeS+iZ63+AlH5Uiz+q1SKMj
|
||||
MCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwID
|
||||
SAAwRQIhALxyd72Aev/IAvXZpx7TLbLrGMrZGTEMjXMi1Gda9MAFAiA82SUmu3dR
|
||||
9d0VWY74lOlHsojsoi3keb4PeOMyyFFFaQ==
|
||||
-----END CERTIFICATE-----
|
10
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/cert.pem
generated
vendored
10
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/cert.pem
generated
vendored
|
@ -1,10 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBPTCB5KADAgECAgEAMAoGCCqGSM49BAMCMBcxFTATBgNVBAMTDEludGVybWVk
|
||||
aWF0ZTAeFw0xNDA5MjIxNjM3NThaFw0xNDA5MjkxNjM3NTlaMBUxEzARBgNVBAMT
|
||||
ClRydXN0IENlcnQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASR+jpYA6SPRkq+
|
||||
2B9FH23Qrqgsn2ScgfiU73PN9Kgn0xyStp2RHoDhyKoQKU5T1TPOdWxVan3+ljUx
|
||||
/O/1pKdSoyMwITAOBgNVHQ8BAf8EBAMCAIAwDwYDVR0TAQH/BAUwAwEB/zAKBggq
|
||||
hkjOPQQDAgNIADBFAiEA2NpSs22EiYwbZlkjcVuAryJlBbnRzYvX7IIkk9fSRYQC
|
||||
IH4YfZC3tvUWFxc4Spvic2uCHazAu+0Fzjs53OJxwirZ
|
||||
-----END CERTIFICATE-----
|
||||
---
|
45
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/chain.pem
generated
vendored
45
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/chain.pem
generated
vendored
|
@ -1,45 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBPzCB5qADAgECAgEAMAoGCCqGSM49BAMCMBcxFTATBgNVBAMTDEludGVybWVk
|
||||
aWF0ZTAeFw0xNDA5MjIxNjM3NThaFw0xNDA5MjkxNjM3NTlaMBcxFTATBgNVBAMT
|
||||
DEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABMac+uvHxGGH
|
||||
xCisqvN5+ZO6w9Q3BlPXu5r2GVXmo07DX15Dj894S4ByNMo8iluDyqK/8JS/1cq1
|
||||
S+Q0CE6yRw6jIzAhMA4GA1UdDwEB/wQEAwIABjAPBgNVHRMBAf8EBTADAQH/MAoG
|
||||
CCqGSM49BAMCA0gAMEUCIDHx2NPcyo4JiBKFRdCZiLTyncBDJIlWzOhprFbmm914
|
||||
AiEAjbxeVHWiO+Q/7nzQXpGzsnszaMdmL1LLSQuTf9MX+bc=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBPzCB5qADAgECAgEAMAoGCCqGSM49BAMCMBcxFTATBgNVBAMTDEludGVybWVk
|
||||
aWF0ZTAeFw0xNDA5MjIxNjM3NThaFw0xNDA5MjkxNjM3NTlaMBcxFTATBgNVBAMT
|
||||
DEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJJo+KFt18Og
|
||||
0hbUmxnxBTBHg0FIxlWJMac1iNnqlH6hnPZf1a1uJJm/iNZNPxd+jHh+ZjInvTmU
|
||||
Fg7DiDXiyuOjIzAhMA4GA1UdDwEB/wQEAwIABjAPBgNVHRMBAf8EBTADAQH/MAoG
|
||||
CCqGSM49BAMCA0gAMEUCIHGyXQESb6pph5gz4ppgfD4br9F5TYM2/Fap+IK1Jhm1
|
||||
AiEAxamUnj4AWIHut2T5R3Xg2tn0q5JDtsB3drZ/MXoMepI=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBPzCB5qADAgECAgEAMAoGCCqGSM49BAMCMBcxFTATBgNVBAMTDEludGVybWVk
|
||||
aWF0ZTAeFw0xNDA5MjIxNjM3NThaFw0xNDA5MjkxNjM3NTlaMBcxFTATBgNVBAMT
|
||||
DEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNIvT/bkf6rm
|
||||
RYNE5e53izqdm9HHSBXlSFQGWShDrmYmlJbJrzE7gdd6dWMaTi3TzUGJzVcvASNJ
|
||||
/tkZZW2uMaKjIzAhMA4GA1UdDwEB/wQEAwIABjAPBgNVHRMBAf8EBTADAQH/MAoG
|
||||
CCqGSM49BAMCA0gAMEUCIQCYu0lvqmvj+99qiyOc/vJWhT/oIKUu+h8dIU3bULt1
|
||||
AwIgKiMptAa9IJfXa+VvleIdWpdldJa5g1OvRaP+ANQ/MGA=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBPjCB5qADAgECAgEAMAoGCCqGSM49BAMCMBcxFTATBgNVBAMTDEludGVybWVk
|
||||
aWF0ZTAeFw0xNDA5MjIxNjM3NThaFw0xNDA5MjkxNjM3NTlaMBcxFTATBgNVBAMT
|
||||
DEludGVybWVkaWF0ZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKx0nRr6QlXX
|
||||
xYLe1+BmJkI3moUdYxJr/6xfhnqJTPhk7UR8/h69BlAX7PE5Cp1j7q4bCoAAdARN
|
||||
csjpOKn1tpOjIzAhMA4GA1UdDwEB/wQEAwIABjAPBgNVHRMBAf8EBTADAQH/MAoG
|
||||
CCqGSM49BAMCA0cAMEQCIConoQP4XuaCoobZD3v0t0/WROD/wVDUBu5xILa8sSKe
|
||||
AiBJCWa8cXi2U6z6cc/RKcRaDOTmL+1Cs38aRUiU/+VCPw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBOjCB4aADAgECAgEAMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMTB0NBIFJvb3Qw
|
||||
HhcNMTQwOTIyMTYzNzU4WhcNMTQwOTI5MTYzNzU5WjAXMRUwEwYDVQQDEwxJbnRl
|
||||
cm1lZGlhdGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQsGtLo05ztLyhrzzMu
|
||||
bziiYR7Y1qxhm6DlV9kaa7DHyuLpNOsEKNkW6gx/9g1AxVfDv2dcuoqnCErawdab
|
||||
+jgDoyMwITAOBgNVHQ8BAf8EBAMCAAYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjO
|
||||
PQQDAgNIADBFAiEAy+WumOj7I8iIhQNf+NQfV+LNBBoy4ufeeyaPGcRG3hICIFMW
|
||||
th+PDs1HgdeQvG1tPP9d7TBfMu7k1lVlCf7KcvKN
|
||||
-----END CERTIFICATE-----
|
BIN
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/generatecerts
generated
vendored
BIN
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/generatecerts
generated
vendored
Binary file not shown.
5
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/key.pem
generated
vendored
5
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/key.pem
generated
vendored
|
@ -1,5 +0,0 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIDmjTNf5Q5kuGCFrfsa60qLUKZDoSuIgS+GKOb9vRWFJoAoGCCqGSM49
|
||||
AwEHoUQDQgAEkfo6WAOkj0ZKvtgfRR9t0K6oLJ9knIH4lO9zzfSoJ9MckradkR6A
|
||||
4ciqEClOU9UzznVsVWp9/pY1Mfzv9aSnUg==
|
||||
-----END EC PRIVATE KEY-----
|
161
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/main.go
generated
vendored
161
Godeps/_workspace/src/github.com/docker/libtrust/chainsign/generatecerts/main.go
generated
vendored
|
@ -1,161 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"log"
|
||||
"math/big"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
func generateTrustCA() (libtrust.PrivateKey, *x509.Certificate) {
|
||||
key, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cert := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "CA Root",
|
||||
},
|
||||
NotBefore: time.Now().Add(-time.Second),
|
||||
NotAfter: time.Now().Add(24 * 7 * time.Hour),
|
||||
IsCA: true,
|
||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(
|
||||
rand.Reader, cert, cert,
|
||||
key.CryptoPublicKey(), key.CryptoPrivateKey(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return key, cert
|
||||
}
|
||||
|
||||
func generateIntermediate(key libtrust.PublicKey, parentKey libtrust.PrivateKey, parent *x509.Certificate) *x509.Certificate {
|
||||
cert := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Intermediate",
|
||||
},
|
||||
NotBefore: time.Now().Add(-time.Second),
|
||||
NotAfter: time.Now().Add(24 * 7 * time.Hour),
|
||||
IsCA: true,
|
||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(
|
||||
rand.Reader, cert, parent,
|
||||
key.CryptoPublicKey(), parentKey.CryptoPrivateKey(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return cert
|
||||
}
|
||||
|
||||
func generateTrustCert(key libtrust.PublicKey, parentKey libtrust.PrivateKey, parent *x509.Certificate) *x509.Certificate {
|
||||
cert := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Trust Cert",
|
||||
},
|
||||
NotBefore: time.Now().Add(-time.Second),
|
||||
NotAfter: time.Now().Add(24 * 7 * time.Hour),
|
||||
IsCA: true,
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(
|
||||
rand.Reader, cert, parent,
|
||||
key.CryptoPublicKey(), parentKey.CryptoPrivateKey(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return cert
|
||||
}
|
||||
|
||||
func generateTrustChain(key libtrust.PrivateKey, ca *x509.Certificate) (libtrust.PrivateKey, []*x509.Certificate) {
|
||||
parent := ca
|
||||
parentKey := key
|
||||
chain := make([]*x509.Certificate, 6)
|
||||
for i := 5; i > 0; i-- {
|
||||
intermediatekey, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
chain[i] = generateIntermediate(intermediatekey, parentKey, parent)
|
||||
parent = chain[i]
|
||||
parentKey = intermediatekey
|
||||
}
|
||||
trustKey, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
chain[0] = generateTrustCert(trustKey, parentKey, parent)
|
||||
|
||||
return trustKey, chain
|
||||
}
|
||||
|
||||
func main() {
|
||||
caKey, caCert := generateTrustCA()
|
||||
key, chain := generateTrustChain(caKey, caCert)
|
||||
|
||||
caf, err := os.OpenFile("ca.pem", os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
log.Fatalf("Error opening ca.pem: %s", err)
|
||||
}
|
||||
defer caf.Close()
|
||||
pem.Encode(caf, &pem.Block{Type: "CERTIFICATE", Bytes: caCert.Raw})
|
||||
|
||||
chainf, err := os.OpenFile("chain.pem", os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
log.Fatalf("Error opening ca.pem: %s", err)
|
||||
}
|
||||
defer chainf.Close()
|
||||
for _, c := range chain[1:] {
|
||||
pem.Encode(chainf, &pem.Block{Type: "CERTIFICATE", Bytes: c.Raw})
|
||||
}
|
||||
|
||||
certf, err := os.OpenFile("cert.pem", os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
log.Fatalf("Error opening ca.pem: %s", err)
|
||||
}
|
||||
defer certf.Close()
|
||||
pem.Encode(certf, &pem.Block{Type: "CERTIFICATE", Bytes: chain[0].Raw})
|
||||
|
||||
err = libtrust.SaveKey("key.pem", key)
|
||||
if err != nil {
|
||||
log.Fatalf("Error saving key: %s", err)
|
||||
}
|
||||
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL derek
|
|
@ -1,184 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
var ca string
|
||||
var chain string
|
||||
var cert string
|
||||
var signKey string
|
||||
var validKeys string
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&ca, "ca", "", "Certificate authorities (pem file)")
|
||||
flag.StringVar(&chain, "chain", "", "Certificate chain to include (pem file)")
|
||||
flag.StringVar(&cert, "cert", "", "Certificate used to sign")
|
||||
flag.StringVar(&signKey, "k", "", "Private key to use for signing (pem or JWS file)")
|
||||
flag.StringVar(&validKeys, "keys", "", "File containing list of valid keys and namespaces")
|
||||
}
|
||||
|
||||
func LoadValidKeys(filename string) (map[string][]string, error) {
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
validKeys := make(map[string][]string)
|
||||
r := bufio.NewScanner(f)
|
||||
for r.Scan() {
|
||||
parts := strings.Split(r.Text(), " ")
|
||||
if len(parts) < 2 {
|
||||
return nil, errors.New("Invalid line input: expecting <KeyId> <namespace> ...")
|
||||
}
|
||||
validKeys[parts[0]] = parts[1:]
|
||||
}
|
||||
return validKeys, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if ca == "" {
|
||||
log.Fatal("Missing ca")
|
||||
}
|
||||
if chain == "" {
|
||||
log.Fatalf("Missing chain")
|
||||
}
|
||||
if cert == "" {
|
||||
log.Fatalf("Missing certificate")
|
||||
}
|
||||
if signKey == "" {
|
||||
log.Fatalf("Missing key")
|
||||
}
|
||||
if validKeys == "" {
|
||||
log.Fatalf("Missing valid keys")
|
||||
}
|
||||
|
||||
caPool, err := libtrust.LoadCertificatePool(ca)
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading ca certs: %s", err)
|
||||
}
|
||||
|
||||
chainCerts, err := libtrust.LoadCertificateBundle(chain)
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading chain certificates; %s", err)
|
||||
}
|
||||
chainPool := x509.NewCertPool()
|
||||
for _, cert := range chainCerts {
|
||||
chainPool.AddCert(cert)
|
||||
}
|
||||
|
||||
signCert, err := tls.LoadX509KeyPair(cert, signKey)
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading key: %s", err)
|
||||
}
|
||||
if signCert.Certificate == nil {
|
||||
log.Fatalf("Signed Cert is empty")
|
||||
}
|
||||
|
||||
validKeyMap, err := LoadValidKeys(validKeys)
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading valid keys: %s", err)
|
||||
}
|
||||
|
||||
verifyOptions := x509.VerifyOptions{
|
||||
Intermediates: chainPool,
|
||||
Roots: caPool,
|
||||
}
|
||||
|
||||
parsedCert, err := x509.ParseCertificate(signCert.Certificate[0])
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing certificate: %s", err)
|
||||
}
|
||||
|
||||
chains, err := parsedCert.Verify(verifyOptions)
|
||||
if err != nil {
|
||||
log.Fatalf("Error verifying certificate: %s", err)
|
||||
}
|
||||
if len(chains) == 0 {
|
||||
log.Fatalf("No verified chains")
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading content from stdin: %s", err)
|
||||
}
|
||||
|
||||
sig, err := libtrust.ParsePrettySignature(content, "signatures")
|
||||
|
||||
buildKeys, err := sig.Verify()
|
||||
if err != nil {
|
||||
log.Fatalf("Error verifying signatures: %s", err)
|
||||
}
|
||||
|
||||
type manifest struct {
|
||||
Name string `json:"name"`
|
||||
Tag string `json:"tag"`
|
||||
}
|
||||
var buildManifest manifest
|
||||
payload, err := sig.Payload()
|
||||
if err != nil {
|
||||
log.Fatalf("Error retrieving payload: %s", err)
|
||||
}
|
||||
err = json.Unmarshal(payload, &buildManifest)
|
||||
if err != nil {
|
||||
log.Fatalf("Error unmarshalling build manifest: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("Build keys: %#v", buildKeys)
|
||||
// Check keys against list of valid keys
|
||||
var foundKey bool
|
||||
for _, key := range buildKeys {
|
||||
keyID := key.KeyID()
|
||||
log.Printf("Checking key id: %s", keyID)
|
||||
namespaces, ok := validKeyMap[keyID]
|
||||
if ok {
|
||||
for _, namespace := range namespaces {
|
||||
if namespace == "*" || strings.HasPrefix(buildManifest.Name, namespace) {
|
||||
foundKey = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if !foundKey {
|
||||
log.Fatalf("No valid key found for build")
|
||||
}
|
||||
|
||||
verifiedSig, err := libtrust.NewJSONSignature(content)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating JSON signature: %s", err)
|
||||
}
|
||||
|
||||
privKey, err := libtrust.FromCryptoPrivateKey(signCert.PrivateKey)
|
||||
if err != nil {
|
||||
log.Fatalf("Error converting priv key: %s", err)
|
||||
}
|
||||
signChain := make([]*x509.Certificate, 1, len(chainCerts)+1)
|
||||
signChain[0] = parsedCert
|
||||
err = verifiedSig.SignWithChain(privKey, append(signChain, chainCerts...))
|
||||
if err != nil {
|
||||
log.Fatalf("Error signing with chain: %s", err)
|
||||
}
|
||||
|
||||
// Output signed content to stdout
|
||||
out, err := verifiedSig.PrettySignature("verifySignatures")
|
||||
if err != nil {
|
||||
log.Fatalf("Error formatting output: %s", err)
|
||||
}
|
||||
_, err = os.Stdout.Write(out)
|
||||
if err != nil {
|
||||
log.Fatalf("Error writing output: %s", err)
|
||||
}
|
||||
}
|
|
@ -1,599 +0,0 @@
|
|||
mode: set
|
||||
github.com/docker/libtrust/jsonsign.go:53.40,57.2 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:61.52,63.2 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:65.60,72.16 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:76.2,76.49 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:72.16,74.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:79.76,85.2 5 1
|
||||
github.com/docker/libtrust/jsonsign.go:88.53,90.16 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:93.2,94.16 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:97.2,98.16 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:102.2,114.12 4 1
|
||||
github.com/docker/libtrust/jsonsign.go:90.16,92.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:94.16,96.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:98.16,100.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:120.89,127.16 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:130.2,131.16 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:134.2,135.16 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:139.2,144.29 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:148.2,156.12 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:127.16,129.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:131.16,133.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:135.16,137.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:144.29,146.3 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:161.56,163.42 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:200.2,200.18 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:163.42,165.17 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:168.3,169.38 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:188.3,189.17 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:193.3,194.17 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:198.3,198.22 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:165.17,167.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:169.38,171.18 2 0
|
||||
github.com/docker/libtrust/jsonsign.go:174.4,175.18 2 0
|
||||
github.com/docker/libtrust/jsonsign.go:178.4,179.18 2 0
|
||||
github.com/docker/libtrust/jsonsign.go:171.18,173.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:175.18,177.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:179.18,181.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:182.5,182.41 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:182.41,184.4 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:184.5,186.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:189.17,191.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:194.17,196.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:206.89,208.42 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:266.2,266.20 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:208.42,210.17 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:213.3,214.38 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:210.17,212.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:214.38,216.18 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:219.4,220.18 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:223.4,224.18 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:227.4,228.39 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:243.4,249.18 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:252.4,255.18 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:259.4,260.18 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:216.18,218.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:220.18,222.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:224.18,226.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:228.39,230.38 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:230.38,232.20 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:235.6,236.20 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:239.6,239.41 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:232.20,234.7 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:236.20,238.7 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:249.18,251.5 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:255.18,257.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:260.18,262.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:271.48,272.29 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:275.2,280.47 2 0
|
||||
github.com/docker/libtrust/jsonsign.go:272.29,274.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:283.28,285.2 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:287.59,288.77 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:294.2,294.8 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:288.77,290.21 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:290.21,292.4 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:310.55,317.16 4 0
|
||||
github.com/docker/libtrust/jsonsign.go:320.2,320.33 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:323.2,324.16 2 0
|
||||
github.com/docker/libtrust/jsonsign.go:328.2,329.16 2 0
|
||||
github.com/docker/libtrust/jsonsign.go:332.2,333.46 2 0
|
||||
github.com/docker/libtrust/jsonsign.go:354.2,354.16 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:317.16,319.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:320.33,322.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:324.16,326.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:329.16,331.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:333.46,337.36 2 0
|
||||
github.com/docker/libtrust/jsonsign.go:340.3,340.34 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:347.3,351.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:337.36,339.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:340.34,342.18 2 0
|
||||
github.com/docker/libtrust/jsonsign.go:345.4,345.26 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:342.18,344.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:359.63,362.16 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:366.2,373.32 5 1
|
||||
github.com/docker/libtrust/jsonsign.go:376.2,377.35 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:380.2,383.16 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:362.16,364.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:373.32,375.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:377.35,379.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:388.75,389.24 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:396.2,400.16 4 1
|
||||
github.com/docker/libtrust/jsonsign.go:403.2,409.16 4 1
|
||||
github.com/docker/libtrust/jsonsign.go:390.2,390.30 0 1
|
||||
github.com/docker/libtrust/jsonsign.go:391.2,391.16 0 0
|
||||
github.com/docker/libtrust/jsonsign.go:392.2,393.46 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:400.16,402.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:412.71,414.9 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:417.2,417.27 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:414.9,416.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:418.2,419.17 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:420.2,421.22 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:422.2,423.18 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:427.82,429.9 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:432.2,433.8 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:429.9,431.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:440.88,443.16 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:446.2,447.9 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:451.2,453.16 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:457.2,460.49 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:511.2,511.36 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:514.2,520.16 6 1
|
||||
github.com/docker/libtrust/jsonsign.go:443.16,445.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:447.9,449.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:453.16,455.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:460.49,462.17 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:465.3,467.17 3 1
|
||||
github.com/docker/libtrust/jsonsign.go:471.3,472.10 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:475.3,476.10 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:479.3,480.17 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:483.3,483.27 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:488.3,488.30 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:494.3,498.39 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:505.3,509.4 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:462.17,464.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:467.17,469.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:472.10,474.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:476.10,478.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:480.17,482.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:483.27,485.4 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:485.5,485.45 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:485.45,487.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:488.30,490.4 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:490.5,490.59 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:490.59,492.4 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:498.39,500.18 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:503.4,503.26 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:500.18,502.5 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:511.36,513.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:525.79,526.29 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:529.2,530.16 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:533.2,537.21 4 1
|
||||
github.com/docker/libtrust/jsonsign.go:542.2,542.24 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:546.2,549.21 4 1
|
||||
github.com/docker/libtrust/jsonsign.go:563.2,565.25 2 1
|
||||
github.com/docker/libtrust/jsonsign.go:526.29,528.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:530.16,532.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:537.21,539.3 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:539.4,541.3 1 1
|
||||
github.com/docker/libtrust/jsonsign.go:542.24,544.3 1 0
|
||||
github.com/docker/libtrust/jsonsign.go:549.21,557.3 7 1
|
||||
github.com/docker/libtrust/jsonsign.go:557.4,562.3 4 1
|
||||
github.com/docker/libtrust/key.go:71.79,72.51 1 1
|
||||
github.com/docker/libtrust/key.go:73.2,74.42 1 1
|
||||
github.com/docker/libtrust/key.go:75.2,76.48 1 1
|
||||
github.com/docker/libtrust/key.go:77.2,78.81 1 0
|
||||
github.com/docker/libtrust/key.go:85.83,86.53 1 1
|
||||
github.com/docker/libtrust/key.go:87.2,88.44 1 1
|
||||
github.com/docker/libtrust/key.go:89.2,90.50 1 1
|
||||
github.com/docker/libtrust/key.go:91.2,92.83 1 0
|
||||
github.com/docker/libtrust/key.go:98.60,100.21 2 1
|
||||
github.com/docker/libtrust/key.go:106.2,106.37 1 1
|
||||
github.com/docker/libtrust/key.go:100.21,102.3 1 0
|
||||
github.com/docker/libtrust/key.go:102.4,102.42 1 1
|
||||
github.com/docker/libtrust/key.go:102.42,104.3 1 0
|
||||
github.com/docker/libtrust/key.go:112.68,115.6 2 1
|
||||
github.com/docker/libtrust/key.go:132.2,132.21 1 1
|
||||
github.com/docker/libtrust/key.go:115.6,118.22 3 1
|
||||
github.com/docker/libtrust/key.go:124.3,125.17 2 1
|
||||
github.com/docker/libtrust/key.go:129.3,129.36 1 1
|
||||
github.com/docker/libtrust/key.go:118.22,119.9 1 1
|
||||
github.com/docker/libtrust/key.go:120.5,120.43 1 1
|
||||
github.com/docker/libtrust/key.go:120.43,122.4 1 0
|
||||
github.com/docker/libtrust/key.go:125.17,127.4 1 0
|
||||
github.com/docker/libtrust/key.go:137.62,139.21 2 1
|
||||
github.com/docker/libtrust/key.go:143.2,145.9 2 1
|
||||
github.com/docker/libtrust/key.go:165.2,167.17 2 1
|
||||
github.com/docker/libtrust/key.go:139.21,141.3 1 0
|
||||
github.com/docker/libtrust/key.go:146.2,148.17 2 1
|
||||
github.com/docker/libtrust/key.go:151.3,151.41 1 1
|
||||
github.com/docker/libtrust/key.go:152.2,154.17 2 1
|
||||
github.com/docker/libtrust/key.go:157.3,158.17 2 1
|
||||
github.com/docker/libtrust/key.go:161.2,162.86 1 0
|
||||
github.com/docker/libtrust/key.go:148.17,150.4 1 0
|
||||
github.com/docker/libtrust/key.go:154.17,156.4 1 0
|
||||
github.com/docker/libtrust/key.go:158.17,160.4 1 0
|
||||
github.com/docker/libtrust/key.go:172.60,176.16 3 1
|
||||
github.com/docker/libtrust/key.go:183.2,184.16 2 1
|
||||
github.com/docker/libtrust/key.go:188.2,188.9 1 1
|
||||
github.com/docker/libtrust/key.go:176.16,180.3 1 0
|
||||
github.com/docker/libtrust/key.go:184.16,186.3 1 0
|
||||
github.com/docker/libtrust/key.go:189.2,191.33 1 1
|
||||
github.com/docker/libtrust/key.go:192.2,194.34 1 1
|
||||
github.com/docker/libtrust/key.go:195.2,198.4 1 0
|
||||
github.com/docker/libtrust/key.go:204.65,206.16 2 1
|
||||
github.com/docker/libtrust/key.go:210.2,212.33 2 1
|
||||
github.com/docker/libtrust/key.go:220.2,220.21 1 1
|
||||
github.com/docker/libtrust/key.go:206.16,208.3 1 0
|
||||
github.com/docker/libtrust/key.go:212.33,214.17 2 1
|
||||
github.com/docker/libtrust/key.go:217.3,217.36 1 1
|
||||
github.com/docker/libtrust/key.go:214.17,216.4 1 0
|
||||
github.com/docker/libtrust/key.go:225.62,229.16 3 1
|
||||
github.com/docker/libtrust/key.go:236.2,237.16 2 1
|
||||
github.com/docker/libtrust/key.go:241.2,241.9 1 1
|
||||
github.com/docker/libtrust/key.go:229.16,233.3 1 0
|
||||
github.com/docker/libtrust/key.go:237.16,239.3 1 0
|
||||
github.com/docker/libtrust/key.go:242.2,244.34 1 1
|
||||
github.com/docker/libtrust/key.go:245.2,247.35 1 1
|
||||
github.com/docker/libtrust/key.go:248.2,251.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:18.56,20.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:30.2,30.18 1 1
|
||||
github.com/docker/libtrust/key_files.go:20.16,21.25 1 1
|
||||
github.com/docker/libtrust/key_files.go:27.3,27.18 1 1
|
||||
github.com/docker/libtrust/key_files.go:21.25,23.4 1 1
|
||||
github.com/docker/libtrust/key_files.go:23.5,25.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:39.55,41.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:45.2,47.81 2 1
|
||||
github.com/docker/libtrust/key_files.go:59.2,59.17 1 1
|
||||
github.com/docker/libtrust/key_files.go:41.16,43.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:47.81,49.17 2 1
|
||||
github.com/docker/libtrust/key_files.go:49.17,51.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:52.4,54.17 2 1
|
||||
github.com/docker/libtrust/key_files.go:54.17,56.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:64.60,66.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:70.2,72.81 2 1
|
||||
github.com/docker/libtrust/key_files.go:84.2,84.17 1 1
|
||||
github.com/docker/libtrust/key_files.go:66.16,68.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:72.81,74.17 2 1
|
||||
github.com/docker/libtrust/key_files.go:74.17,76.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:77.4,79.17 2 1
|
||||
github.com/docker/libtrust/key_files.go:79.17,81.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:89.53,93.81 3 1
|
||||
github.com/docker/libtrust/key_files.go:108.2,109.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:113.2,113.12 1 1
|
||||
github.com/docker/libtrust/key_files.go:93.81,96.17 2 1
|
||||
github.com/docker/libtrust/key_files.go:96.17,98.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:99.4,102.17 2 1
|
||||
github.com/docker/libtrust/key_files.go:105.3,105.44 1 1
|
||||
github.com/docker/libtrust/key_files.go:102.17,104.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:109.16,111.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:117.58,121.81 3 1
|
||||
github.com/docker/libtrust/key_files.go:136.2,137.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:141.2,141.12 1 1
|
||||
github.com/docker/libtrust/key_files.go:121.81,124.17 2 1
|
||||
github.com/docker/libtrust/key_files.go:124.17,126.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:127.4,130.17 2 1
|
||||
github.com/docker/libtrust/key_files.go:133.3,133.44 1 1
|
||||
github.com/docker/libtrust/key_files.go:130.17,132.4 1 0
|
||||
github.com/docker/libtrust/key_files.go:137.16,139.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:151.59,152.81 1 1
|
||||
github.com/docker/libtrust/key_files.go:157.2,157.36 1 1
|
||||
github.com/docker/libtrust/key_files.go:152.81,154.3 1 1
|
||||
github.com/docker/libtrust/key_files.go:160.64,161.20 1 1
|
||||
github.com/docker/libtrust/key_files.go:166.2,169.16 3 1
|
||||
github.com/docker/libtrust/key_files.go:173.2,173.25 1 1
|
||||
github.com/docker/libtrust/key_files.go:161.20,164.3 1 1
|
||||
github.com/docker/libtrust/key_files.go:169.16,171.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:176.63,178.49 2 1
|
||||
github.com/docker/libtrust/key_files.go:182.2,182.43 1 1
|
||||
github.com/docker/libtrust/key_files.go:178.49,180.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:185.62,187.49 2 1
|
||||
github.com/docker/libtrust/key_files.go:191.2,191.42 1 1
|
||||
github.com/docker/libtrust/key_files.go:187.49,189.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:195.58,196.81 1 1
|
||||
github.com/docker/libtrust/key_files.go:201.2,201.40 1 1
|
||||
github.com/docker/libtrust/key_files.go:196.81,198.3 1 1
|
||||
github.com/docker/libtrust/key_files.go:204.62,206.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:210.2,211.49 2 1
|
||||
github.com/docker/libtrust/key_files.go:215.2,216.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:220.2,224.16 4 1
|
||||
github.com/docker/libtrust/key_files.go:228.2,229.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:233.2,233.12 1 1
|
||||
github.com/docker/libtrust/key_files.go:206.16,208.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:211.49,213.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:216.16,218.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:224.16,226.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:229.16,231.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:236.61,239.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:242.2,245.16 3 1
|
||||
github.com/docker/libtrust/key_files.go:249.2,250.16 2 1
|
||||
github.com/docker/libtrust/key_files.go:254.2,254.12 1 1
|
||||
github.com/docker/libtrust/key_files.go:239.16,241.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:245.16,247.3 1 0
|
||||
github.com/docker/libtrust/key_files.go:250.16,252.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:26.69,28.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:31.41,33.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:36.39,47.2 5 1
|
||||
github.com/docker/libtrust/rsa_key.go:49.40,51.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:57.83,60.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:64.2,66.16 3 1
|
||||
github.com/docker/libtrust/rsa_key.go:69.2,72.16 3 1
|
||||
github.com/docker/libtrust/rsa_key.go:76.2,76.12 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:60.16,62.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:66.16,68.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:72.16,74.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:82.59,84.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:86.55,88.31 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:91.2,96.12 5 1
|
||||
github.com/docker/libtrust/rsa_key.go:88.31,90.3 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:101.63,103.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:106.55,108.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:111.2,112.59 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:108.16,110.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:115.74,117.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:119.67,121.9 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:124.2,124.10 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:121.9,123.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:127.77,134.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:138.2,139.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:144.2,145.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:149.2,150.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:154.2,160.8 3 1
|
||||
github.com/docker/libtrust/rsa_key.go:170.2,170.27 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:174.2,176.17 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:134.16,136.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:139.16,141.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:145.16,147.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:150.16,152.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:160.8,162.17 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:165.3,165.25 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:162.17,164.4 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:165.25,167.4 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:170.27,172.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:189.73,194.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:197.47,199.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:201.41,203.2 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:211.108,217.16 4 1
|
||||
github.com/docker/libtrust/rsa_key.go:220.2,223.16 3 1
|
||||
github.com/docker/libtrust/rsa_key.go:227.2,229.8 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:217.16,219.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:223.16,225.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:235.62,237.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:239.56,252.26 10 1
|
||||
github.com/docker/libtrust/rsa_key.go:265.2,265.12 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:252.26,254.33 2 0
|
||||
github.com/docker/libtrust/rsa_key.go:262.3,262.31 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:254.33,261.4 6 0
|
||||
github.com/docker/libtrust/rsa_key.go:270.64,272.2 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:275.56,279.2 3 1
|
||||
github.com/docker/libtrust/rsa_key.go:281.79,289.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:292.2,293.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:296.2,297.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:300.2,301.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:304.2,305.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:308.2,309.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:313.2,314.29 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:322.2,323.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:327.2,338.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:383.2,388.17 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:289.16,291.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:293.16,295.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:297.16,299.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:301.16,303.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:305.16,307.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:309.16,311.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:314.29,317.3 2 0
|
||||
github.com/docker/libtrust/rsa_key.go:323.16,325.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:338.16,341.10 2 0
|
||||
github.com/docker/libtrust/rsa_key.go:344.3,345.32 2 0
|
||||
github.com/docker/libtrust/rsa_key.go:348.3,352.39 4 0
|
||||
github.com/docker/libtrust/rsa_key.go:379.3,380.47 2 0
|
||||
github.com/docker/libtrust/rsa_key.go:341.10,343.4 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:345.32,347.4 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:352.39,354.11 2 0
|
||||
github.com/docker/libtrust/rsa_key.go:358.4,359.18 2 0
|
||||
github.com/docker/libtrust/rsa_key.go:362.4,363.18 2 0
|
||||
github.com/docker/libtrust/rsa_key.go:366.4,367.18 2 0
|
||||
github.com/docker/libtrust/rsa_key.go:371.4,376.73 6 0
|
||||
github.com/docker/libtrust/rsa_key.go:354.11,356.5 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:359.18,361.5 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:363.18,365.5 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:367.18,369.5 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:395.68,398.16 3 1
|
||||
github.com/docker/libtrust/rsa_key.go:402.2,405.8 3 1
|
||||
github.com/docker/libtrust/rsa_key.go:398.16,400.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:409.54,411.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:415.2,415.15 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:411.16,413.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:419.54,421.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:425.2,425.15 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:421.16,423.3 1 0
|
||||
github.com/docker/libtrust/rsa_key.go:429.54,431.16 2 1
|
||||
github.com/docker/libtrust/rsa_key.go:435.2,435.15 1 1
|
||||
github.com/docker/libtrust/rsa_key.go:431.16,433.3 1 0
|
||||
github.com/docker/libtrust/util.go:21.43,23.2 1 1
|
||||
github.com/docker/libtrust/util.go:29.52,30.20 1 1
|
||||
github.com/docker/libtrust/util.go:39.2,39.43 1 1
|
||||
github.com/docker/libtrust/util.go:31.2,31.9 0 1
|
||||
github.com/docker/libtrust/util.go:32.2,33.12 1 1
|
||||
github.com/docker/libtrust/util.go:34.2,35.11 1 1
|
||||
github.com/docker/libtrust/util.go:36.2,37.53 1 0
|
||||
github.com/docker/libtrust/util.go:42.35,46.33 4 1
|
||||
github.com/docker/libtrust/util.go:51.2,52.21 2 1
|
||||
github.com/docker/libtrust/util.go:46.33,50.3 3 1
|
||||
github.com/docker/libtrust/util.go:55.74,57.9 2 1
|
||||
github.com/docker/libtrust/util.go:61.2,62.9 2 1
|
||||
github.com/docker/libtrust/util.go:65.2,67.17 2 1
|
||||
github.com/docker/libtrust/util.go:57.9,59.3 1 0
|
||||
github.com/docker/libtrust/util.go:62.9,64.3 1 0
|
||||
github.com/docker/libtrust/util.go:70.80,74.16 3 1
|
||||
github.com/docker/libtrust/util.go:77.2,78.33 2 1
|
||||
github.com/docker/libtrust/util.go:81.2,81.43 1 1
|
||||
github.com/docker/libtrust/util.go:74.16,76.3 1 0
|
||||
github.com/docker/libtrust/util.go:78.33,80.3 1 0
|
||||
github.com/docker/libtrust/util.go:84.82,86.16 2 1
|
||||
github.com/docker/libtrust/util.go:98.2,102.32 4 1
|
||||
github.com/docker/libtrust/util.go:106.2,106.43 1 1
|
||||
github.com/docker/libtrust/util.go:86.16,88.3 1 0
|
||||
github.com/docker/libtrust/util.go:102.32,104.3 1 0
|
||||
github.com/docker/libtrust/util.go:109.61,111.16 2 1
|
||||
github.com/docker/libtrust/util.go:115.2,115.43 1 1
|
||||
github.com/docker/libtrust/util.go:111.16,113.3 1 0
|
||||
github.com/docker/libtrust/util.go:118.52,126.24 4 1
|
||||
github.com/docker/libtrust/util.go:131.2,131.16 1 1
|
||||
github.com/docker/libtrust/util.go:126.24,127.18 1 1
|
||||
github.com/docker/libtrust/util.go:127.18,128.9 1 1
|
||||
github.com/docker/libtrust/util.go:134.63,136.16 2 1
|
||||
github.com/docker/libtrust/util.go:142.2,146.50 4 1
|
||||
github.com/docker/libtrust/util.go:136.16,138.3 1 0
|
||||
github.com/docker/libtrust/util.go:149.93,151.16 2 1
|
||||
github.com/docker/libtrust/util.go:155.2,156.16 2 1
|
||||
github.com/docker/libtrust/util.go:160.2,160.47 1 1
|
||||
github.com/docker/libtrust/util.go:151.16,153.3 1 0
|
||||
github.com/docker/libtrust/util.go:156.16,158.3 1 0
|
||||
github.com/docker/libtrust/util.go:163.103,165.28 2 1
|
||||
github.com/docker/libtrust/util.go:180.2,180.22 1 1
|
||||
github.com/docker/libtrust/util.go:165.28,166.26 1 1
|
||||
github.com/docker/libtrust/util.go:167.3,168.29 1 1
|
||||
github.com/docker/libtrust/util.go:169.3,170.20 1 1
|
||||
github.com/docker/libtrust/util.go:175.3,175.11 0 0
|
||||
github.com/docker/libtrust/util.go:170.20,172.5 1 1
|
||||
github.com/docker/libtrust/util.go:172.6,174.5 0 0
|
||||
github.com/docker/libtrust/util.go:183.65,185.16 2 1
|
||||
github.com/docker/libtrust/util.go:189.2,190.16 2 1
|
||||
github.com/docker/libtrust/util.go:194.2,196.20 2 1
|
||||
github.com/docker/libtrust/util.go:185.16,187.3 1 0
|
||||
github.com/docker/libtrust/util.go:190.16,192.3 1 0
|
||||
github.com/docker/libtrust/util.go:199.64,200.43 1 1
|
||||
github.com/docker/libtrust/util.go:200.43,202.21 2 1
|
||||
github.com/docker/libtrust/util.go:207.3,207.40 1 1
|
||||
github.com/docker/libtrust/util.go:202.21,204.4 1 1
|
||||
github.com/docker/libtrust/util.go:204.5,206.4 1 1
|
||||
github.com/docker/libtrust/certificates.go:24.69,33.15 2 1
|
||||
github.com/docker/libtrust/certificates.go:37.2,37.21 1 1
|
||||
github.com/docker/libtrust/certificates.go:41.2,41.21 1 1
|
||||
github.com/docker/libtrust/certificates.go:45.2,58.3 1 1
|
||||
github.com/docker/libtrust/certificates.go:33.15,35.3 1 1
|
||||
github.com/docker/libtrust/certificates.go:37.21,39.3 1 1
|
||||
github.com/docker/libtrust/certificates.go:41.21,43.3 1 1
|
||||
github.com/docker/libtrust/certificates.go:61.123,69.16 4 1
|
||||
github.com/docker/libtrust/certificates.go:73.2,74.16 2 1
|
||||
github.com/docker/libtrust/certificates.go:78.2,78.8 1 1
|
||||
github.com/docker/libtrust/certificates.go:69.16,71.3 1 0
|
||||
github.com/docker/libtrust/certificates.go:74.16,76.3 1 0
|
||||
github.com/docker/libtrust/certificates.go:84.118,93.2 2 1
|
||||
github.com/docker/libtrust/certificates.go:97.78,104.2 2 1
|
||||
github.com/docker/libtrust/certificates.go:108.89,118.2 3 1
|
||||
github.com/docker/libtrust/certificates.go:123.93,126.41 2 1
|
||||
github.com/docker/libtrust/certificates.go:135.2,135.22 1 1
|
||||
github.com/docker/libtrust/certificates.go:126.41,128.17 2 1
|
||||
github.com/docker/libtrust/certificates.go:132.3,132.25 1 1
|
||||
github.com/docker/libtrust/certificates.go:128.17,130.4 1 0
|
||||
github.com/docker/libtrust/certificates.go:140.74,142.16 2 1
|
||||
github.com/docker/libtrust/certificates.go:145.2,148.47 4 1
|
||||
github.com/docker/libtrust/certificates.go:160.2,160.26 1 1
|
||||
github.com/docker/libtrust/certificates.go:142.16,144.3 1 0
|
||||
github.com/docker/libtrust/certificates.go:148.47,149.34 1 1
|
||||
github.com/docker/libtrust/certificates.go:149.34,151.18 2 1
|
||||
github.com/docker/libtrust/certificates.go:154.4,154.45 1 1
|
||||
github.com/docker/libtrust/certificates.go:151.18,153.5 1 0
|
||||
github.com/docker/libtrust/certificates.go:155.5,157.4 1 0
|
||||
github.com/docker/libtrust/certificates.go:165.67,167.16 2 1
|
||||
github.com/docker/libtrust/certificates.go:170.2,171.29 2 1
|
||||
github.com/docker/libtrust/certificates.go:174.2,174.18 1 1
|
||||
github.com/docker/libtrust/certificates.go:167.16,169.3 1 0
|
||||
github.com/docker/libtrust/certificates.go:171.29,173.3 1 1
|
||||
github.com/docker/libtrust/ec_key.go:30.78,33.9 2 1
|
||||
github.com/docker/libtrust/ec_key.go:34.2,35.86 1 1
|
||||
github.com/docker/libtrust/ec_key.go:36.2,37.86 1 1
|
||||
github.com/docker/libtrust/ec_key.go:38.2,39.86 1 1
|
||||
github.com/docker/libtrust/ec_key.go:40.2,41.55 1 0
|
||||
github.com/docker/libtrust/ec_key.go:46.40,48.2 1 1
|
||||
github.com/docker/libtrust/ec_key.go:52.42,54.2 1 1
|
||||
github.com/docker/libtrust/ec_key.go:57.38,68.2 5 1
|
||||
github.com/docker/libtrust/ec_key.go:70.39,72.2 1 1
|
||||
github.com/docker/libtrust/ec_key.go:78.82,81.47 1 1
|
||||
github.com/docker/libtrust/ec_key.go:86.2,88.38 3 1
|
||||
github.com/docker/libtrust/ec_key.go:92.2,98.16 6 1
|
||||
github.com/docker/libtrust/ec_key.go:101.2,103.44 2 1
|
||||
github.com/docker/libtrust/ec_key.go:107.2,107.12 1 1
|
||||
github.com/docker/libtrust/ec_key.go:81.47,83.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:88.38,90.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:98.16,100.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:103.44,105.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:113.58,115.2 1 1
|
||||
github.com/docker/libtrust/ec_key.go:117.54,119.31 2 1
|
||||
github.com/docker/libtrust/ec_key.go:122.2,139.12 13 1
|
||||
github.com/docker/libtrust/ec_key.go:119.31,121.3 1 1
|
||||
github.com/docker/libtrust/ec_key.go:144.62,146.2 1 1
|
||||
github.com/docker/libtrust/ec_key.go:149.54,151.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:154.2,155.59 2 1
|
||||
github.com/docker/libtrust/ec_key.go:151.16,153.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:158.73,160.2 1 1
|
||||
github.com/docker/libtrust/ec_key.go:162.66,164.9 2 1
|
||||
github.com/docker/libtrust/ec_key.go:167.2,167.10 1 1
|
||||
github.com/docker/libtrust/ec_key.go:164.9,166.3 1 1
|
||||
github.com/docker/libtrust/ec_key.go:170.75,177.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:181.2,186.9 2 1
|
||||
github.com/docker/libtrust/ec_key.go:201.2,202.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:205.2,206.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:210.2,211.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:214.2,215.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:219.2,226.8 3 1
|
||||
github.com/docker/libtrust/ec_key.go:236.2,238.17 2 1
|
||||
github.com/docker/libtrust/ec_key.go:177.16,179.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:187.2,189.17 2 1
|
||||
github.com/docker/libtrust/ec_key.go:190.2,192.17 2 1
|
||||
github.com/docker/libtrust/ec_key.go:193.2,195.17 2 1
|
||||
github.com/docker/libtrust/ec_key.go:196.2,197.88 1 0
|
||||
github.com/docker/libtrust/ec_key.go:202.16,204.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:206.16,208.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:211.16,213.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:215.16,217.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:226.8,228.17 2 1
|
||||
github.com/docker/libtrust/ec_key.go:231.3,231.25 1 1
|
||||
github.com/docker/libtrust/ec_key.go:228.17,230.4 1 0
|
||||
github.com/docker/libtrust/ec_key.go:231.25,233.4 1 0
|
||||
github.com/docker/libtrust/ec_key.go:252.82,254.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:258.2,258.57 1 1
|
||||
github.com/docker/libtrust/ec_key.go:254.16,256.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:262.46,264.2 1 1
|
||||
github.com/docker/libtrust/ec_key.go:266.40,268.2 1 0
|
||||
github.com/docker/libtrust/ec_key.go:276.107,283.16 3 1
|
||||
github.com/docker/libtrust/ec_key.go:286.2,289.16 3 1
|
||||
github.com/docker/libtrust/ec_key.go:292.2,304.8 9 1
|
||||
github.com/docker/libtrust/ec_key.go:283.16,285.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:289.16,291.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:310.61,312.2 1 1
|
||||
github.com/docker/libtrust/ec_key.go:314.55,335.2 8 1
|
||||
github.com/docker/libtrust/ec_key.go:339.63,341.2 1 1
|
||||
github.com/docker/libtrust/ec_key.go:344.55,346.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:349.2,350.63 2 1
|
||||
github.com/docker/libtrust/ec_key.go:346.16,348.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:353.77,355.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:362.2,363.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:367.2,368.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:372.2,380.17 2 1
|
||||
github.com/docker/libtrust/ec_key.go:355.16,357.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:363.16,365.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:368.16,370.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:387.78,390.16 3 1
|
||||
github.com/docker/libtrust/ec_key.go:394.2,397.8 3 1
|
||||
github.com/docker/libtrust/ec_key.go:390.16,392.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:401.53,403.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:407.2,410.15 3 1
|
||||
github.com/docker/libtrust/ec_key.go:403.16,405.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:414.53,416.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:420.2,423.15 3 1
|
||||
github.com/docker/libtrust/ec_key.go:416.16,418.3 1 0
|
||||
github.com/docker/libtrust/ec_key.go:427.53,429.16 2 1
|
||||
github.com/docker/libtrust/ec_key.go:433.2,436.15 3 1
|
||||
github.com/docker/libtrust/ec_key.go:429.16,431.3 1 0
|
||||
github.com/docker/libtrust/filter.go:10.91,13.30 2 1
|
||||
github.com/docker/libtrust/filter.go:49.2,49.22 1 1
|
||||
github.com/docker/libtrust/filter.go:13.30,15.55 2 1
|
||||
github.com/docker/libtrust/filter.go:28.3,28.22 1 1
|
||||
github.com/docker/libtrust/filter.go:36.3,36.37 1 1
|
||||
github.com/docker/libtrust/filter.go:16.3,17.13 1 1
|
||||
github.com/docker/libtrust/filter.go:18.3,19.28 1 1
|
||||
github.com/docker/libtrust/filter.go:19.28,21.12 2 1
|
||||
github.com/docker/libtrust/filter.go:24.5,24.29 1 1
|
||||
github.com/docker/libtrust/filter.go:21.12,22.14 1 0
|
||||
github.com/docker/libtrust/filter.go:28.22,29.20 1 1
|
||||
github.com/docker/libtrust/filter.go:32.4,32.12 1 1
|
||||
github.com/docker/libtrust/filter.go:29.20,31.5 1 1
|
||||
github.com/docker/libtrust/filter.go:36.37,38.18 2 1
|
||||
github.com/docker/libtrust/filter.go:42.4,42.13 1 1
|
||||
github.com/docker/libtrust/filter.go:38.18,40.5 1 0
|
||||
github.com/docker/libtrust/filter.go:42.13,44.13 2 1
|
||||
github.com/docker/libtrust/hash.go:15.51,17.2 1 1
|
||||
github.com/docker/libtrust/hash.go:19.51,21.2 1 1
|
||||
github.com/docker/libtrust/hash.go:32.75,33.9 1 1
|
||||
github.com/docker/libtrust/hash.go:34.2,35.20 1 1
|
||||
github.com/docker/libtrust/hash.go:36.2,37.20 1 1
|
||||
github.com/docker/libtrust/hash.go:38.2,39.20 1 1
|
||||
github.com/docker/libtrust/hash.go:40.2,41.82 1 0
|
||||
github.com/docker/libtrust/hash.go:45.85,46.9 1 1
|
||||
github.com/docker/libtrust/hash.go:47.2,48.15 1 1
|
||||
github.com/docker/libtrust/hash.go:49.2,50.15 1 1
|
||||
github.com/docker/libtrust/hash.go:51.2,52.14 1 1
|
||||
github.com/docker/libtrust/hash.go:53.2,54.15 1 1
|
|
@ -1,14 +0,0 @@
|
|||
# The `trust` client binary
|
||||
|
||||
The `trust` binary is a tool to manage key pair, signatures, and ACLs
|
||||
in the global trust graph.
|
||||
|
||||
## Command Reference
|
||||
|
||||
### `grant` command
|
||||
|
||||
### `grants` command
|
||||
|
||||
### `register` command
|
||||
|
||||
Registers a public key with a key server and links it with a user namespace
|
|
@ -1,568 +0,0 @@
|
|||
package jsonsign
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
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 libtrust.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 signKey struct {
|
||||
libtrust.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
|
||||
}
|
||||
|
||||
header := &jsHeader{
|
||||
JWK: key.PublicKey(),
|
||||
Algorithm: algorithm,
|
||||
}
|
||||
sig := &jsSignature{
|
||||
Header: header,
|
||||
Signature: joseBase64UrlEncode(sigBytes),
|
||||
Protected: protected,
|
||||
}
|
||||
|
||||
js.signatures = append(js.signatures, sig)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
sig := &jsSignature{
|
||||
Header: header,
|
||||
Signature: joseBase64UrlEncode(sigBytes),
|
||||
Protected: protected,
|
||||
}
|
||||
|
||||
js.signatures = append(js.signatures, sig)
|
||||
|
||||
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() ([]libtrust.PublicKey, error) {
|
||||
keys := make([]libtrust.PublicKey, len(js.signatures))
|
||||
for i, signature := range js.signatures {
|
||||
signBytes, err := js.signBytes(signature.Protected)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var publicKey libtrust.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 libtrust.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")
|
||||
}
|
||||
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.
|
||||
func NewJSONSignature(content []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:]
|
||||
|
||||
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]
|
||||
|
||||
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
|
||||
}
|
|
@ -1,372 +0,0 @@
|
|||
package jsonsign
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
func createTestJSON(sigKey string, indent string) (map[string]interface{}, []byte) {
|
||||
testMap := map[string]interface{}{
|
||||
"name": "dmcgowan/mycontainer",
|
||||
"config": map[string]interface{}{
|
||||
"ports": []int{9101, 9102},
|
||||
"run": "/bin/echo \"Hello\"",
|
||||
},
|
||||
"layers": []string{
|
||||
"2893c080-27f5-11e4-8c21-0800200c9a66",
|
||||
"c54bc25b-fbb2-497b-a899-a8bc1b5b9d55",
|
||||
"4d5d7e03-f908-49f3-a7f6-9ba28dfe0fb4",
|
||||
"0b6da891-7f7f-4abf-9c97-7887549e696c",
|
||||
"1d960389-ae4f-4011-85fd-18d0f96a67ad",
|
||||
},
|
||||
}
|
||||
formattedSection := `{"config":{"ports":[9101,9102],"run":"/bin/echo \"Hello\""},"layers":["2893c080-27f5-11e4-8c21-0800200c9a66","c54bc25b-fbb2-497b-a899-a8bc1b5b9d55","4d5d7e03-f908-49f3-a7f6-9ba28dfe0fb4","0b6da891-7f7f-4abf-9c97-7887549e696c","1d960389-ae4f-4011-85fd-18d0f96a67ad"],"name":"dmcgowan/mycontainer","%s":[{"header":{`
|
||||
formattedSection = fmt.Sprintf(formattedSection, sigKey)
|
||||
if indent != "" {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
json.Indent(buf, []byte(formattedSection), "", indent)
|
||||
return testMap, buf.Bytes()
|
||||
}
|
||||
return testMap, []byte(formattedSection)
|
||||
|
||||
}
|
||||
|
||||
func TestSignJSON(t *testing.T) {
|
||||
key, err := GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating EC key: %s", err)
|
||||
}
|
||||
|
||||
testMap, _ := createTestJSON("buildSignatures", " ")
|
||||
indented, err := json.MarshalIndent(testMap, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("Marshall error: %s", err)
|
||||
}
|
||||
|
||||
js, err := NewJSONSignature(indented)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating JSON signature: %s", err)
|
||||
}
|
||||
err = js.Sign(key)
|
||||
if err != nil {
|
||||
t.Fatalf("Error signing content: %s", err)
|
||||
}
|
||||
|
||||
keys, err := js.Verify()
|
||||
if err != nil {
|
||||
t.Fatalf("Error verifying signature: %s", err)
|
||||
}
|
||||
if len(keys) != 1 {
|
||||
t.Fatalf("Error wrong number of keys returned")
|
||||
}
|
||||
if keys[0].KeyID() != key.KeyID() {
|
||||
t.Fatalf("Unexpected public key returned")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestSignMap(t *testing.T) {
|
||||
key, err := GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating EC key: %s", err)
|
||||
}
|
||||
|
||||
testMap, _ := createTestJSON("buildSignatures", " ")
|
||||
js, err := NewJSONSignatureFromMap(testMap)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating JSON signature: %s", err)
|
||||
}
|
||||
err = js.Sign(key)
|
||||
if err != nil {
|
||||
t.Fatalf("Error signing JSON signature: %s", err)
|
||||
}
|
||||
|
||||
keys, err := js.Verify()
|
||||
if err != nil {
|
||||
t.Fatalf("Error verifying signature: %s", err)
|
||||
}
|
||||
if len(keys) != 1 {
|
||||
t.Fatalf("Error wrong number of keys returned")
|
||||
}
|
||||
if keys[0].KeyID() != key.KeyID() {
|
||||
t.Fatalf("Unexpected public key returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormattedJson(t *testing.T) {
|
||||
key, err := GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating EC key: %s", err)
|
||||
}
|
||||
|
||||
testMap, firstSection := createTestJSON("buildSignatures", " ")
|
||||
indented, err := json.MarshalIndent(testMap, "", " ")
|
||||
if err != nil {
|
||||
t.Fatalf("Marshall error: %s", err)
|
||||
}
|
||||
|
||||
js, err := NewJSONSignature(indented)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating JSON signature: %s", err)
|
||||
}
|
||||
err = js.Sign(key)
|
||||
if err != nil {
|
||||
t.Fatalf("Error signing content: %s", err)
|
||||
}
|
||||
|
||||
b, err := js.PrettySignature("buildSignatures")
|
||||
if err != nil {
|
||||
t.Fatalf("Error signing map: %s", err)
|
||||
}
|
||||
|
||||
if bytes.Compare(b[:len(firstSection)], firstSection) != 0 {
|
||||
t.Fatalf("Wrong signed value\nExpected:\n%s\nActual:\n%s", firstSection, b[:len(firstSection)])
|
||||
}
|
||||
|
||||
parsed, err := ParsePrettySignature(b, "buildSignatures")
|
||||
if err != nil {
|
||||
t.Fatalf("Error parsing formatted signature: %s", err)
|
||||
}
|
||||
|
||||
keys, err := parsed.Verify()
|
||||
if err != nil {
|
||||
t.Fatalf("Error verifying signature: %s", err)
|
||||
}
|
||||
if len(keys) != 1 {
|
||||
t.Fatalf("Error wrong number of keys returned")
|
||||
}
|
||||
if keys[0].KeyID() != key.KeyID() {
|
||||
t.Fatalf("Unexpected public key returned")
|
||||
}
|
||||
|
||||
var unmarshalled map[string]interface{}
|
||||
err = json.Unmarshal(b, &unmarshalled)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not unmarshall after parse: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestFormattedFlatJson(t *testing.T) {
|
||||
key, err := GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating EC key: %s", err)
|
||||
}
|
||||
|
||||
testMap, firstSection := createTestJSON("buildSignatures", "")
|
||||
unindented, err := json.Marshal(testMap)
|
||||
if err != nil {
|
||||
t.Fatalf("Marshall error: %s", err)
|
||||
}
|
||||
|
||||
js, err := NewJSONSignature(unindented)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating JSON signature: %s", err)
|
||||
}
|
||||
err = js.Sign(key)
|
||||
if err != nil {
|
||||
t.Fatalf("Error signing JSON signature: %s", err)
|
||||
}
|
||||
|
||||
b, err := js.PrettySignature("buildSignatures")
|
||||
if err != nil {
|
||||
t.Fatalf("Error signing map: %s", err)
|
||||
}
|
||||
|
||||
if bytes.Compare(b[:len(firstSection)], firstSection) != 0 {
|
||||
t.Fatalf("Wrong signed value\nExpected:\n%s\nActual:\n%s", firstSection, b[:len(firstSection)])
|
||||
}
|
||||
|
||||
parsed, err := ParsePrettySignature(b, "buildSignatures")
|
||||
if err != nil {
|
||||
t.Fatalf("Error parsing formatted signature: %s", err)
|
||||
}
|
||||
|
||||
keys, err := parsed.Verify()
|
||||
if err != nil {
|
||||
t.Fatalf("Error verifying signature: %s", err)
|
||||
}
|
||||
if len(keys) != 1 {
|
||||
t.Fatalf("Error wrong number of keys returned")
|
||||
}
|
||||
if keys[0].KeyID() != key.KeyID() {
|
||||
t.Fatalf("Unexpected public key returned")
|
||||
}
|
||||
}
|
||||
|
||||
func generateTrustCA() (PrivateKey, *x509.Certificate) {
|
||||
key, err := GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cert := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "CA Root",
|
||||
},
|
||||
NotBefore: time.Now().Add(-time.Second),
|
||||
NotAfter: time.Now().Add(time.Hour),
|
||||
IsCA: true,
|
||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(
|
||||
rand.Reader, cert, cert,
|
||||
key.CryptoPublicKey(), key.CryptoPrivateKey(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return key, cert
|
||||
}
|
||||
|
||||
func generateIntermediate(key libtrust.PublicKey, parentKey PrivateKey, parent *x509.Certificate) *x509.Certificate {
|
||||
cert := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Intermediate",
|
||||
},
|
||||
NotBefore: time.Now().Add(-time.Second),
|
||||
NotAfter: time.Now().Add(time.Hour),
|
||||
IsCA: true,
|
||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(
|
||||
rand.Reader, cert, parent,
|
||||
key.CryptoPublicKey(), parentKey.CryptoPrivateKey(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return cert
|
||||
}
|
||||
|
||||
func generateTrustCert(key libtrust.PublicKey, parentKey PrivateKey, parent *x509.Certificate) *x509.Certificate {
|
||||
cert := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(0),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Trust Cert",
|
||||
},
|
||||
NotBefore: time.Now().Add(-time.Second),
|
||||
NotAfter: time.Now().Add(time.Hour),
|
||||
IsCA: true,
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(
|
||||
rand.Reader, cert, parent,
|
||||
key.CryptoPublicKey(), parentKey.CryptoPrivateKey(),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return cert
|
||||
}
|
||||
|
||||
func generateTrustChain(key PrivateKey, ca *x509.Certificate) (PrivateKey, []*x509.Certificate) {
|
||||
parent := ca
|
||||
parentKey := key
|
||||
chain := make([]*x509.Certificate, 6)
|
||||
for i := 5; i > 0; i-- {
|
||||
intermediatekey, err := GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
chain[i] = generateIntermediate(intermediatekey, parentKey, parent)
|
||||
parent = chain[i]
|
||||
parentKey = intermediatekey
|
||||
}
|
||||
trustKey, err := GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
chain[0] = generateTrustCert(trustKey, parentKey, parent)
|
||||
|
||||
return trustKey, chain
|
||||
}
|
||||
|
||||
func TestChainVerify(t *testing.T) {
|
||||
caKey, ca := generateTrustCA()
|
||||
trustKey, chain := generateTrustChain(caKey, ca)
|
||||
|
||||
testMap, _ := createTestJSON("verifySignatures", " ")
|
||||
js, err := NewJSONSignatureFromMap(testMap)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating JSONSignature from map: %s", err)
|
||||
}
|
||||
|
||||
err = js.SignWithChain(trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error signing with chain: %s", err)
|
||||
}
|
||||
|
||||
pool := x509.NewCertPool()
|
||||
pool.AddCert(ca)
|
||||
chains, err := js.VerifyChains(pool)
|
||||
if err != nil {
|
||||
t.Fatalf("Error verifying content: %s", err)
|
||||
}
|
||||
if len(chains) != 1 {
|
||||
t.Fatalf("Unexpected chains length: %d", len(chains))
|
||||
}
|
||||
if len(chains[0]) != 7 {
|
||||
t.Fatalf("Unexpected chain length: %d", len(chains[0]))
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidChain(t *testing.T) {
|
||||
caKey, ca := generateTrustCA()
|
||||
trustKey, chain := generateTrustChain(caKey, ca)
|
||||
|
||||
testMap, _ := createTestJSON("verifySignatures", " ")
|
||||
js, err := NewJSONSignatureFromMap(testMap)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating JSONSignature from map: %s", err)
|
||||
}
|
||||
|
||||
err = js.SignWithChain(trustKey, chain[:5])
|
||||
if err != nil {
|
||||
t.Fatalf("Error signing with chain: %s", err)
|
||||
}
|
||||
|
||||
pool := x509.NewCertPool()
|
||||
pool.AddCert(ca)
|
||||
chains, err := js.VerifyChains(pool)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error verifying with bad chain")
|
||||
}
|
||||
if len(chains) != 0 {
|
||||
t.Fatalf("Unexpected chains returned from invalid verify")
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
|
@ -1,27 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/docker/libtrust"
|
||||
"log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ids, err := libtrust.ListSSHAgentIDs()
|
||||
if err != nil {
|
||||
log.Fatalf("Error listing ssh agent ids: %s", err)
|
||||
}
|
||||
|
||||
for i := range ids {
|
||||
var id libtrust.ID
|
||||
id = ids[i]
|
||||
log.Printf("ID: %#v", id.JSONWebKey())
|
||||
|
||||
signed, err := id.Sign(bytes.NewReader([]byte("hello there")))
|
||||
if err != nil {
|
||||
log.Fatalf("Error signing: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("Signed\n%x", signed)
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"crv": "P-256",
|
||||
"d": "T68FInnZjHW8c8Y3y8UKDEwVEfubGX7mP8X5EOpxRw0",
|
||||
"kid": "GW4F:GS7P:22KY:SQXM:FI74:SQBS:KRXR:V4TR:IG6Q:7NLL:OJIS:3XXJ",
|
||||
"kty": "EC",
|
||||
"x": "B23slGpLr16MTAJ3MaGVZK6QYEb_l5EZkpnrPcdX6JQ",
|
||||
"y": "xgkrg8u46RGLbAMqeg7tYxMGbsEdpxdZ4liN_V8TNZQ"
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnzCCAUSgAwIBAgIBADAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdT
|
||||
N1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6
|
||||
M1hYSjAeFw0xNDA5MDUyMzA3NTRaFw0yNDA5MDkyMzA3NTRaMEYxRDBCBgNVBAMT
|
||||
O0dXNEY6R1M3UDoyMktZOlNRWE06Rkk3NDpTUUJTOktSWFI6VjRUUjpJRzZROjdO
|
||||
TEw6T0pJUzozWFhKMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEB23slGpLr16M
|
||||
TAJ3MaGVZK6QYEb/l5EZkpnrPcdX6JTGCSuDy7jpEYtsAyp6Du1jEwZuwR2nF1ni
|
||||
WI39XxM1lKMjMCEwDgYDVR0PAQH/BAQDAgAEMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDSQAwRgIhAOFl3YnbPAPd7hRbh2Wpe0RrtZ0KAZGpjKk3C1ZhQEG4
|
||||
AiEAh6R8OVclkFNXFbQML8X5uEL+3d7wB+osNU0OlHFaiiQ=
|
||||
-----END CERTIFICATE-----
|
|
@ -1,22 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcy
|
||||
QjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6
|
||||
WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMT
|
||||
O1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02
|
||||
MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ
|
||||
4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN
|
||||
3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkC
|
||||
IDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdT
|
||||
N1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6
|
||||
M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMT
|
||||
O09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNV
|
||||
TEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80e
|
||||
o8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8Uw
|
||||
Raw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsC
|
||||
IQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg==
|
||||
-----END CERTIFICATE-----
|
Binary file not shown.
|
@ -1,35 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "PTC6:ABN6:Q4GG:GAAP:ZI7C:4TVD:NERQ:IWSC:UWVO:4HUK:DSI6:4NKD"
|
||||
}
|
||||
],
|
||||
"expiration": "2017-03-19T19:30:00.894517334Z",
|
||||
"issuedAt": "2015-03-19T19:30:00.894517667Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "KjhqAzsjY87dEyVdQkGoMgJciUalpFla1bno6KnZR6irMhfTxH_qwP69VAqPRrhHV5UdplAeKCDgTiXI6tphFg",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjYxNiwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE1LTAzLTE5VDE5OjMwOjAwWiJ9"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
[
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "PTC6:ABN6:Q4GG:GAAP:ZI7C:4TVD:NERQ:IWSC:UWVO:4HUK:DSI6:4NKD"
|
||||
}
|
||||
]
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"crv": "P-256",
|
||||
"d": "vIA7rvskakiQZI33vYTsOr_icsaTkQoml5IZjFAdBzA",
|
||||
"kid": "OQIS:G2B4:P7QB:G3ZI:THPN:ZITM:UDP2:V7ZS:US6H:CULD:RIZB:X7PI",
|
||||
"kty": "EC",
|
||||
"x": "K0pEXXaql80eo8khKBUhwg8fXwDnc-QIR3CB86JnCVg",
|
||||
"y": "hFrJFKwZkGb3XPCUw7cQQr37PZxu8mfFMEWsOhvUHVI"
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
[
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "TIX7:E75F:VWRT:NFT6:3E25:TPJX:CAEL:YBHA:FTLE:IDGI:BBJ5:HS67"
|
||||
}
|
||||
]
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
}
|
||||
],
|
||||
"expiration": "2014-12-29T00:08:20.565183779Z",
|
||||
"issuedAt": "2014-09-30T00:08:20.565183976Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "uYMwXO869mGDkq7jrE-xfXHcY96JkcIZt_lLWidUtK4Z3-VH8UJx8j-bHQh0rD3C4Olsx7SY5dDOO_Zq60_i1w",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjMwMCwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTA5LTMwVDAwOjA4OjIwWiJ9"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4"
|
||||
}
|
||||
],
|
||||
"expiration": "2017-02-19T22:55:15.973200265Z",
|
||||
"issuedAt": "2015-02-19T22:55:15.973200588Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "YYP07HOiZWVZ5ZYBvFW5FOlAbY86GrLQ62uGpDphPAJFUFzGgCZCuN04iXVIyFueiJOS6brPSV2dDcd_LlSz-A",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjQ1OCwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE1LTAyLTE5VDIyOjU1OjE1WiJ9"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4"
|
||||
}
|
||||
],
|
||||
"expiration": "2015-05-20T22:07:15.075359917Z",
|
||||
"issuedAt": "2015-02-19T22:07:15.075360044Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "te7xmIGQ9EGfYjikIwx0orqZ8WWH7DQN7-sAsoyfDfv_uq5DpgRqs5qkW_rGkwsbF37rq6Bdhdwktvt9YsmlVA",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjQ1OCwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE1LTAyLTE5VDIyOjA3OjE1WiJ9"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "TIX7:E75F:VWRT:NFT6:3E25:TPJX:CAEL:YBHA:FTLE:IDGI:BBJ5:HS67"
|
||||
}
|
||||
],
|
||||
"expiration": "2017-03-22T19:04:46.713978458Z",
|
||||
"issuedAt": "2015-03-22T19:04:46.713978769Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "h-4MmsL1QB9lEfq2V4MVpZNcuiw0cKYP4C8T-nd4JtU1WhJ1q2_9mMQmtaXOdg6wWTcBll1bbf11UwXP26OhaA",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjYxNiwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE1LTAzLTIyVDE5OjA0OjQ2WiJ9"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
}
|
||||
],
|
||||
"expiration": "2014-12-29T00:08:20.565183779Z",
|
||||
"issuedAt": "2014-09-30T00:08:20.565183976Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "uYMwXO869mGDkq7jrE-xfXHcY96JkcIZt_lLWidUtK4Z3-VH8UJx8j-bHQh0rD3C4Olsx7SY5dDOO_Zq60_i1w",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjMwMCwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTA5LTMwVDAwOjA4OjIwWiJ9"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
},
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "OIH7:HQFS:44FK:45VB:3B53:OIAG:TPL4:ATF5:6PNE:MGHN:NHQX:2GE4"
|
||||
}
|
||||
],
|
||||
"expiration": "2015-02-22T22:47:54.722420237Z",
|
||||
"issuedAt": "2014-11-24T22:47:54.722420583Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "WIxdNx3olDbq4fLRx46HHKyghPqpqTMB_RJkI5mCLrg3lIFq8ke-gNgfD_xDHHKgV7CBdmQpUS-FDABcKhQ_0g",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjQ1OCwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTExLTI0VDIyOjQ3OjU0WiJ9"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"crv": "P-256",
|
||||
"d": "6kQq64Rv3qOPLbS9Yj125E1y0ytaUxL8zBA6NJcVEPM",
|
||||
"kid": "W52V:BWCQ:OUY6:IQ5N:X5XG:M7KJ:GX6P:TWMQ:ZFHJ:M632:K23V:XF45",
|
||||
"kty": "EC",
|
||||
"x": "G9rANGMaOxoZ4XzItNBpqrzZLe_hyMY_hnlXARER0rY",
|
||||
"y": "xKeQecpebA2GlxCPNFYKVBjb5XhTlXO8jd63JU9eLZs"
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
### Motivation
|
||||
|
||||
Currently, client to daemon authentication over a TCP port can only be achieved through generating TLS certificates for both the client and daemon. Each daemon instance then needs to be configured to use the generated TLS certificate and the client must specify its own certificate as well. Production critical, large-scale deployments should already be using this method to secure and control access to Docker daemons, but the extra setup required by generating your own keys, getting them signed by a certificate authority, and distributing those certificates is too much overhead for setting up small-scale deployments such as a Boot2Docker VM running on a developer's Mac, for example. Software developers are already familiar with how SSH key distribution works: through a list of authorized_keys on the server and known_host keys on the client. Ideally each instance of the Docker engine (client or daemon) would have a unique identity represented by its own public key. With a list of trusted public keys, two engines can authenticate to eachother and the daemon can authorize the connection. This can be done at the TLS layer after initially loading a list of trusted public keys into a CA Pool.
|
||||
|
||||
### Proposal Summary
|
||||
|
||||
Every instance of Docker will have its own public key which it either generates and saves on first run or loads from a file on subsequent runs. The public key will be distributed to other instances by a user of docker or system administrator to allow connections between two docker engines. Each instance will have a list of public keys which are trusted to accept connections from (trusted clients) and a separate list which it trusts to make connectionss to (trusted hosts). These public keys will be stored as JSON Web Keys and can be distributed as a JSON file, or as a standard PEM file. For TLS connections, the Docker engine's key pair will be used to generate a self-signed TLS certificate and the list of public keys will be used to generate a certificate pool with a certificate authority for each public key. For TLS servers the list of public keys will be loaded from an authorization file (authorized_keys.json) and for TLS clients the list will be loaded from a known hosts file (allowed_hosts.json), a client must always provide its certificate if the daemon requires it. In addition, a certificate authority PEM file will be allowed to be specified to maintain the existing TLS behavior. As another possible addition, upon connecting to a previously unknown server, a CLI user can be prompted to allow a public key now and in the future, leaving it up the user’s discretion.
|
||||
|
||||
### Key Files
|
||||
|
||||
Docker will support key files in either JSON Web Key format or more traditional PEM format.
|
||||
|
||||
##### Private and Public Key files
|
||||
|
||||
Both the docker daemon and client will have a private key file and a public key file in either of these formats. A client's private key default location will be at `~/.docker/key.(pem|json|jwk)` and public key at `~/.docker/pub_key.(pem|json|jwk)` where `~` is the home directory of the user running the `docker` client. The daemon's private key default location will be at `/var/lib/docker/key.(pem|json|jwk)` and public key at `/var/lib/docker/pub_key.(pem|json|jwk)`. Unix file permissions for these private keys MUST be set to `0600`, or 'Read/Write only by User'. It is suggested that the public keys have permissions set to `0644`, or 'Read/Write by User, Read by group/others'. Because these keys may have a variable file extension, Docker will load whichever one matches the glob `key.*` first, so it is NOT RECOMMENDED that there be multiple `key.*` files to avoid any ambiguity over which key file will be used. If the `--tlskey=KEYFILE` argument is used, that exact file will be used. Optionally, we may add a config file for Docker client and daemon in which users may specify the file to use, but that possibility is up for discussion.
|
||||
|
||||
##### Authorized Keys file
|
||||
|
||||
An instance of the Docker engine in daemon mode will need to know which clients are authorized to connect. We propose a file which contains a list of public keys which are authorized to access the Docker Remote API. This idea is borrowed from SSH's `authorized_keys` file. Any client which has the corresponding private key for any public key in this list will be able to connect. This is accomplished by generating a Certificate Authority Pool with a CA certificate automatically generated by the daemon for each key in this list. The server's TLS configuration will allow clients which present a self-signed certificate using one of these keys. Like today, the daemon can still be configured to use a traditional Certificate Authority (the `--tlscacert=CACERTFILE` option). The default location for this file will be `/var/lib/docker/authorized_keys.(pem|json|jwk)`. Docker will also look for trusted client keys in individual files in a directory at `/var/lib/docker/authorized_keys.d` in either PEM or JWK format.
|
||||
|
||||
##### Trusted Hosts file
|
||||
|
||||
An instance of the Docker engine in client mode will need to know which hosts it trusts to connect to. We propose a file which contains a list of public keys which the client trusts to be the key of the Docker Remote API server it wishes to connect to. This idea is borrowed from SSH's `know_hosts` file. Any daemon which has the corresponding private key for a public key in this list AND presents a self-signed server certificate in the TLS handshake which has the desired server name (hostname or IP address of `$DOCKER_HOST`) using one of these keys. Like today, the client can still be configured to use a traditional Certificate Authority (the `--tlscacert=CACERTFILE` option). The TCP address (in the form of `<hostname_or_ip>:<port>`) will be specified for each key using extended attributes for the key, i.e, a `address` JSON field if in JWK format or a `address` header if in PEM format. The default location for this file will be `~/.docker/trusted_hosts.(pem|json|jwk)`. Docker will also look for trusted host keys in individual files in a directory at `~/.docker/trusted_hosts.d` in either PEM or JWK format.
|
||||
|
||||
### Key Types
|
||||
|
||||
By default, a Docker engine will generate an ECDSA key, using the standard P-256 elliptic curve, if a private key file does not already exist. Supported Elliptic Curves are P-256, P-384, and P-521. RSA keys are also supported. The default of Elliptic Curve Cryptography was chosen due to more efficient key generation and smaller key sizes for equivalent levels of security when compared to RSA [[reference](http://www.nsa.gov/business/programs/elliptic_curve.shtml)].
|
||||
|
||||
### User visible changes
|
||||
- TLS is always used for when using tcp:// (unix:// does not require)
|
||||
- Client TLS verification is on by default (`--insecure` flag added to disable)
|
||||
- Server TLS verification is on by default (`--insecure` flag added to disable)
|
||||
- `--tls` and `--tlsverify` flags removed
|
||||
- `-i`/`--identity` flag to specify the identity (private key) file
|
||||
- User prompt added when connecting to unknown server
|
||||
|
||||
### Backwards Compatibility
|
||||
|
||||
In order to maintain backwards compatibility, existing TLS ca, cert, and key options for setting up TLS connections will be allowed. Scripts using `--tls` and `--tlsverify` will need to remove these options since these are now the default. To use the existing insecure behavior, run scripts will need to be modified to use `--insecure`, this is not recommended. These changes do no have any effect on servers using unix sockets.
|
||||
|
||||
- Connecting from older client: The client must generate a certificate which is distributed to the server. Optionally the newer server can run with `--insecure` which will require no changes to the client.
|
||||
- Connecting to an older server: If non-TLS, Client will maintain ability to connect to endpoint using the `--insecure` flag. If TLS is manually configured, no changes should be required.
|
||||
|
||||
### Usage Pattern
|
||||
- Single Machine - Setup using Unix socket, no changes
|
||||
- Single Machine (with non-B2D VM) -
|
||||
- Invoke docker on host to generate key.json
|
||||
- Invoke docker on guest to generate key.json
|
||||
- Copy ~/.docker/pub_key.json on guest to /var/lib/docker/trusted_hosts.d/guest.json on host
|
||||
- Copy /var/lib/docker/pub_key.json on host to ~/.docker/authorized_keys.d/host.json on guest (optionally use prompt)
|
||||
- Single Machine (B2D) - Boot2Docker installation generates and copies keys
|
||||
- Two Machines -
|
||||
- Invoke docker on client to generate key.json
|
||||
- Invoke docker on server to generate key.json
|
||||
- Copy ~/.docker/pub_key.json on client to ~/.docker/authorized_keys.d/client.json on server
|
||||
- Copy /var/lib/docker/pub_key.json on server to ~/.docker/trusted_hosts.d/server.json on client
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC7DCCAdagAwIBAgIRAMzw0lcScp8VgiIX5W18bkUwCwYJKoZIhvcNAQELMBYx
|
||||
FDASBgNVBAoTC0Jvb3QyRG9ja2VyMB4XDTE0MTAxMzIxMjIyOVoXDTE3MDkyNzIx
|
||||
MjIyOVowEzERMA8GA1UEChMIUmVnaXN0cnkwggEiMA0GCSqGSIb3DQEBAQUAA4IB
|
||||
DwAwggEKAoIBAQC8V4jsxvsRZ5ml1Q/VXtrJStFcTjzwh2niEPCvER6xYcWHloMM
|
||||
A6q8cvoHYv2/1ELbKQbLaIuKowWa3gvsiL1Fs3b02jv0a9rN4kFofkRLKuvYKroB
|
||||
Y2P06LNT/sXnE+jCSw9OEdYZuoVXeohmVpcQUCeh8LNDS0b+vg+fU/O46iggUlqu
|
||||
LOaXC8A68SSiBP6qG/cOBPNmfGi09G8sCJ7b7Xd2J8MPeUovNVw+2Wfj4Bzox8s/
|
||||
7B9Ef6iIfwdkvclHoBZIzclJdA0ew5aam/a7SStuRMgX7yhDfRh9sRiyv/ZvKXW6
|
||||
CUy0Oqa//UlmQoC6K3kOm/EMzPocI6NwJ53PAgMBAAGjPDA6MA4GA1UdDwEB/wQE
|
||||
AwIAoDAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATAL
|
||||
BgkqhkiG9w0BAQsDggEBAJjOpgKhzlMcrWhh2pFNaHK77IIROMG8XgmdWE3u2IS9
|
||||
oKbe31n1scyNIvUkrE11iwqJ+4i6C9/eHf1sTz1sHSoBA+7w9O7ghErQ5XK+rfZD
|
||||
Ax/Bu7o1lpnxtrQTiMaVUXZrBnowooDCdjyQyX0BeiIIRhQyBbx3lMpfjbyXFM/l
|
||||
hTuRC8Mt2QSu6pn+Le8t9rlkFq9exHg0Jng1ZpaJWCt6K27J8rMS3jngFUa2ihG6
|
||||
d5vSu6Gqaqhtki4uGA2mUu7RPUhZ5H+WLmDknHeD3/k9ASloa6jw2ehcyU9o4PMB
|
||||
5Lr1zMEG5RkNDVcE5qurWNrpZc1ajPomxmuTrcwO6vQ=
|
||||
-----END CERTIFICATE-----
|
173
Godeps/_workspace/src/github.com/docker/libtrust/registry-test/generate_cert.go
generated
vendored
173
Godeps/_workspace/src/github.com/docker/libtrust/registry-test/generate_cert.go
generated
vendored
|
@ -1,173 +0,0 @@
|
|||
// Usage:
|
||||
// Generate CA
|
||||
// ./generate_cert --cert ca.pem --key ca-key.pem
|
||||
// Generate signed certificate
|
||||
// ./generate_cert --host 127.0.0.1 --cert cert.pem --key key.pem --ca ca.pem --ca-key ca-key.pem
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"flag"
|
||||
"log"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for")
|
||||
certFile = flag.String("cert", "", "Output file for certificate")
|
||||
keyFile = flag.String("key", "", "Output file for key")
|
||||
ca = flag.String("ca", "", "Certificate authority file to sign with")
|
||||
caKey = flag.String("ca-key", "", "Certificate authority key file to sign with")
|
||||
)
|
||||
|
||||
const (
|
||||
RSABITS = 2048
|
||||
VALIDFOR = 1080 * 24 * time.Hour
|
||||
ORG = "Registry"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if *certFile == "" {
|
||||
log.Fatalf("Missing required parameter: --cert")
|
||||
}
|
||||
|
||||
if *keyFile == "" {
|
||||
log.Fatalf("Missing required parameter: --key")
|
||||
}
|
||||
|
||||
if *ca == "" {
|
||||
if *caKey != "" {
|
||||
log.Fatalf("Must provide both --ca and --ca-key")
|
||||
}
|
||||
if err := GenerateCA(*certFile, *keyFile); err != nil {
|
||||
log.Fatalf("Failured to generate CA: %s", err)
|
||||
}
|
||||
} else {
|
||||
if err := GenerateCert(strings.Split(*host, ","), *certFile, *keyFile, *ca, *caKey); err != nil {
|
||||
log.Fatalf("Failured to generate cert: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// newCertificate creates a new template
|
||||
func newCertificate() *x509.Certificate {
|
||||
notBefore := time.Now()
|
||||
notAfter := notBefore.Add(time.Hour * 24 * 1080)
|
||||
|
||||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
|
||||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to generate serial number: %s", err)
|
||||
}
|
||||
|
||||
return &x509.Certificate{
|
||||
SerialNumber: serialNumber,
|
||||
Subject: pkix.Name{
|
||||
Organization: []string{ORG},
|
||||
},
|
||||
NotBefore: notBefore,
|
||||
NotAfter: notAfter,
|
||||
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||
//ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateCA generates a new certificate authority
|
||||
// and stores the resulting certificate and key file
|
||||
// in the arguments.
|
||||
func GenerateCA(certFile, keyFile string) error {
|
||||
template := newCertificate()
|
||||
template.IsCA = true
|
||||
template.KeyUsage |= x509.KeyUsageCertSign
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, RSABITS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, template, template, &priv.PublicKey, priv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
certOut, err := os.Create(certFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||
certOut.Close()
|
||||
|
||||
keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||||
keyOut.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateCert generates a new certificate signed using the provided
|
||||
// certificate authority files and stores the result in the certificate
|
||||
// file and key provided. The provided host names are set to the
|
||||
// appropriate certificate fields.
|
||||
func GenerateCert(hosts []string, certFile, keyFile, caFile, caKeyFile string) error {
|
||||
template := newCertificate()
|
||||
for _, h := range hosts {
|
||||
if ip := net.ParseIP(h); ip != nil {
|
||||
template.IPAddresses = append(template.IPAddresses, ip)
|
||||
} else {
|
||||
template.DNSNames = append(template.DNSNames, h)
|
||||
}
|
||||
}
|
||||
|
||||
tlsCert, err := tls.LoadX509KeyPair(caFile, caKeyFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
priv, err := rsa.GenerateKey(rand.Reader, RSABITS)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
x509Cert, err := x509.ParseCertificate(tlsCert.Certificate[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
derBytes, err := x509.CreateCertificate(rand.Reader, template, x509Cert, &priv.PublicKey, tlsCert.PrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
certOut, err := os.Create(certFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
|
||||
certOut.Close()
|
||||
|
||||
keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||||
keyOut.Close()
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEAvFeI7Mb7EWeZpdUP1V7ayUrRXE488Idp4hDwrxEesWHFh5aD
|
||||
DAOqvHL6B2L9v9RC2ykGy2iLiqMFmt4L7Ii9RbN29No79GvazeJBaH5ESyrr2Cq6
|
||||
AWNj9OizU/7F5xPowksPThHWGbqFV3qIZlaXEFAnofCzQ0tG/r4Pn1PzuOooIFJa
|
||||
rizmlwvAOvEkogT+qhv3DgTzZnxotPRvLAie2+13difDD3lKLzVcPtln4+Ac6MfL
|
||||
P+wfRH+oiH8HZL3JR6AWSM3JSXQNHsOWmpv2u0krbkTIF+8oQ30YfbEYsr/2byl1
|
||||
uglMtDqmv/1JZkKAuit5DpvxDMz6HCOjcCedzwIDAQABAoIBAQCDKJZTBbK8CSCH
|
||||
yptPJNJJ0Y+Ar39ipXqIEvH5iHuOXZ8YcClsiXUx7QPPdxFssF2qj6SKrJBYiHST
|
||||
x8QYAZWFX5gcpYmRCjcCn2ibYyseCZLaI88KvnNSj2aqvMaGyGeUPn83B9bIbgsD
|
||||
w3IPioeCtb8T2DKOT3LuXd81PlqAz2Q2O1OHhTpWYA9gLAeXx+z6jU+Cvn9z67n0
|
||||
+9utUTk8n+SN4+K4h7ufM7CFzLgnugyrhvIgm0NfHDhR9SBwwSTJ/J1CrD4TLkIm
|
||||
d3HetZemfRjByg11Zrltm3YgxdTWKrjfqX3XguR/6HIiXvo5vWhs5DAuQtvTc8Wa
|
||||
ahceS2KxAoGBAMPqj8mWu+LSlWmXIx2gXNPkhK1EovZL0gImouWbb7kCHxQNYTJs
|
||||
wWzG61y9NdCHkhbCDsGXj9rFpPlrDr567gMZTYmLBzcB8DXpHr5XPyl6ZDqYs/L0
|
||||
4jDTSG/tthIDnxVY1O+bGrzknVpakrgJ9H2yivgWIWBVX3XUfXEH8f4HAoGBAPYa
|
||||
T5408onWBzWpbydvPd4loAbuCgG2bXOJjqsyZALHS4SoDQ2HUIZokVlf9yWOzyhd
|
||||
R8iWYADhMps+/wVW6eNAva3hCzI8US0ZiF7SgIZlq31UV1kDXl/XV+ccFp1R95KV
|
||||
c0VbRw2Tqzhmdu7OcvysP8FYZvGWGCev6Opxqe/5AoGBAJDt1xp4kFsWDwOCk66Z
|
||||
77GsTd3jdW4f3qZKsJyMJNTG1fi+gRWNUHVIndoH+mRdtdtyCPp7RSbAqO79nHWa
|
||||
eLIAKNTD7T1rCKjI4D5MSmRDrxuN1Si4sQ8PbXmnbtXaqfdftH3fzqLHuAOcFwdg
|
||||
DeZiit1FecFKxohi/bz89K5HAoGAQI0qMQ8mRu0yuuqUUz2kdq5byTWKvmRBVTrR
|
||||
hyoSfYAU2NjTg6bogjjPVygKxXkt8SJ2f7ChwdlP0tS1Q4tGkesbVY5fx292w2Od
|
||||
F3ITcC0ezCLhPmHZ0T3EusPtUpp7W6GDuL92ZaNEF+kYbQ8NriToHCi558g80bwc
|
||||
VdI2htECgYEAjOkauwVyJrNt3/NNW7yv/hLOzgX+Cxe9GSWZj9LoYdjB1Y9/rzyq
|
||||
f2YGdmyrrY8dWXHI9YK/RXk9/r2EDNNGwyH0+6na5pS5D+r78DhS1fiba7EJrPYK
|
||||
s68QsKo397pa6gWhlQpsUJr97/y2V9Fba8SINnzzmG0zJehPGQXuRFc=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,18 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIC3DCCAcagAwIBAgIQXHT/h2+fDzoIxPvBTexiCjALBgkqhkiG9w0BAQswFjEU
|
||||
MBIGA1UEChMLQm9vdDJEb2NrZXIwHhcNMTQxMDEzMjIxMzI5WhcNMTcwOTI3MjIx
|
||||
MzI5WjATMREwDwYDVQQKEwhSZWdpc3RyeTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAPKkPwCO4bgmrJek6lWjToBuyF4Or3E/38GwIECpuZuymoBs4C1B
|
||||
7Qp7oOrGIRh96htgYPl5WkDUM0If9yG2bDR9JwLxs5OEZrwLbzsvDgaGYiLocElH
|
||||
nKoUdorkr2DtG/rBOgiAqiw9Rw4+Bb0J09hx/Q+S9xuebthSnnKKtBXicBfmHkbD
|
||||
UhfolSdbdBa4u3R2gkFzGXCoAnuYJSerO6fewCJTg2jWxGjuU/Ekm3m13XWQWBis
|
||||
OQN7qGRr/sHLaB4wp69X/mtOKyK1BoGPYV2f73VKremU52QsTcpYw9q6Zoy/iztq
|
||||
WZMVY0Mo4x1TvVKFlzbb9g3UpqDEZCgxS60CAwEAAaMtMCswDgYDVR0PAQH/BAQD
|
||||
AgCgMAwGA1UdEwEB/wQCMAAwCwYDVR0RBAQwAoIAMAsGCSqGSIb3DQEBCwOCAQEA
|
||||
rq6CCnZKw39nT8VVAMiGS63q6+eGX0u8SjsPQu7qqxDex4La09rAZzlfh2GvusCz
|
||||
kJcFyliCwbZTZqFyfYXex+dFgBRaGmjTaE5ZKS7e0UV0oPE4ig9OFMl8/5dsOWJe
|
||||
3SpXOwC41idNAqzJ/StcWy2IIco7TM3YcjCFQeHwNOpspgOiTN3CYkUCmxkRVd2q
|
||||
U8aEvk6/rmmVCesDWsAAngfdHPRVca7PSn8Xz0hglHtdTsO/32EfCmOJI9Lc78cR
|
||||
6g9mX98oJwstQYTsA7lvcTArbCVhbQ/4z8T/AZu2P89Nr8+GW6XRxM5Ne08RnvlE
|
||||
IZa1y0Fg07FIqgJB3HAbHA==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEA8qQ/AI7huCasl6TqVaNOgG7IXg6vcT/fwbAgQKm5m7KagGzg
|
||||
LUHtCnug6sYhGH3qG2Bg+XlaQNQzQh/3IbZsNH0nAvGzk4RmvAtvOy8OBoZiIuhw
|
||||
SUecqhR2iuSvYO0b+sE6CICqLD1HDj4FvQnT2HH9D5L3G55u2FKecoq0FeJwF+Ye
|
||||
RsNSF+iVJ1t0Fri7dHaCQXMZcKgCe5glJ6s7p97AIlODaNbEaO5T8SSbebXddZBY
|
||||
GKw5A3uoZGv+wctoHjCnr1f+a04rIrUGgY9hXZ/vdUqt6ZTnZCxNyljD2rpmjL+L
|
||||
O2pZkxVjQyjjHVO9UoWXNtv2DdSmoMRkKDFLrQIDAQABAoIBAHkE4IN3wC7n4ydT
|
||||
UqlZ5Tp7hqYa7vguInzpSnzV6kQ0xYiORRVtjzuuQ6k1Hqanjo8O9+8VzqUM8W/m
|
||||
n40J/lgDn+SBBs7pt4/MqDK9mmI4vlOo2PBDrmjKAgHuY2aVfGIJ49b/zWB5Q6pf
|
||||
1t7dOvL2j4AoDeWRlLmCI5L/iShsKlm8isnEqnvSoWYQEIjyesum8LhjfvDVyvl7
|
||||
huOiIbwqCz5198GedhrbCRE4O/owbv9e1yv9RpV/Kruauw+W1uRg4o+WAzvaZ71q
|
||||
rzlJAi0TQ144E0DqCmCswpJpB/jxK+prcagdTY80SYxg+MPToqqwlUGzwP4piHyO
|
||||
Hltqm6UCgYEA+7IufLh6nhTgVRD5nPAVDZXxA5906YlZTWTeRH5gOBWoULh+4Ur/
|
||||
L+hEZzwiZz5cdWf+qggDmO8HAgtbvUdgMddAOGfEcsVma+H1BqD6ktFXU3tuFqPG
|
||||
+Mvtz7uDpyVCSiltBOBtI/Ps6VXXRyjXtpWir3QCjLn+emFlxB/kTKMCgYEA9spt
|
||||
k6TcFMVI8pXzpDhi4WDaf63/WftF3+FBCXLIejq1gQH0edUtKTYieyajgemo4/ph
|
||||
3LiF9P6lWLRjHpWyrIlW5j3qSOXu/KX1MkKGUnWXXu5EXf+U5+yXl/LgNvgkA3Rc
|
||||
lpIiL6xhJkkOn0b9b6SfDO3Mkc+fdFLNtoFzu28CgYBhwLEXVVqh/L+nqiEX15KF
|
||||
pT9mxc5VSTe6vDsq5N4fyiGFwDHe9A6qH445ffxqlqi4HHymstga1HKnU5v8pjTx
|
||||
BoV1oq+EV7BQpABS48CNtuowjRaTimYjiKhC7rPR/cGCJhamNzeMKBdSBDnI9E7b
|
||||
JcB6XhcDatUv2JX6ltxG+wKBgEGqbymf7idgrx5NI/0IO9c4TCs5Av7QSzFc4E9B
|
||||
SXKseGsROBnKzS9wBhC6oTsKDzRKBQwT1SDxONG3fcA/mMEr8gFlbBdlhweWqP1s
|
||||
kg0S2Oobf/l67gYf/94gc+RsdjitF43A6HPC7D6hpdBftUOli+SGya3qjsUG21G6
|
||||
dC7lAoGAJ84wM2yGU358OCmMdbxdjSpwk3P5ue+kcZqYa6R9NX503hg+zdDAnPzS
|
||||
Dn0Psf7XKklGqMnDRLyusKNPE4hhR/AukeGvBpB8rntBkXvBn0gR3Pz9mJioUvCw
|
||||
nvsYNrv7yPaMUjDpi3tlDdCxA/c1OYI4nPD1RO1z6KtXzXumg6k=
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"keyType": "jwk",
|
||||
"keyId": "KVKI:GMUJ:FMD7:7BWO:KP7O:QIWP:VRDG:IAWU:MJ6Z:GX35:N6E5:XCD6:2AIQ",
|
||||
"key": {
|
||||
"crv": "P-256",
|
||||
"d": "woOnFXsfJ2UhOW0A0sHRQr-j-ylaFp5hSqv9MXaWIfA",
|
||||
"kid": "KVKI:GMUJ:FMD7:7BWO:KP7O:QIWP:VRDG:IAWU:MJ6Z:GX35:N6E5:XCD6:2AIQ",
|
||||
"kty": "EC",
|
||||
"x": "7C7zxqK8TJUO0yiO3QHhaUm5gjBO_u4UN6Gdw2U846Y",
|
||||
"y": "11bnKVNb4Yoy0rpJA7slvBm44Lmc4c36h_LjEP8PJmQ"
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
MHcCAQEEIFlzVietDbzPESwRynJaAZA38KgGkyxkmnOko1OAxniMoAoGCCqGSM49AwEHoUQDQgAEL1Rx9iUzepbmqQub62qSPgC2YTabUFtnqDXNrfN7g2z0P9FYV/ScBIqxnBDdV6Sy1ZIrfUgiuA7JyaABg4hjCw==
|
||||
MHcCAQEEIGrv2ULb+HV3KoJlciMJ1THswtYxvZ9HVrvIVYaZyt3UoAoGCCqGSM49AwEHoUQDQgAEV+CHKKPoF1rFiVkFiEdoXlXa8UybgoNPQmPVr8ImuR0grslx2Tk/Ja/23CYzYtLeEuRa+lRQSxKa2NjDo7BhfQ==
|
||||
MHcCAQEEIBxKadItcsdt+lqIh9fCOYX8OpTiIYLlaeZWeKxvJrw4oAoGCCqGSM49AwEHoUQDQgAEp8JenwbJSTVXKS0IHH1KrwPgF7duEwV3aIejGYiBlVZDdgz+DzJcQOGEh9gcOjQ02p7/ciwE4RGZVWs5gUi2nA==
|
||||
MHcCAQEEIEP8tpIAkgABEl87mJgiPLkdUIjowoDWFm6phU8bTpZ4oAoGCCqGSM49AwEHoUQDQgAEMvc0R61PCQT+NmyJjnjJugzZhfab2yb/7t40DiehQhotCpAiFY1xRIeTq0TphgsFAR7TSRajvBVwdPYfEypOAQ==
|
||||
MHcCAQEEIHQ1lyvaMTwnbab+NRQvZY4+uvrRwhiotyrZHkfnNWpSoAoGCCqGSM49AwEHoUQDQgAEujEqwGrX0laAM+OHIjM/84n/eYitBmcTTNPgoRaiGfd5xdFPdtTG6ZSt4/m+FBdQ1RAF8bvYPgyMmvm8V7uFDg==
|
|
@ -1,5 +0,0 @@
|
|||
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
|
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/client_data/private_key.pem
generated
vendored
Normal file
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/client_data/private_key.pem
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
comment: TLS Demo Client
|
||||
keyID: YCNH:BVIR:5GVK:RZOG:JNWW:ZL4B:MQRY:WXEF:AOOD:S6N6:FQZW:RGZ2
|
||||
|
||||
MHcCAQEEIOLL3nXjiX0XDSRNYV7jH7Tpd1QGoeKedwGTmB96bz77oAoGCCqGSM49
|
||||
AwEHoUQDQgAEHpO8+XFpL5+dcOazOlZDfnVNif+HSZxFaQ2bLcslQKUdIkrV2+Up
|
||||
tQd6fXupPYDVfWGuelkQrdel5ObnMAZ8YQ==
|
||||
-----END EC PRIVATE KEY-----
|
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/client_data/public_key.pem
generated
vendored
Normal file
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/client_data/public_key.pem
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
comment: TLS Demo Client
|
||||
keyID: YCNH:BVIR:5GVK:RZOG:JNWW:ZL4B:MQRY:WXEF:AOOD:S6N6:FQZW:RGZ2
|
||||
kid: YCNH:BVIR:5GVK:RZOG:JNWW:ZL4B:MQRY:WXEF:AOOD:S6N6:FQZW:RGZ2
|
||||
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHpO8+XFpL5+dcOazOlZDfnVNif+H
|
||||
SZxFaQ2bLcslQKUdIkrV2+UptQd6fXupPYDVfWGuelkQrdel5ObnMAZ8YQ==
|
||||
-----END PUBLIC KEY-----
|
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/client_data/trusted_hosts.pem
generated
vendored
Normal file
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/client_data/trusted_hosts.pem
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
hosts: localhost,docker.example.com
|
||||
keyID: LH6B:6ZBK:D34J:M6E5:RV6I:5BAL:7KGZ:PHCJ:JKDU:7PLV:2D7H:UZR2
|
||||
kid: LH6B:6ZBK:D34J:M6E5:RV6I:5BAL:7KGZ:PHCJ:JKDU:7PLV:2D7H:UZR2
|
||||
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGn+xPy/OOCXFidcKb13zfJJV0JwS
|
||||
BE1vlyxog0tSsN/U8tObgpDKaCE7+9tLl4djnd+blOOIJq6fph/dAZal4A==
|
||||
-----END PUBLIC KEY-----
|
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/server_data/private_key.pem
generated
vendored
Normal file
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/server_data/private_key.pem
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN EC PRIVATE KEY-----
|
||||
hosts: localhost,docker.example.com
|
||||
keyID: LH6B:6ZBK:D34J:M6E5:RV6I:5BAL:7KGZ:PHCJ:JKDU:7PLV:2D7H:UZR2
|
||||
|
||||
MHcCAQEEILDWn14dH5vPo1JWpXrWB5qj6MS51T3XAGp/fuFTUg5IoAoGCCqGSM49
|
||||
AwEHoUQDQgAEGn+xPy/OOCXFidcKb13zfJJV0JwSBE1vlyxog0tSsN/U8tObgpDK
|
||||
aCE7+9tLl4djnd+blOOIJq6fph/dAZal4A==
|
||||
-----END EC PRIVATE KEY-----
|
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/server_data/public_key.pem
generated
vendored
Normal file
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/server_data/public_key.pem
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
hosts: localhost,docker.example.com
|
||||
keyID: LH6B:6ZBK:D34J:M6E5:RV6I:5BAL:7KGZ:PHCJ:JKDU:7PLV:2D7H:UZR2
|
||||
kid: LH6B:6ZBK:D34J:M6E5:RV6I:5BAL:7KGZ:PHCJ:JKDU:7PLV:2D7H:UZR2
|
||||
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEGn+xPy/OOCXFidcKb13zfJJV0JwS
|
||||
BE1vlyxog0tSsN/U8tObgpDKaCE7+9tLl4djnd+blOOIJq6fph/dAZal4A==
|
||||
-----END PUBLIC KEY-----
|
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/server_data/trusted_clients.pem
generated
vendored
Normal file
8
Godeps/_workspace/src/github.com/docker/libtrust/tlsdemo/server_data/trusted_clients.pem
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
comment: TLS Demo Client
|
||||
keyID: YCNH:BVIR:5GVK:RZOG:JNWW:ZL4B:MQRY:WXEF:AOOD:S6N6:FQZW:RGZ2
|
||||
kid: YCNH:BVIR:5GVK:RZOG:JNWW:ZL4B:MQRY:WXEF:AOOD:S6N6:FQZW:RGZ2
|
||||
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHpO8+XFpL5+dcOazOlZDfnVNif+H
|
||||
SZxFaQ2bLcslQKUdIkrV2+UptQd6fXupPYDVfWGuelkQrdel5ObnMAZ8YQ==
|
||||
-----END PUBLIC KEY-----
|
Binary file not shown.
|
@ -1,53 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
var ca string
|
||||
var chain string
|
||||
var cert string
|
||||
var signKey string
|
||||
var validKeys string
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&signKey, "k", "", "Private key to use for signing (pem or JWS file)")
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
if signKey == "" {
|
||||
log.Fatalf("Missing key")
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading content from stdin: %s", err)
|
||||
}
|
||||
|
||||
sig, err := libtrust.NewJSONSignature(content)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating JSON signature: %s", err)
|
||||
}
|
||||
|
||||
privKey, err := libtrust.LoadKeyFile(signKey)
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading priv key: %s", err)
|
||||
}
|
||||
sig.Sign(privKey)
|
||||
|
||||
// Output signed content to stdout
|
||||
out, err := sig.PrettySignature("signatures")
|
||||
if err != nil {
|
||||
log.Fatalf("Error formatting output: %s", err)
|
||||
}
|
||||
_, err = os.Stdout.Write(out)
|
||||
if err != nil {
|
||||
log.Fatalf("Error writing output: %s", err)
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"crv": "P-256",
|
||||
"d": "z7JYp-fmJMFPsalhcGy7G0RNdE2l23VDcNh6zYI75aE",
|
||||
"kid": "UAY5:GSOJ:M4G5:Y5E4:CZ43:HJC4:G5AD:IDW3:GM7B:TRKT:5C3C:H3NH",
|
||||
"kty": "EC",
|
||||
"x": "8P_ZDmt8RFIeIDR_vma9SUZOF3GWUV9gDF6MuAJY68I",
|
||||
"y": "kFEmSOPtggWhun8pyUh3V6oQZYXfQuoz4Ia7ituWpDc"
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnjCCAUSgAwIBAgIBADAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztVQVk1OkdT
|
||||
T0o6TTRHNTpZNUU0OkNaNDM6SEpDNDpHNUFEOklEVzM6R003QjpUUktUOjVDM0M6
|
||||
SDNOSDAeFw0xNDExMDQyMDQxMTVaFw0yNDExMDgyMDQxMTVaMEYxRDBCBgNVBAMT
|
||||
O1VBWTU6R1NPSjpNNEc1Olk1RTQ6Q1o0MzpISkM0Okc1QUQ6SURXMzpHTTdCOlRS
|
||||
S1Q6NUMzQzpIM05IMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8P/ZDmt8RFIe
|
||||
IDR/vma9SUZOF3GWUV9gDF6MuAJY68KQUSZI4+2CBaG6fynJSHdXqhBlhd9C6jPg
|
||||
hruK25akN6MjMCEwDgYDVR0PAQH/BAQDAgAEMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDSAAwRQIhAKVFo9JVRbjIJaOjgMpPUuVMxfLYffDfiEYOPvJkEu9b
|
||||
AiBWSPsJyfyiv5sD+qKc/pKU31o9v/gQ8agQMs6weIomrw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,22 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnjCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztKQk5IOlgy
|
||||
R1o6R0tIVzpJWjZEOk1TRzY6R1BZRjo0NDU2OkNFNDY6VDRKNjpWVVdROkZEWlU6
|
||||
QUxZNDAeFw0xNDExMTEyMDQxMTRaFw0xNTAyMDkyMDQxMTVaMEYxRDBCBgNVBAMT
|
||||
O1dXQUM6NURWRzpSVlhZOkFQU0M6Q0VaVzpUT1A0Ok1NSEo6RkVaVDpXTU9KOkhW
|
||||
TFg6SFFNUDo2SldLMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfmp8Xhfx+d5l
|
||||
FYD+Ouxq3b75DzAnCGjY2iGGwcGRpkmk5dslR9JmySCKl7saJHYcoGdljR1PeYwt
|
||||
aRiEKL2Nm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDSAAwRQIgBhSPTHU/d4SvN9fD54wM9Es856s7KSikP2CSrvKvNW4C
|
||||
IQDdwJd7h0u7oMKlD3QSadun4Wwu6hKnMoLevQPeRMV9bA==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnzCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztVQVk1OkdT
|
||||
T0o6TTRHNTpZNUU0OkNaNDM6SEpDNDpHNUFEOklEVzM6R003QjpUUktUOjVDM0M6
|
||||
SDNOSDAeFw0xNDExMTEyMDQxMTRaFw0xNTAyMDkyMDQxMTVaMEYxRDBCBgNVBAMT
|
||||
O0pCTkg6WDJHWjpHS0hXOklaNkQ6TVNHNjpHUFlGOjQ0NTY6Q0U0NjpUNEo2OlZV
|
||||
V1E6RkRaVTpBTFk0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAECoQE4u9QsNH5
|
||||
FmoDfSQHojxMN/NoFF5qs1Tnp5M9oHTzwT+vFA2g6jArP+ZKl67nLanA/K4pFle8
|
||||
jgcCobScsKMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDSQAwRgIhANhTbxwevwYurL4GRP4PRreZEvSjgOJnQO0/7FGhzDct
|
||||
AiEA5gPXKid+i1xQ+ZjiNcuUzdAi828WRqmpPYVbpK18AbA=
|
||||
-----END CERTIFICATE-----
|
Binary file not shown.
126
Godeps/_workspace/src/github.com/docker/libtrust/tools/generate_trust_keys.go
generated
vendored
126
Godeps/_workspace/src/github.com/docker/libtrust/tools/generate_trust_keys.go
generated
vendored
|
@ -1,126 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"log"
|
||||
"math/big"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
func writeCertFile(filename string, certs []*x509.Certificate) error {
|
||||
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
for _, cert := range certs {
|
||||
err = pem.Encode(f, &pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateIntermediate(parent *x509.Certificate, key libtrust.PublicKey, parentKey libtrust.PrivateKey) (*x509.Certificate, error) {
|
||||
cert := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{
|
||||
CommonName: key.KeyID(),
|
||||
},
|
||||
NotBefore: time.Now().Add(-time.Second),
|
||||
NotAfter: time.Now().Add(90 * 24 * time.Hour),
|
||||
IsCA: true,
|
||||
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, cert, parent, key.CryptoPublicKey(), parentKey.CryptoPrivateKey())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func generateLeaf(parent *x509.Certificate, key libtrust.PublicKey, parentKey libtrust.PrivateKey) (*x509.Certificate, error) {
|
||||
cert := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(2),
|
||||
Subject: pkix.Name{
|
||||
CommonName: key.KeyID(),
|
||||
},
|
||||
NotBefore: time.Now().Add(-time.Second),
|
||||
NotAfter: time.Now().Add(90 * 24 * time.Hour),
|
||||
IsCA: true,
|
||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||
BasicConstraintsValid: true,
|
||||
}
|
||||
|
||||
certDER, err := x509.CreateCertificate(rand.Reader, cert, parent, key.CryptoPublicKey(), parentKey.CryptoPrivateKey())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
caKey, _ := libtrust.GenerateECP256PrivateKey()
|
||||
masterKey, _ := libtrust.GenerateECP256PrivateKey()
|
||||
trustKey, _ := libtrust.GenerateECP256PrivateKey()
|
||||
|
||||
log.Printf("Generated keys:\n\tCA: %s\n\tMaster: %s\n\tTrust: %s", caKey.KeyID(), masterKey.KeyID(), trustKey.KeyID())
|
||||
|
||||
libtrust.SaveKey("ca-key.json", caKey)
|
||||
libtrust.SaveKey("master-key.json", masterKey)
|
||||
libtrust.SaveKey("trust-key.json", trustKey)
|
||||
|
||||
// TODO better CA function
|
||||
ca, err := libtrust.GenerateCACert(caKey, caKey.PublicKey())
|
||||
if err != nil {
|
||||
log.Fatalf("Error generating CA: %s", err)
|
||||
}
|
||||
|
||||
err = writeCertFile("ca.pem", []*x509.Certificate{ca})
|
||||
if err != nil {
|
||||
log.Fatalf("Error writing CA pem file: %s", err)
|
||||
}
|
||||
|
||||
masterCert, err := generateIntermediate(ca, masterKey.PublicKey(), caKey)
|
||||
if err != nil {
|
||||
log.Fatalf("Error generating master certificate: %s", err)
|
||||
}
|
||||
// Generate Master Server certificate, signed by CA
|
||||
// Output master-key.json
|
||||
|
||||
leafCert, err := generateLeaf(masterCert, trustKey.PublicKey(), masterKey)
|
||||
if err != nil {
|
||||
log.Fatalf("Error generating leaf certificate: %s", err)
|
||||
}
|
||||
// Generate key, from key trust Server certificate, signed by master
|
||||
// Output cert.pem (both trust server and master certificate), key.json
|
||||
|
||||
err = writeCertFile("cert.pem", []*x509.Certificate{leafCert, masterCert})
|
||||
if err != nil {
|
||||
log.Fatalf("Error generating cert pem file")
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"crv": "P-256",
|
||||
"d": "VTn3fGowJO6x7dYNvmYPIMt2nLJRMOVM-GG6ZdlSUS8",
|
||||
"kid": "JBNH:X2GZ:GKHW:IZ6D:MSG6:GPYF:4456:CE46:T4J6:VUWQ:FDZU:ALY4",
|
||||
"kty": "EC",
|
||||
"x": "CoQE4u9QsNH5FmoDfSQHojxMN_NoFF5qs1Tnp5M9oHQ",
|
||||
"y": "88E_rxQNoOowKz_mSpeu5y2pwPyuKRZXvI4HAqG0nLA"
|
||||
}
|
Binary file not shown.
|
@ -1,28 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
func main() {
|
||||
input, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading stdin: %s", err)
|
||||
}
|
||||
|
||||
sig, err := libtrust.ParsePrettySignature(input, "signatures")
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing pretty signature: %s", err)
|
||||
}
|
||||
|
||||
jws, err := sig.JWS()
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating JWS: %s", err)
|
||||
}
|
||||
|
||||
os.Stdout.Write(jws)
|
||||
}
|
Binary file not shown.
|
@ -1,44 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
func main() {
|
||||
keyFile, err := filepath.Abs("/home/derek/.docker/key.json")
|
||||
if err != nil {
|
||||
log.Fatalf("Error getting path: %s", err)
|
||||
}
|
||||
pk, err := libtrust.LoadKeyFile(keyFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading key file: %s", err)
|
||||
}
|
||||
|
||||
input, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading stdin: %s", err)
|
||||
}
|
||||
|
||||
sig, err := libtrust.NewJSONSignature(input)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating JSON signature: %s", err)
|
||||
}
|
||||
|
||||
err = sig.Sign(pk)
|
||||
if err != nil {
|
||||
log.Fatalf("Error signing: %s", err)
|
||||
}
|
||||
//log.Printf("Private key (%s): %s", pk.KeyType(), pk.KeyID())
|
||||
jws, err := sig.JWS()
|
||||
if err != nil {
|
||||
log.Fatalf("Error getting JWS: %s", err)
|
||||
}
|
||||
|
||||
os.Stdout.Write(jws)
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"crv": "P-256",
|
||||
"d": "M_n9CSpMg51gEhx1vf28QcQGjxcT43sps1-F8Yzo9dQ",
|
||||
"kid": "WWAC:5DVG:RVXY:APSC:CEZW:TOP4:MMHJ:FEZT:WMOJ:HVLX:HQMP:6JWK",
|
||||
"kty": "EC",
|
||||
"x": "fmp8Xhfx-d5lFYD-Ouxq3b75DzAnCGjY2iGGwcGRpkk",
|
||||
"y": "pOXbJUfSZskgipe7GiR2HKBnZY0dT3mMLWkYhCi9jZs"
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/codegangsta/cli"
|
||||
)
|
||||
|
||||
func main() {
|
||||
dir := path.Join(getHomeDir(), ".docker")
|
||||
app := cli.NewApp()
|
||||
app.Name = "trust"
|
||||
app.Usage = "manage keys and grants"
|
||||
app.Commands = []cli.Command{
|
||||
cli.Command{
|
||||
Name: "tag",
|
||||
Usage: "create or update a tag",
|
||||
Action: actionTag,
|
||||
Flags: []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "commit",
|
||||
Usage: "Whether to immediately commit tag",
|
||||
},
|
||||
},
|
||||
},
|
||||
cli.Command{
|
||||
Name: "untag",
|
||||
Usage: "delete a tag",
|
||||
Action: actionUntag,
|
||||
Flags: []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "ref,r",
|
||||
Value: "",
|
||||
Usage: "Tag or Hash reference",
|
||||
},
|
||||
},
|
||||
},
|
||||
cli.Command{
|
||||
Name: "commit",
|
||||
Usage: "commit target changes",
|
||||
Action: actionCommit,
|
||||
},
|
||||
}
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "dir,d",
|
||||
Value: dir,
|
||||
Usage: "Directory for repository",
|
||||
},
|
||||
}
|
||||
|
||||
app.Run(os.Args)
|
||||
}
|
||||
|
||||
func getHomeDir() string {
|
||||
if runtime.GOOS == "windows" {
|
||||
return os.Getenv("USERPROFILE")
|
||||
}
|
||||
return os.Getenv("HOME")
|
||||
}
|
||||
|
||||
func updateRepository() {
|
||||
log.Infof("Getting updated targets from repository")
|
||||
log.Infof("Verifying local keys match repository")
|
||||
}
|
||||
|
||||
func actionTag(c *cli.Context) {
|
||||
hash := c.Args().First()
|
||||
if len(hash) == 0 {
|
||||
cli.ShowCommandHelp(c, "tag")
|
||||
return
|
||||
}
|
||||
|
||||
tag := c.Args().Get(1)
|
||||
if len(tag) == 0 {
|
||||
cli.ShowCommandHelp(c, "tag")
|
||||
return
|
||||
}
|
||||
// TODO parse tag (Get last index of ':')
|
||||
|
||||
updateRepository()
|
||||
log.Infof("Checking hash exists for name")
|
||||
log.Infof("Tagging %s as %s", hash, tag)
|
||||
fmt.Printf("%s+ %s %s%s\n", Green, tag, hash, Clear)
|
||||
}
|
||||
|
||||
func actionUntag(c *cli.Context) {
|
||||
tagOrHash := c.Args().First()
|
||||
if len(tagOrHash) == 0 {
|
||||
cli.ShowCommandHelp(c, "untag")
|
||||
return
|
||||
}
|
||||
updateRepository()
|
||||
fmt.Printf("%s+ %s%s\n", Red, tagOrHash, Clear)
|
||||
}
|
||||
|
||||
func actionCommit(c *cli.Context) {
|
||||
}
|
||||
|
||||
const Black = "\x1b[30;1m"
|
||||
const Red = "\x1b[31;1m"
|
||||
const Green = "\x1b[32;1m"
|
||||
const Yellow = "\x1b[33;1m"
|
||||
const Blue = "\x1b[34;1m"
|
||||
const Magenta = "\x1b[35;1m"
|
||||
const Cyan = "\x1b[36;1m"
|
||||
const White = "\x1b[37;1m"
|
||||
const Clear = "\x1b[0m"
|
Binary file not shown.
11
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/client/integtest/ca.pem
generated
vendored
11
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/client/integtest/ca.pem
generated
vendored
|
@ -1,11 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnzCCAUSgAwIBAgIBADAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdT
|
||||
N1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6
|
||||
M1hYSjAeFw0xNDA5MDUyMzA3NTRaFw0yNDA5MDkyMzA3NTRaMEYxRDBCBgNVBAMT
|
||||
O0dXNEY6R1M3UDoyMktZOlNRWE06Rkk3NDpTUUJTOktSWFI6VjRUUjpJRzZROjdO
|
||||
TEw6T0pJUzozWFhKMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEB23slGpLr16M
|
||||
TAJ3MaGVZK6QYEb/l5EZkpnrPcdX6JTGCSuDy7jpEYtsAyp6Du1jEwZuwR2nF1ni
|
||||
WI39XxM1lKMjMCEwDgYDVR0PAQH/BAQDAgAEMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDSQAwRgIhAOFl3YnbPAPd7hRbh2Wpe0RrtZ0KAZGpjKk3C1ZhQEG4
|
||||
AiEAh6R8OVclkFNXFbQML8X5uEL+3d7wB+osNU0OlHFaiiQ=
|
||||
-----END CERTIFICATE-----
|
38
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/client/integtest/exercise.go
generated
vendored
38
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/client/integtest/exercise.go
generated
vendored
|
@ -1,38 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
"github.com/docker/libtrust/trustapi/client"
|
||||
)
|
||||
|
||||
func exerciseBaseGraph(c *client.TrustClient, name string) []byte {
|
||||
statement, err := c.GetBaseGraph(name)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
b, err := statement.Bytes()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func main() {
|
||||
pool, err := libtrust.LoadCertificatePool("./ca.pem")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
c := client.NewTrustClient("localhost:8092", pool)
|
||||
b1 := exerciseBaseGraph(c, "empty")
|
||||
b2 := exerciseBaseGraph(c, "dmcgowan")
|
||||
_, err = c.GetBaseGraph("empty-bad")
|
||||
if err == nil {
|
||||
log.Fatalf("Did not receive error getting empty-bad")
|
||||
}
|
||||
log.Printf("Expected error getting empty-bad: %s", err)
|
||||
|
||||
log.Printf("Statements:\nempty:\n%s\n\ndmcgowan\n%s", b1, b2)
|
||||
}
|
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/dmcgowan.json
generated
vendored
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/dmcgowan.json
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/dmcgowan/my-app",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
}
|
||||
],
|
||||
"expiration": "2014-12-11T23:14:27.32116801Z",
|
||||
"issuedAt": "2014-09-12T23:14:27.321168201Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "SugIISjm_U1HD2ua6BK8mocu6H5mLBVsnMNXPue-J0yuEh1PeVy5waojA0eRUCXETlO1W9vJ-GO7W0YpVSFqtw",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjMwNywiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTA5LTEyVDIzOjE0OjI3WiJ9"
|
||||
}
|
||||
]
|
||||
}
|
19
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/empty-bad.json
generated
vendored
19
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/empty-bad.json
generated
vendored
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [],
|
||||
"expiration": "2014-12-19T23:28:35.400329125Z",
|
||||
"issuedAt": "2014-09-12T23:28:35.40032963Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "Dp_mTZUSBDIkXpl1qBM4u__wGfcpD-zeyWXkVAHL9NnCWfSXAECKwyYiAJCv4dYRplotrZVzuIMt6DnQpe34_w",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjEzOCwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTA5LTEyVDIzOjI4OjM1WiJ9"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [],
|
||||
"expiration": "2014-12-11T23:28:35.400329125Z",
|
||||
"issuedAt": "2014-09-12T23:28:35.40032963Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "Dp_mTZUSBDIkXpl1qBM4u__wGfcpD-zeyWXkVAHL9NnCWfSXAECKwyYiAJCv4dYRplotrZVzuIMt6DnQpe34_w",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjEzOCwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTA5LTEyVDIzOjI4OjM1WiJ9"
|
||||
}
|
||||
]
|
||||
}
|
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/official.json
generated
vendored
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/official.json
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/dmcgowan",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
}
|
||||
],
|
||||
"expiration": "2014-12-16T01:25:16.569500374Z",
|
||||
"issuedAt": "2014-09-17T01:25:16.569500504Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "RSDqbBfd2OWdEpKTxO0V6rep-cwIGiayzb8VBqVYCTcj22JrogKjmUDji4Nz965s6vw7NG9cezdaRAJB3tpflA",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjMwMSwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTA5LTE3VDAxOjI1OjE2WiJ9"
|
||||
}
|
||||
]
|
||||
}
|
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/official2.json
generated
vendored
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/official2.json
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/library",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
}
|
||||
],
|
||||
"expiration": "2014-12-29T00:08:20.565183779Z",
|
||||
"issuedAt": "2014-09-30T00:08:20.565183976Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "uYMwXO869mGDkq7jrE-xfXHcY96JkcIZt_lLWidUtK4Z3-VH8UJx8j-bHQh0rD3C4Olsx7SY5dDOO_Zq60_i1w",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjMwMCwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTA5LTMwVDAwOjA4OjIwWiJ9"
|
||||
}
|
||||
]
|
||||
}
|
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/official_bak.json
generated
vendored
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/official_bak.json
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/dmcgowan",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
}
|
||||
],
|
||||
"expiration": "2014-12-16T01:25:16.569500374Z",
|
||||
"issuedAt": "2014-09-17T01:25:16.569500504Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "RSDqbBfd2OWdEpKTxO0V6rep-cwIGiayzb8VBqVYCTcj22JrogKjmUDji4Nz965s6vw7NG9cezdaRAJB3tpflA",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjMwMSwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTA5LTE3VDAxOjI1OjE2WiJ9"
|
||||
}
|
||||
]
|
||||
}
|
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/official_exp.json
generated
vendored
25
Godeps/_workspace/src/github.com/docker/libtrust/trustapi/server/official_exp.json
generated
vendored
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"revocations": [],
|
||||
"grants": [
|
||||
{
|
||||
"subject": "/dmcgowan",
|
||||
"permission": 15,
|
||||
"grantee": "LYRA:YAG2:QQKS:376F:QQXY:3UNK:SXH7:K6ES:Y5AU:XUN5:ZLVY:KBYL"
|
||||
}
|
||||
],
|
||||
"expiration": "2014-09-17T15:50:31.965636009Z",
|
||||
"issuedAt": "2014-09-17T15:48:31.965636222Z",
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"alg": "ES256",
|
||||
"x5c": [
|
||||
"MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcyQjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkCIDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U",
|
||||
"MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdTN1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMTO09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNVTEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80eo8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8UwRaw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsCIQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg=="
|
||||
]
|
||||
},
|
||||
"signature": "N7fvmmwZbuV70PdzlQ75EDCHapnMLWDXD3iwOxv0KpTLFF2udh7liT888GVoCSFFae187KsymOT-EO4EXTPJDQ",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjMwMSwiZm9ybWF0VGFpbCI6IkNuMCIsInRpbWUiOiIyMDE0LTA5LTE3VDE1OjQ4OjMxWiJ9"
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
|
@ -1,60 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/docker/libtrust/trustapi"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
var baseGraphs map[string][]byte
|
||||
var baseDirectory string
|
||||
|
||||
func init() {
|
||||
baseGraphs = map[string][]byte{}
|
||||
flag.StringVar(&baseDirectory, "base", "", "Base directory for base graph files")
|
||||
}
|
||||
|
||||
func register(r *mux.Router) {
|
||||
r.Get("graphbase").HandlerFunc(handleBaseGraph)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
files, err := filepath.Glob(filepath.Join(baseDirectory, "*.json"))
|
||||
if err != nil {
|
||||
log.Fatalf("Error loading json files: %s", err)
|
||||
}
|
||||
for _, f := range files {
|
||||
name := filepath.Base(f)
|
||||
name = name[:len(name)-5]
|
||||
b, err := ioutil.ReadFile(f)
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading file: %s", err)
|
||||
}
|
||||
baseGraphs[name] = b
|
||||
}
|
||||
|
||||
r := trustapi.NewRouter("localhost")
|
||||
register(r)
|
||||
http.ListenAndServe("localhost:8092", r)
|
||||
}
|
||||
|
||||
func handleBaseGraph(rw http.ResponseWriter, r *http.Request) {
|
||||
graphname := mux.Vars(r)["graphname"]
|
||||
log.Printf("Getting graph: %s", graphname)
|
||||
b, ok := baseGraphs[graphname]
|
||||
if !ok {
|
||||
rw.WriteHeader(404)
|
||||
fmt.Fprintf(rw, "base graph not found")
|
||||
return
|
||||
}
|
||||
|
||||
rw.Header().Set("Content-Type", "application/json")
|
||||
rw.Write(b)
|
||||
}
|
|
@ -1,101 +0,0 @@
|
|||
mode: set
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:18.32,23.2 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:28.49,30.31 2 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:47.2,47.28 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:30.31,35.30 5 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:35.30,37.15 2 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:41.4,41.18 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:44.4,44.25 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:37.15,40.5 2 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:41.18,43.5 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:50.55,55.33 5 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:62.2,62.20 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:55.33,57.14 2 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:60.3,60.24 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:57.14,59.4 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:65.39,66.34 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:71.2,71.14 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:66.34,67.53 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:67.53,69.4 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:76.43,78.2 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:80.147,81.20 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:84.2,86.31 3 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:101.2,101.34 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:115.2,115.14 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:81.20,83.3 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:86.31,87.21 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:90.3,91.48 2 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:87.21,88.12 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:91.48,92.40 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:92.40,93.24 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:93.24,95.6 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:96.6,98.5 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:101.34,103.14 2 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:111.3,111.86 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:103.14,107.4 3 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:107.5,109.4 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:111.86,113.4 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:118.100,120.2 1 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:122.109,124.53 2 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:131.2,132.20 2 1
|
||||
github.com/docker/libtrust/trustgraph/memory_graph.go:124.53,130.3 5 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:34.56,41.2 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:53.38,55.2 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:60.45,62.2 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:65.79,67.16 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:70.2,71.16 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:74.2,75.16 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:78.2,80.16 3 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:84.2,84.22 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:95.2,97.24 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:67.16,69.3 1 0
|
||||
github.com/docker/libtrust/trustgraph/statement.go:71.16,73.3 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:75.16,77.3 1 0
|
||||
github.com/docker/libtrust/trustgraph/statement.go:80.16,82.3 1 0
|
||||
github.com/docker/libtrust/trustgraph/statement.go:84.22,86.17 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:86.17,88.4 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:89.4,91.17 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:91.17,93.4 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:102.151,105.16 3 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:108.2,109.16 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:112.2,116.16 4 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:120.2,121.16 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:124.2,125.16 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:129.2,129.24 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:105.16,107.3 1 0
|
||||
github.com/docker/libtrust/trustgraph/statement.go:109.16,111.3 1 0
|
||||
github.com/docker/libtrust/trustgraph/statement.go:116.16,118.3 1 0
|
||||
github.com/docker/libtrust/trustgraph/statement.go:121.16,123.3 1 0
|
||||
github.com/docker/libtrust/trustgraph/statement.go:125.16,127.3 1 0
|
||||
github.com/docker/libtrust/trustgraph/statement.go:134.34,136.2 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:138.44,140.2 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:142.39,144.2 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:148.96,150.39 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:155.2,160.35 5 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:204.2,205.34 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:209.2,209.35 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:150.39,151.43 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:151.43,153.4 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:160.35,161.56 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:164.3,164.42 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:181.3,181.52 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:161.56,163.4 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:164.42,170.31 5 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:170.31,172.16 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:176.5,177.26 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:172.16,175.6 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:181.52,187.31 5 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:194.4,194.19 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:187.31,189.16 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:192.5,192.26 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:189.16,190.11 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:194.19,195.39 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:195.39,196.54 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:196.54,198.7 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:205.34,207.3 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:213.62,215.31 2 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:220.2,222.36 3 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:226.2,226.27 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:215.31,216.29 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:216.29,218.4 1 1
|
||||
github.com/docker/libtrust/trustgraph/statement.go:222.36,225.3 2 1
|
8
Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/graphtool/ca-key.json
generated
vendored
8
Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/graphtool/ca-key.json
generated
vendored
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"crv": "P-256",
|
||||
"d": "T68FInnZjHW8c8Y3y8UKDEwVEfubGX7mP8X5EOpxRw0",
|
||||
"kid": "GW4F:GS7P:22KY:SQXM:FI74:SQBS:KRXR:V4TR:IG6Q:7NLL:OJIS:3XXJ",
|
||||
"kty": "EC",
|
||||
"x": "B23slGpLr16MTAJ3MaGVZK6QYEb_l5EZkpnrPcdX6JQ",
|
||||
"y": "xgkrg8u46RGLbAMqeg7tYxMGbsEdpxdZ4liN_V8TNZQ"
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnzCCAUSgAwIBAgIBADAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdT
|
||||
N1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6
|
||||
M1hYSjAeFw0xNDA5MDUyMzA3NTRaFw0yNDA5MDkyMzA3NTRaMEYxRDBCBgNVBAMT
|
||||
O0dXNEY6R1M3UDoyMktZOlNRWE06Rkk3NDpTUUJTOktSWFI6VjRUUjpJRzZROjdO
|
||||
TEw6T0pJUzozWFhKMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEB23slGpLr16M
|
||||
TAJ3MaGVZK6QYEb/l5EZkpnrPcdX6JTGCSuDy7jpEYtsAyp6Du1jEwZuwR2nF1ni
|
||||
WI39XxM1lKMjMCEwDgYDVR0PAQH/BAQDAgAEMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDSQAwRgIhAOFl3YnbPAPd7hRbh2Wpe0RrtZ0KAZGpjKk3C1ZhQEG4
|
||||
AiEAh6R8OVclkFNXFbQML8X5uEL+3d7wB+osNU0OlHFaiiQ=
|
||||
-----END CERTIFICATE-----
|
22
Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/graphtool/cert.pem
generated
vendored
22
Godeps/_workspace/src/github.com/docker/libtrust/trustgraph/graphtool/cert.pem
generated
vendored
|
@ -1,22 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnTCCAUSgAwIBAgIBAjAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztPUUlTOkcy
|
||||
QjQ6UDdRQjpHM1pJOlRIUE46WklUTTpVRFAyOlY3WlM6VVM2SDpDVUxEOlJJWkI6
|
||||
WDdQSTAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMT
|
||||
O1c1MlY6QldDUTpPVVk2OklRNU46WDVYRzpNN0tKOkdYNlA6VFdNUTpaRkhKOk02
|
||||
MzI6SzIzVjpYRjQ1MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG9rANGMaOxoZ
|
||||
4XzItNBpqrzZLe/hyMY/hnlXARER0rbEp5B5yl5sDYaXEI80VgpUGNvleFOVc7yN
|
||||
3rclT14tm6MjMCEwDgYDVR0PAQH/BAQDAgCAMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDRwAwRAIgQhkTTERnf/+2i1hM+hHivMngiciCQgqdcxo1UeK53fkC
|
||||
IDzml+Gk4oAFGGcsO3wdHqbxfjyGkNr8hxfuWoq6Wl3U
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBnjCCAUSgAwIBAgIBATAKBggqhkjOPQQDAjBGMUQwQgYDVQQDEztHVzRGOkdT
|
||||
N1A6MjJLWTpTUVhNOkZJNzQ6U1FCUzpLUlhSOlY0VFI6SUc2UTo3TkxMOk9KSVM6
|
||||
M1hYSjAeFw0xNDA5MTIyMzA3NTNaFw0xNDEyMTEyMzA3NTRaMEYxRDBCBgNVBAMT
|
||||
O09RSVM6RzJCNDpQN1FCOkczWkk6VEhQTjpaSVRNOlVEUDI6VjdaUzpVUzZIOkNV
|
||||
TEQ6UklaQjpYN1BJMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK0pEXXaql80e
|
||||
o8khKBUhwg8fXwDnc+QIR3CB86JnCViEWskUrBmQZvdc8JTDtxBCvfs9nG7yZ8Uw
|
||||
Raw6G9QdUqMjMCEwDgYDVR0PAQH/BAQDAgAGMA8GA1UdEwEB/wQFMAMBAf8wCgYI
|
||||
KoZIzj0EAwIDSAAwRQIgCA6aCc66+d2/yz47PmvvZy+GDudWXFxD6plt2KUtuGsC
|
||||
IQDykk/gYQ5MfIUlS8O+UEAwY7okfz6DxlpFGMVSO57gEg==
|
||||
-----END CERTIFICATE-----
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue