mirror of
https://github.com/rancher/os.git
synced 2025-09-02 07:15:41 +00:00
Cleanup ./vendor dir
This commit is contained in:
94
vendor/github.com/docker/libtrust/testutil/certificates.go
generated
vendored
94
vendor/github.com/docker/libtrust/testutil/certificates.go
generated
vendored
@@ -1,94 +0,0 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"math/big"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GenerateTrustCA generates a new certificate authority for testing.
|
||||
func GenerateTrustCA(pub crypto.PublicKey, priv crypto.PrivateKey) (*x509.Certificate, error) {
|
||||
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, pub, priv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// GenerateIntermediate generates an intermediate certificate for testing using
|
||||
// the parent certificate (likely a CA) and the provided keys.
|
||||
func GenerateIntermediate(key crypto.PublicKey, parentKey crypto.PrivateKey, parent *x509.Certificate) (*x509.Certificate, error) {
|
||||
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, parentKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
||||
|
||||
// GenerateTrustCert generates a new trust certificate for testing. Unlike the
|
||||
// intermediate certificates, this certificate should be used for signature
|
||||
// only, not creating certificates.
|
||||
func GenerateTrustCert(key crypto.PublicKey, parentKey crypto.PrivateKey, parent *x509.Certificate) (*x509.Certificate, error) {
|
||||
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, parentKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cert, err = x509.ParseCertificate(certDER)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cert, nil
|
||||
}
|
50
vendor/github.com/docker/libtrust/tlsdemo/README.md
generated
vendored
50
vendor/github.com/docker/libtrust/tlsdemo/README.md
generated
vendored
@@ -1,50 +0,0 @@
|
||||
## Libtrust TLS Config Demo
|
||||
|
||||
This program generates key pairs and trust files for a TLS client and server.
|
||||
|
||||
To generate the keys, run:
|
||||
|
||||
```
|
||||
$ go run genkeys.go
|
||||
```
|
||||
|
||||
The generated files are:
|
||||
|
||||
```
|
||||
$ ls -l client_data/ server_data/
|
||||
client_data/:
|
||||
total 24
|
||||
-rw------- 1 jlhawn staff 281 Aug 8 16:21 private_key.json
|
||||
-rw-r--r-- 1 jlhawn staff 225 Aug 8 16:21 public_key.json
|
||||
-rw-r--r-- 1 jlhawn staff 275 Aug 8 16:21 trusted_hosts.json
|
||||
|
||||
server_data/:
|
||||
total 24
|
||||
-rw-r--r-- 1 jlhawn staff 348 Aug 8 16:21 trusted_clients.json
|
||||
-rw------- 1 jlhawn staff 281 Aug 8 16:21 private_key.json
|
||||
-rw-r--r-- 1 jlhawn staff 225 Aug 8 16:21 public_key.json
|
||||
```
|
||||
|
||||
The private key and public key for the client and server are stored in `private_key.json` and `public_key.json`, respectively, and in their respective directories. They are represented as JSON Web Keys: JSON objects which represent either an ECDSA or RSA private key. The host keys trusted by the client are stored in `trusted_hosts.json` and contain a mapping of an internet address, `<HOSTNAME_OR_IP>:<PORT>`, to a JSON Web Key which is a JSON object representing either an ECDSA or RSA public key of the trusted server. The client keys trusted by the server are stored in `trusted_clients.json` and contain an array of JSON objects which contain a comment field which can be used describe the key and a JSON Web Key which is a JSON object representing either an ECDSA or RSA public key of the trusted client.
|
||||
|
||||
To start the server, run:
|
||||
|
||||
```
|
||||
$ go run server.go
|
||||
```
|
||||
|
||||
This starts an HTTPS server which listens on `localhost:8888`. The server configures itself with a certificate which is valid for both `localhost` and `127.0.0.1` and uses the key from `server_data/private_key.json`. It accepts connections from clients which present a certificate for a key that it is configured to trust from the `trusted_clients.json` file and returns a simple 'hello' message.
|
||||
|
||||
To make a request using the client, run:
|
||||
|
||||
```
|
||||
$ go run client.go
|
||||
```
|
||||
|
||||
This command creates an HTTPS client which makes a GET request to `https://localhost:8888`. The client configures itself with a certificate using the key from `client_data/private_key.json`. It only connects to a server which presents a certificate signed by the key specified for the `localhost:8888` address from `client_data/trusted_hosts.json` and made to be used for the `localhost` hostname. If the connection succeeds, it prints the response from the server.
|
||||
|
||||
The file `gencert.go` can be used to generate PEM encoded version of the client key and certificate. If you save them to `key.pem` and `cert.pem` respectively, you can use them with `curl` to test out the server (if it is still running).
|
||||
|
||||
```
|
||||
curl --cert cert.pem --key key.pem -k https://localhost:8888
|
||||
```
|
89
vendor/github.com/docker/libtrust/tlsdemo/client.go
generated
vendored
89
vendor/github.com/docker/libtrust/tlsdemo/client.go
generated
vendored
@@ -1,89 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
var (
|
||||
serverAddress = "localhost:8888"
|
||||
privateKeyFilename = "client_data/private_key.pem"
|
||||
trustedHostsFilename = "client_data/trusted_hosts.pem"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Load Client Key.
|
||||
clientKey, err := libtrust.LoadKeyFile(privateKeyFilename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Generate Client Certificate.
|
||||
selfSignedClientCert, err := libtrust.GenerateSelfSignedClientCert(clientKey)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Load trusted host keys.
|
||||
hostKeys, err := libtrust.LoadKeySetFile(trustedHostsFilename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Ensure the host we want to connect to is trusted!
|
||||
host, _, err := net.SplitHostPort(serverAddress)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
serverKeys, err := libtrust.FilterByHosts(hostKeys, host, false)
|
||||
if err != nil {
|
||||
log.Fatalf("%q is not a known and trusted host", host)
|
||||
}
|
||||
|
||||
// Generate a CA pool with the trusted host's key.
|
||||
caPool, err := libtrust.GenerateCACertPool(clientKey, serverKeys)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Create HTTP Client.
|
||||
client := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
Certificates: []tls.Certificate{
|
||||
tls.Certificate{
|
||||
Certificate: [][]byte{selfSignedClientCert.Raw},
|
||||
PrivateKey: clientKey.CryptoPrivateKey(),
|
||||
Leaf: selfSignedClientCert,
|
||||
},
|
||||
},
|
||||
RootCAs: caPool,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var makeRequest = func(url string) {
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Println(resp.Status)
|
||||
log.Println(string(body))
|
||||
}
|
||||
|
||||
// Make the request to the trusted server!
|
||||
makeRequest(fmt.Sprintf("https://%s", serverAddress))
|
||||
}
|
62
vendor/github.com/docker/libtrust/tlsdemo/gencert.go
generated
vendored
62
vendor/github.com/docker/libtrust/tlsdemo/gencert.go
generated
vendored
@@ -1,62 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
var (
|
||||
serverAddress = "localhost:8888"
|
||||
clientPrivateKeyFilename = "client_data/private_key.pem"
|
||||
trustedHostsFilename = "client_data/trusted_hosts.pem"
|
||||
)
|
||||
|
||||
func main() {
|
||||
key, err := libtrust.LoadKeyFile(clientPrivateKeyFilename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
keyPEMBlock, err := key.PEMBlock()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
encodedPrivKey := pem.EncodeToMemory(keyPEMBlock)
|
||||
fmt.Printf("Client Key:\n\n%s\n", string(encodedPrivKey))
|
||||
|
||||
cert, err := libtrust.GenerateSelfSignedClientCert(key)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
encodedCert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw})
|
||||
fmt.Printf("Client Cert:\n\n%s\n", string(encodedCert))
|
||||
|
||||
trustedServerKeys, err := libtrust.LoadKeySetFile(trustedHostsFilename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
hostname, _, err := net.SplitHostPort(serverAddress)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
trustedServerKeys, err = libtrust.FilterByHosts(trustedServerKeys, hostname, false)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
caCert, err := libtrust.GenerateCACert(key, trustedServerKeys[0])
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
encodedCert = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: caCert.Raw})
|
||||
fmt.Printf("CA Cert:\n\n%s\n", string(encodedCert))
|
||||
}
|
61
vendor/github.com/docker/libtrust/tlsdemo/genkeys.go
generated
vendored
61
vendor/github.com/docker/libtrust/tlsdemo/genkeys.go
generated
vendored
@@ -1,61 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Generate client key.
|
||||
clientKey, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Add a comment for the client key.
|
||||
clientKey.AddExtendedField("comment", "TLS Demo Client")
|
||||
|
||||
// Save the client key, public and private versions.
|
||||
err = libtrust.SaveKey("client_data/private_key.pem", clientKey)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err = libtrust.SavePublicKey("client_data/public_key.pem", clientKey.PublicKey())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Generate server key.
|
||||
serverKey, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Set the list of addresses to use for the server.
|
||||
serverKey.AddExtendedField("hosts", []string{"localhost", "docker.example.com"})
|
||||
|
||||
// Save the server key, public and private versions.
|
||||
err = libtrust.SaveKey("server_data/private_key.pem", serverKey)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err = libtrust.SavePublicKey("server_data/public_key.pem", serverKey.PublicKey())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Generate Authorized Keys file for server.
|
||||
err = libtrust.AddKeySetFile("server_data/trusted_clients.pem", clientKey.PublicKey())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Generate Known Host Keys file for client.
|
||||
err = libtrust.AddKeySetFile("client_data/trusted_hosts.pem", serverKey.PublicKey())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
80
vendor/github.com/docker/libtrust/tlsdemo/server.go
generated
vendored
80
vendor/github.com/docker/libtrust/tlsdemo/server.go
generated
vendored
@@ -1,80 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"html"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
var (
|
||||
serverAddress = "localhost:8888"
|
||||
privateKeyFilename = "server_data/private_key.pem"
|
||||
authorizedClientsFilename = "server_data/trusted_clients.pem"
|
||||
)
|
||||
|
||||
func requestHandler(w http.ResponseWriter, r *http.Request) {
|
||||
clientCert := r.TLS.PeerCertificates[0]
|
||||
keyID := clientCert.Subject.CommonName
|
||||
log.Printf("Request from keyID: %s\n", keyID)
|
||||
fmt.Fprintf(w, "Hello, client! I'm a server! And you are %T: %s.\n", clientCert.PublicKey, html.EscapeString(keyID))
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Load server key.
|
||||
serverKey, err := libtrust.LoadKeyFile(privateKeyFilename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Generate server certificate.
|
||||
selfSignedServerCert, err := libtrust.GenerateSelfSignedServerCert(
|
||||
serverKey, []string{"localhost"}, []net.IP{net.ParseIP("127.0.0.1")},
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Load authorized client keys.
|
||||
authorizedClients, err := libtrust.LoadKeySetFile(authorizedClientsFilename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Create CA pool using trusted client keys.
|
||||
caPool, err := libtrust.GenerateCACertPool(serverKey, authorizedClients)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Create TLS config, requiring client certificates.
|
||||
tlsConfig := &tls.Config{
|
||||
Certificates: []tls.Certificate{
|
||||
tls.Certificate{
|
||||
Certificate: [][]byte{selfSignedServerCert.Raw},
|
||||
PrivateKey: serverKey.CryptoPrivateKey(),
|
||||
Leaf: selfSignedServerCert,
|
||||
},
|
||||
},
|
||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||
ClientCAs: caPool,
|
||||
}
|
||||
|
||||
// Create HTTP server with simple request handler.
|
||||
server := &http.Server{
|
||||
Addr: serverAddress,
|
||||
Handler: http.HandlerFunc(requestHandler),
|
||||
}
|
||||
|
||||
// Listen and server HTTPS using the libtrust TLS config.
|
||||
listener, err := net.Listen("tcp", server.Addr)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
tlsListener := tls.NewListener(listener, tlsConfig)
|
||||
server.Serve(tlsListener)
|
||||
}
|
50
vendor/github.com/docker/libtrust/trustgraph/graph.go
generated
vendored
50
vendor/github.com/docker/libtrust/trustgraph/graph.go
generated
vendored
@@ -1,50 +0,0 @@
|
||||
package trustgraph
|
||||
|
||||
import "github.com/docker/libtrust"
|
||||
|
||||
// TrustGraph represents a graph of authorization mapping
|
||||
// public keys to nodes and grants between nodes.
|
||||
type TrustGraph interface {
|
||||
// Verifies that the given public key is allowed to perform
|
||||
// the given action on the given node according to the trust
|
||||
// graph.
|
||||
Verify(libtrust.PublicKey, string, uint16) (bool, error)
|
||||
|
||||
// GetGrants returns an array of all grant chains which are used to
|
||||
// allow the requested permission.
|
||||
GetGrants(libtrust.PublicKey, string, uint16) ([][]*Grant, error)
|
||||
}
|
||||
|
||||
// Grant represents a transfer of permission from one part of the
|
||||
// trust graph to another. This is the only way to delegate
|
||||
// permission between two different sub trees in the graph.
|
||||
type Grant struct {
|
||||
// Subject is the namespace being granted
|
||||
Subject string
|
||||
|
||||
// Permissions is a bit map of permissions
|
||||
Permission uint16
|
||||
|
||||
// Grantee represents the node being granted
|
||||
// a permission scope. The grantee can be
|
||||
// either a namespace item or a key id where namespace
|
||||
// items will always start with a '/'.
|
||||
Grantee string
|
||||
|
||||
// statement represents the statement used to create
|
||||
// this object.
|
||||
statement *Statement
|
||||
}
|
||||
|
||||
// Permissions
|
||||
// Read node 0x01 (can read node, no sub nodes)
|
||||
// Write node 0x02 (can write to node object, cannot create subnodes)
|
||||
// Read subtree 0x04 (delegates read to each sub node)
|
||||
// Write subtree 0x08 (delegates write to each sub node, included create on the subject)
|
||||
//
|
||||
// Permission shortcuts
|
||||
// ReadItem = 0x01
|
||||
// WriteItem = 0x03
|
||||
// ReadAccess = 0x07
|
||||
// WriteAccess = 0x0F
|
||||
// Delegate = 0x0F
|
133
vendor/github.com/docker/libtrust/trustgraph/memory_graph.go
generated
vendored
133
vendor/github.com/docker/libtrust/trustgraph/memory_graph.go
generated
vendored
@@ -1,133 +0,0 @@
|
||||
package trustgraph
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
type grantNode struct {
|
||||
grants []*Grant
|
||||
children map[string]*grantNode
|
||||
}
|
||||
|
||||
type memoryGraph struct {
|
||||
roots map[string]*grantNode
|
||||
}
|
||||
|
||||
func newGrantNode() *grantNode {
|
||||
return &grantNode{
|
||||
grants: []*Grant{},
|
||||
children: map[string]*grantNode{},
|
||||
}
|
||||
}
|
||||
|
||||
// NewMemoryGraph returns a new in memory trust graph created from
|
||||
// a static list of grants. This graph is immutable after creation
|
||||
// and any alterations should create a new instance.
|
||||
func NewMemoryGraph(grants []*Grant) TrustGraph {
|
||||
roots := map[string]*grantNode{}
|
||||
for _, grant := range grants {
|
||||
parts := strings.Split(grant.Grantee, "/")
|
||||
nodes := roots
|
||||
var node *grantNode
|
||||
var nodeOk bool
|
||||
for _, part := range parts {
|
||||
node, nodeOk = nodes[part]
|
||||
if !nodeOk {
|
||||
node = newGrantNode()
|
||||
nodes[part] = node
|
||||
}
|
||||
if part != "" {
|
||||
node.grants = append(node.grants, grant)
|
||||
}
|
||||
nodes = node.children
|
||||
}
|
||||
}
|
||||
return &memoryGraph{roots}
|
||||
}
|
||||
|
||||
func (g *memoryGraph) getGrants(name string) []*Grant {
|
||||
nameParts := strings.Split(name, "/")
|
||||
nodes := g.roots
|
||||
var node *grantNode
|
||||
var nodeOk bool
|
||||
for _, part := range nameParts {
|
||||
node, nodeOk = nodes[part]
|
||||
if !nodeOk {
|
||||
return nil
|
||||
}
|
||||
nodes = node.children
|
||||
}
|
||||
return node.grants
|
||||
}
|
||||
|
||||
func isSubName(name, sub string) bool {
|
||||
if strings.HasPrefix(name, sub) {
|
||||
if len(name) == len(sub) || name[len(sub)] == '/' {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type walkFunc func(*Grant, []*Grant) bool
|
||||
|
||||
func foundWalkFunc(*Grant, []*Grant) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *memoryGraph) walkGrants(start, target string, permission uint16, f walkFunc, chain []*Grant, visited map[*Grant]bool, collect bool) bool {
|
||||
if visited == nil {
|
||||
visited = map[*Grant]bool{}
|
||||
}
|
||||
grants := g.getGrants(start)
|
||||
subGrants := make([]*Grant, 0, len(grants))
|
||||
for _, grant := range grants {
|
||||
if visited[grant] {
|
||||
continue
|
||||
}
|
||||
visited[grant] = true
|
||||
if grant.Permission&permission == permission {
|
||||
if isSubName(target, grant.Subject) {
|
||||
if f(grant, chain) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
subGrants = append(subGrants, grant)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, grant := range subGrants {
|
||||
var chainCopy []*Grant
|
||||
if collect {
|
||||
chainCopy = make([]*Grant, len(chain)+1)
|
||||
copy(chainCopy, chain)
|
||||
chainCopy[len(chainCopy)-1] = grant
|
||||
} else {
|
||||
chainCopy = nil
|
||||
}
|
||||
|
||||
if g.walkGrants(grant.Subject, target, permission, f, chainCopy, visited, collect) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (g *memoryGraph) Verify(key libtrust.PublicKey, node string, permission uint16) (bool, error) {
|
||||
return g.walkGrants(key.KeyID(), node, permission, foundWalkFunc, nil, nil, false), nil
|
||||
}
|
||||
|
||||
func (g *memoryGraph) GetGrants(key libtrust.PublicKey, node string, permission uint16) ([][]*Grant, error) {
|
||||
grants := [][]*Grant{}
|
||||
collect := func(grant *Grant, chain []*Grant) bool {
|
||||
grantChain := make([]*Grant, len(chain)+1)
|
||||
copy(grantChain, chain)
|
||||
grantChain[len(grantChain)-1] = grant
|
||||
grants = append(grants, grantChain)
|
||||
return false
|
||||
}
|
||||
g.walkGrants(key.KeyID(), node, permission, collect, nil, nil, true)
|
||||
return grants, nil
|
||||
}
|
174
vendor/github.com/docker/libtrust/trustgraph/memory_graph_test.go
generated
vendored
174
vendor/github.com/docker/libtrust/trustgraph/memory_graph_test.go
generated
vendored
@@ -1,174 +0,0 @@
|
||||
package trustgraph
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
func createTestKeysAndGrants(count int) ([]*Grant, []libtrust.PrivateKey) {
|
||||
grants := make([]*Grant, count)
|
||||
keys := make([]libtrust.PrivateKey, count)
|
||||
for i := 0; i < count; i++ {
|
||||
pk, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
grant := &Grant{
|
||||
Subject: fmt.Sprintf("/user-%d", i+1),
|
||||
Permission: 0x0f,
|
||||
Grantee: pk.KeyID(),
|
||||
}
|
||||
keys[i] = pk
|
||||
grants[i] = grant
|
||||
}
|
||||
return grants, keys
|
||||
}
|
||||
|
||||
func testVerified(t *testing.T, g TrustGraph, k libtrust.PublicKey, keyName, target string, permission uint16) {
|
||||
if ok, err := g.Verify(k, target, permission); err != nil {
|
||||
t.Fatalf("Unexpected error during verification: %s", err)
|
||||
} else if !ok {
|
||||
t.Errorf("key failed verification\n\tKey: %s(%s)\n\tNamespace: %s", keyName, k.KeyID(), target)
|
||||
}
|
||||
}
|
||||
|
||||
func testNotVerified(t *testing.T, g TrustGraph, k libtrust.PublicKey, keyName, target string, permission uint16) {
|
||||
if ok, err := g.Verify(k, target, permission); err != nil {
|
||||
t.Fatalf("Unexpected error during verification: %s", err)
|
||||
} else if ok {
|
||||
t.Errorf("key should have failed verification\n\tKey: %s(%s)\n\tNamespace: %s", keyName, k.KeyID(), target)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerify(t *testing.T) {
|
||||
grants, keys := createTestKeysAndGrants(4)
|
||||
extraGrants := make([]*Grant, 3)
|
||||
extraGrants[0] = &Grant{
|
||||
Subject: "/user-3",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-2",
|
||||
}
|
||||
extraGrants[1] = &Grant{
|
||||
Subject: "/user-3/sub-project",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-4",
|
||||
}
|
||||
extraGrants[2] = &Grant{
|
||||
Subject: "/user-4",
|
||||
Permission: 0x07,
|
||||
Grantee: "/user-1",
|
||||
}
|
||||
grants = append(grants, extraGrants...)
|
||||
|
||||
g := NewMemoryGraph(grants)
|
||||
|
||||
testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1", 0x0f)
|
||||
testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1/some-project/sub-value", 0x0f)
|
||||
testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-4", 0x07)
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2/", 0x0f)
|
||||
testVerified(t, g, keys[2].PublicKey(), "user-key-3", "/user-3/sub-value", 0x0f)
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3/sub-value", 0x0f)
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3", 0x0f)
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3/", 0x0f)
|
||||
testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3/sub-project", 0x0f)
|
||||
testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3/sub-project/app", 0x0f)
|
||||
testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-4", 0x0f)
|
||||
|
||||
testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-2", 0x0f)
|
||||
testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-3/sub-value", 0x0f)
|
||||
testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-4", 0x0f)
|
||||
testNotVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-1/", 0x0f)
|
||||
testNotVerified(t, g, keys[2].PublicKey(), "user-key-3", "/user-2", 0x0f)
|
||||
testNotVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-4", 0x0f)
|
||||
testNotVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3", 0x0f)
|
||||
}
|
||||
|
||||
func TestCircularWalk(t *testing.T) {
|
||||
grants, keys := createTestKeysAndGrants(3)
|
||||
user1Grant := &Grant{
|
||||
Subject: "/user-2",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-1",
|
||||
}
|
||||
user2Grant := &Grant{
|
||||
Subject: "/user-1",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-2",
|
||||
}
|
||||
grants = append(grants, user1Grant, user2Grant)
|
||||
|
||||
g := NewMemoryGraph(grants)
|
||||
|
||||
testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1", 0x0f)
|
||||
testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-2", 0x0f)
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2", 0x0f)
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-1", 0x0f)
|
||||
testVerified(t, g, keys[2].PublicKey(), "user-key-3", "/user-3", 0x0f)
|
||||
|
||||
testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-3", 0x0f)
|
||||
testNotVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3", 0x0f)
|
||||
}
|
||||
|
||||
func assertGrantSame(t *testing.T, actual, expected *Grant) {
|
||||
if actual != expected {
|
||||
t.Fatalf("Unexpected grant retrieved\n\tExpected: %v\n\tActual: %v", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetGrants(t *testing.T) {
|
||||
grants, keys := createTestKeysAndGrants(5)
|
||||
extraGrants := make([]*Grant, 4)
|
||||
extraGrants[0] = &Grant{
|
||||
Subject: "/user-3/friend-project",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-2/friends",
|
||||
}
|
||||
extraGrants[1] = &Grant{
|
||||
Subject: "/user-3/sub-project",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-4",
|
||||
}
|
||||
extraGrants[2] = &Grant{
|
||||
Subject: "/user-2/friends",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-5/fun-project",
|
||||
}
|
||||
extraGrants[3] = &Grant{
|
||||
Subject: "/user-5/fun-project",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-1",
|
||||
}
|
||||
grants = append(grants, extraGrants...)
|
||||
|
||||
g := NewMemoryGraph(grants)
|
||||
|
||||
grantChains, err := g.GetGrants(keys[3], "/user-3/sub-project/specific-app", 0x0f)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting grants: %s", err)
|
||||
}
|
||||
if len(grantChains) != 1 {
|
||||
t.Fatalf("Expected number of grant chains returned, expected %d, received %d", 1, len(grantChains))
|
||||
}
|
||||
if len(grantChains[0]) != 2 {
|
||||
t.Fatalf("Unexpected number of grants retrieved\n\tExpected: %d\n\tActual: %d", 2, len(grantChains[0]))
|
||||
}
|
||||
assertGrantSame(t, grantChains[0][0], grants[3])
|
||||
assertGrantSame(t, grantChains[0][1], extraGrants[1])
|
||||
|
||||
grantChains, err = g.GetGrants(keys[0], "/user-3/friend-project/fun-app", 0x0f)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting grants: %s", err)
|
||||
}
|
||||
if len(grantChains) != 1 {
|
||||
t.Fatalf("Expected number of grant chains returned, expected %d, received %d", 1, len(grantChains))
|
||||
}
|
||||
if len(grantChains[0]) != 4 {
|
||||
t.Fatalf("Unexpected number of grants retrieved\n\tExpected: %d\n\tActual: %d", 2, len(grantChains[0]))
|
||||
}
|
||||
assertGrantSame(t, grantChains[0][0], grants[0])
|
||||
assertGrantSame(t, grantChains[0][1], extraGrants[3])
|
||||
assertGrantSame(t, grantChains[0][2], extraGrants[2])
|
||||
assertGrantSame(t, grantChains[0][3], extraGrants[0])
|
||||
}
|
227
vendor/github.com/docker/libtrust/trustgraph/statement.go
generated
vendored
227
vendor/github.com/docker/libtrust/trustgraph/statement.go
generated
vendored
@@ -1,227 +0,0 @@
|
||||
package trustgraph
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
)
|
||||
|
||||
type jsonGrant struct {
|
||||
Subject string `json:"subject"`
|
||||
Permission uint16 `json:"permission"`
|
||||
Grantee string `json:"grantee"`
|
||||
}
|
||||
|
||||
type jsonRevocation struct {
|
||||
Subject string `json:"subject"`
|
||||
Revocation uint16 `json:"revocation"`
|
||||
Grantee string `json:"grantee"`
|
||||
}
|
||||
|
||||
type jsonStatement struct {
|
||||
Revocations []*jsonRevocation `json:"revocations"`
|
||||
Grants []*jsonGrant `json:"grants"`
|
||||
Expiration time.Time `json:"expiration"`
|
||||
IssuedAt time.Time `json:"issuedAt"`
|
||||
}
|
||||
|
||||
func (g *jsonGrant) Grant(statement *Statement) *Grant {
|
||||
return &Grant{
|
||||
Subject: g.Subject,
|
||||
Permission: g.Permission,
|
||||
Grantee: g.Grantee,
|
||||
statement: statement,
|
||||
}
|
||||
}
|
||||
|
||||
// Statement represents a set of grants made from a verifiable
|
||||
// authority. A statement has an expiration associated with it
|
||||
// set by the authority.
|
||||
type Statement struct {
|
||||
jsonStatement
|
||||
|
||||
signature *libtrust.JSONSignature
|
||||
}
|
||||
|
||||
// IsExpired returns whether the statement has expired
|
||||
func (s *Statement) IsExpired() bool {
|
||||
return s.Expiration.Before(time.Now().Add(-10 * time.Second))
|
||||
}
|
||||
|
||||
// Bytes returns an indented json representation of the statement
|
||||
// in a byte array. This value can be written to a file or stream
|
||||
// without alteration.
|
||||
func (s *Statement) Bytes() ([]byte, error) {
|
||||
return s.signature.PrettySignature("signatures")
|
||||
}
|
||||
|
||||
// LoadStatement loads and verifies a statement from an input stream.
|
||||
func LoadStatement(r io.Reader, authority *x509.CertPool) (*Statement, error) {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
js, err := libtrust.ParsePrettySignature(b, "signatures")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
payload, err := js.Payload()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var statement Statement
|
||||
err = json.Unmarshal(payload, &statement.jsonStatement)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if authority == nil {
|
||||
_, err = js.Verify()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
_, err = js.VerifyChains(authority)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
statement.signature = js
|
||||
|
||||
return &statement, nil
|
||||
}
|
||||
|
||||
// CreateStatements creates and signs a statement from a stream of grants
|
||||
// and revocations in a JSON array.
|
||||
func CreateStatement(grants, revocations io.Reader, expiration time.Duration, key libtrust.PrivateKey, chain []*x509.Certificate) (*Statement, error) {
|
||||
var statement Statement
|
||||
err := json.NewDecoder(grants).Decode(&statement.jsonStatement.Grants)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = json.NewDecoder(revocations).Decode(&statement.jsonStatement.Revocations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
statement.jsonStatement.Expiration = time.Now().UTC().Add(expiration)
|
||||
statement.jsonStatement.IssuedAt = time.Now().UTC()
|
||||
|
||||
b, err := json.MarshalIndent(&statement.jsonStatement, "", " ")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
statement.signature, err = libtrust.NewJSONSignature(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = statement.signature.SignWithChain(key, chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &statement, nil
|
||||
}
|
||||
|
||||
type statementList []*Statement
|
||||
|
||||
func (s statementList) Len() int {
|
||||
return len(s)
|
||||
}
|
||||
|
||||
func (s statementList) Less(i, j int) bool {
|
||||
return s[i].IssuedAt.Before(s[j].IssuedAt)
|
||||
}
|
||||
|
||||
func (s statementList) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
|
||||
// CollapseStatements returns a single list of the valid statements as well as the
|
||||
// time when the next grant will expire.
|
||||
func CollapseStatements(statements []*Statement, useExpired bool) ([]*Grant, time.Time, error) {
|
||||
sorted := make(statementList, 0, len(statements))
|
||||
for _, statement := range statements {
|
||||
if useExpired || !statement.IsExpired() {
|
||||
sorted = append(sorted, statement)
|
||||
}
|
||||
}
|
||||
sort.Sort(sorted)
|
||||
|
||||
var minExpired time.Time
|
||||
var grantCount int
|
||||
roots := map[string]*grantNode{}
|
||||
for i, statement := range sorted {
|
||||
if statement.Expiration.Before(minExpired) || i == 0 {
|
||||
minExpired = statement.Expiration
|
||||
}
|
||||
for _, grant := range statement.Grants {
|
||||
parts := strings.Split(grant.Grantee, "/")
|
||||
nodes := roots
|
||||
g := grant.Grant(statement)
|
||||
grantCount = grantCount + 1
|
||||
|
||||
for _, part := range parts {
|
||||
node, nodeOk := nodes[part]
|
||||
if !nodeOk {
|
||||
node = newGrantNode()
|
||||
nodes[part] = node
|
||||
}
|
||||
node.grants = append(node.grants, g)
|
||||
nodes = node.children
|
||||
}
|
||||
}
|
||||
|
||||
for _, revocation := range statement.Revocations {
|
||||
parts := strings.Split(revocation.Grantee, "/")
|
||||
nodes := roots
|
||||
|
||||
var node *grantNode
|
||||
var nodeOk bool
|
||||
for _, part := range parts {
|
||||
node, nodeOk = nodes[part]
|
||||
if !nodeOk {
|
||||
break
|
||||
}
|
||||
nodes = node.children
|
||||
}
|
||||
if node != nil {
|
||||
for _, grant := range node.grants {
|
||||
if isSubName(grant.Subject, revocation.Subject) {
|
||||
grant.Permission = grant.Permission &^ revocation.Revocation
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retGrants := make([]*Grant, 0, grantCount)
|
||||
for _, rootNodes := range roots {
|
||||
retGrants = append(retGrants, rootNodes.grants...)
|
||||
}
|
||||
|
||||
return retGrants, minExpired, nil
|
||||
}
|
||||
|
||||
// FilterStatements filters the statements to statements including the given grants.
|
||||
func FilterStatements(grants []*Grant) ([]*Statement, error) {
|
||||
statements := map[*Statement]bool{}
|
||||
for _, grant := range grants {
|
||||
if grant.statement != nil {
|
||||
statements[grant.statement] = true
|
||||
}
|
||||
}
|
||||
retStatements := make([]*Statement, len(statements))
|
||||
var i int
|
||||
for statement := range statements {
|
||||
retStatements[i] = statement
|
||||
i++
|
||||
}
|
||||
return retStatements, nil
|
||||
}
|
417
vendor/github.com/docker/libtrust/trustgraph/statement_test.go
generated
vendored
417
vendor/github.com/docker/libtrust/trustgraph/statement_test.go
generated
vendored
@@ -1,417 +0,0 @@
|
||||
package trustgraph
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/libtrust"
|
||||
"github.com/docker/libtrust/testutil"
|
||||
)
|
||||
|
||||
const testStatementExpiration = time.Hour * 5
|
||||
|
||||
func generateStatement(grants []*Grant, key libtrust.PrivateKey, chain []*x509.Certificate) (*Statement, error) {
|
||||
var statement Statement
|
||||
|
||||
statement.Grants = make([]*jsonGrant, len(grants))
|
||||
for i, grant := range grants {
|
||||
statement.Grants[i] = &jsonGrant{
|
||||
Subject: grant.Subject,
|
||||
Permission: grant.Permission,
|
||||
Grantee: grant.Grantee,
|
||||
}
|
||||
}
|
||||
statement.IssuedAt = time.Now()
|
||||
statement.Expiration = time.Now().Add(testStatementExpiration)
|
||||
statement.Revocations = make([]*jsonRevocation, 0)
|
||||
|
||||
marshalled, err := json.MarshalIndent(statement.jsonStatement, "", " ")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sig, err := libtrust.NewJSONSignature(marshalled)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = sig.SignWithChain(key, chain)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
statement.signature = sig
|
||||
|
||||
return &statement, nil
|
||||
}
|
||||
|
||||
func generateTrustChain(t *testing.T, chainLen int) (libtrust.PrivateKey, *x509.CertPool, []*x509.Certificate) {
|
||||
caKey, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating key: %s", err)
|
||||
}
|
||||
ca, err := testutil.GenerateTrustCA(caKey.CryptoPublicKey(), caKey.CryptoPrivateKey())
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating ca: %s", err)
|
||||
}
|
||||
|
||||
parent := ca
|
||||
parentKey := caKey
|
||||
chain := make([]*x509.Certificate, chainLen)
|
||||
for i := chainLen - 1; i > 0; i-- {
|
||||
intermediatekey, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Error generate key: %s", err)
|
||||
}
|
||||
chain[i], err = testutil.GenerateIntermediate(intermediatekey.CryptoPublicKey(), parentKey.CryptoPrivateKey(), parent)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating intermdiate certificate: %s", err)
|
||||
}
|
||||
parent = chain[i]
|
||||
parentKey = intermediatekey
|
||||
}
|
||||
trustKey, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatalf("Error generate key: %s", err)
|
||||
}
|
||||
chain[0], err = testutil.GenerateTrustCert(trustKey.CryptoPublicKey(), parentKey.CryptoPrivateKey(), parent)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generate trust cert: %s", err)
|
||||
}
|
||||
|
||||
caPool := x509.NewCertPool()
|
||||
caPool.AddCert(ca)
|
||||
|
||||
return trustKey, caPool, chain
|
||||
}
|
||||
|
||||
func TestLoadStatement(t *testing.T) {
|
||||
grantCount := 4
|
||||
grants, _ := createTestKeysAndGrants(grantCount)
|
||||
|
||||
trustKey, caPool, chain := generateTrustChain(t, 6)
|
||||
|
||||
statement, err := generateStatement(grants, trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating statement: %s", err)
|
||||
}
|
||||
|
||||
statementBytes, err := statement.Bytes()
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting statement bytes: %s", err)
|
||||
}
|
||||
|
||||
s2, err := LoadStatement(bytes.NewReader(statementBytes), caPool)
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading statement: %s", err)
|
||||
}
|
||||
if len(s2.Grants) != grantCount {
|
||||
t.Fatalf("Unexpected grant length\n\tExpected: %d\n\tActual: %d", grantCount, len(s2.Grants))
|
||||
}
|
||||
|
||||
pool := x509.NewCertPool()
|
||||
_, err = LoadStatement(bytes.NewReader(statementBytes), pool)
|
||||
if err == nil {
|
||||
t.Fatalf("No error thrown verifying without an authority")
|
||||
} else if _, ok := err.(x509.UnknownAuthorityError); !ok {
|
||||
t.Fatalf("Unexpected error verifying without authority: %s", err)
|
||||
}
|
||||
|
||||
s2, err = LoadStatement(bytes.NewReader(statementBytes), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading statement: %s", err)
|
||||
}
|
||||
if len(s2.Grants) != grantCount {
|
||||
t.Fatalf("Unexpected grant length\n\tExpected: %d\n\tActual: %d", grantCount, len(s2.Grants))
|
||||
}
|
||||
|
||||
badData := make([]byte, len(statementBytes))
|
||||
copy(badData, statementBytes)
|
||||
badData[0] = '['
|
||||
_, err = LoadStatement(bytes.NewReader(badData), nil)
|
||||
if err == nil {
|
||||
t.Fatalf("No error thrown parsing bad json")
|
||||
}
|
||||
|
||||
alteredData := make([]byte, len(statementBytes))
|
||||
copy(alteredData, statementBytes)
|
||||
alteredData[30] = '0'
|
||||
_, err = LoadStatement(bytes.NewReader(alteredData), nil)
|
||||
if err == nil {
|
||||
t.Fatalf("No error thrown from bad data")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollapseGrants(t *testing.T) {
|
||||
grantCount := 8
|
||||
grants, keys := createTestKeysAndGrants(grantCount)
|
||||
linkGrants := make([]*Grant, 4)
|
||||
linkGrants[0] = &Grant{
|
||||
Subject: "/user-3",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-2",
|
||||
}
|
||||
linkGrants[1] = &Grant{
|
||||
Subject: "/user-3/sub-project",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-4",
|
||||
}
|
||||
linkGrants[2] = &Grant{
|
||||
Subject: "/user-6",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-7",
|
||||
}
|
||||
linkGrants[3] = &Grant{
|
||||
Subject: "/user-6/sub-project/specific-app",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-5",
|
||||
}
|
||||
trustKey, pool, chain := generateTrustChain(t, 3)
|
||||
|
||||
statements := make([]*Statement, 3)
|
||||
var err error
|
||||
statements[0], err = generateStatement(grants[0:4], trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating statement: %s", err)
|
||||
}
|
||||
statements[1], err = generateStatement(grants[4:], trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating statement: %s", err)
|
||||
}
|
||||
statements[2], err = generateStatement(linkGrants, trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating statement: %s", err)
|
||||
}
|
||||
|
||||
statementsCopy := make([]*Statement, len(statements))
|
||||
for i, statement := range statements {
|
||||
b, err := statement.Bytes()
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting statement bytes: %s", err)
|
||||
}
|
||||
verifiedStatement, err := LoadStatement(bytes.NewReader(b), pool)
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading statement: %s", err)
|
||||
}
|
||||
// Force sort by reversing order
|
||||
statementsCopy[len(statementsCopy)-i-1] = verifiedStatement
|
||||
}
|
||||
statements = statementsCopy
|
||||
|
||||
collapsedGrants, expiration, err := CollapseStatements(statements, false)
|
||||
if len(collapsedGrants) != 12 {
|
||||
t.Fatalf("Unexpected number of grants\n\tExpected: %d\n\tActual: %d", 12, len(collapsedGrants))
|
||||
}
|
||||
if expiration.After(time.Now().Add(time.Hour*5)) || expiration.Before(time.Now()) {
|
||||
t.Fatalf("Unexpected expiration time: %s", expiration.String())
|
||||
}
|
||||
g := NewMemoryGraph(collapsedGrants)
|
||||
|
||||
testVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1", 0x0f)
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2", 0x0f)
|
||||
testVerified(t, g, keys[2].PublicKey(), "user-key-3", "/user-3", 0x0f)
|
||||
testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-4", 0x0f)
|
||||
testVerified(t, g, keys[4].PublicKey(), "user-key-5", "/user-5", 0x0f)
|
||||
testVerified(t, g, keys[5].PublicKey(), "user-key-6", "/user-6", 0x0f)
|
||||
testVerified(t, g, keys[6].PublicKey(), "user-key-7", "/user-7", 0x0f)
|
||||
testVerified(t, g, keys[7].PublicKey(), "user-key-8", "/user-8", 0x0f)
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3", 0x0f)
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-3/sub-project/specific-app", 0x0f)
|
||||
testVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3/sub-project", 0x0f)
|
||||
testVerified(t, g, keys[6].PublicKey(), "user-key-7", "/user-6", 0x0f)
|
||||
testVerified(t, g, keys[6].PublicKey(), "user-key-7", "/user-6/sub-project/specific-app", 0x0f)
|
||||
testVerified(t, g, keys[4].PublicKey(), "user-key-5", "/user-6/sub-project/specific-app", 0x0f)
|
||||
|
||||
testNotVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-3", 0x0f)
|
||||
testNotVerified(t, g, keys[3].PublicKey(), "user-key-4", "/user-6/sub-project", 0x0f)
|
||||
testNotVerified(t, g, keys[4].PublicKey(), "user-key-5", "/user-6/sub-project", 0x0f)
|
||||
|
||||
// Add revocation grant
|
||||
statements = append(statements, &Statement{
|
||||
jsonStatement{
|
||||
IssuedAt: time.Now(),
|
||||
Expiration: time.Now().Add(testStatementExpiration),
|
||||
Grants: []*jsonGrant{},
|
||||
Revocations: []*jsonRevocation{
|
||||
&jsonRevocation{
|
||||
Subject: "/user-1",
|
||||
Revocation: 0x0f,
|
||||
Grantee: keys[0].KeyID(),
|
||||
},
|
||||
&jsonRevocation{
|
||||
Subject: "/user-2",
|
||||
Revocation: 0x08,
|
||||
Grantee: keys[1].KeyID(),
|
||||
},
|
||||
&jsonRevocation{
|
||||
Subject: "/user-6",
|
||||
Revocation: 0x0f,
|
||||
Grantee: "/user-7",
|
||||
},
|
||||
&jsonRevocation{
|
||||
Subject: "/user-9",
|
||||
Revocation: 0x0f,
|
||||
Grantee: "/user-10",
|
||||
},
|
||||
},
|
||||
},
|
||||
nil,
|
||||
})
|
||||
|
||||
collapsedGrants, expiration, err = CollapseStatements(statements, false)
|
||||
if len(collapsedGrants) != 12 {
|
||||
t.Fatalf("Unexpected number of grants\n\tExpected: %d\n\tActual: %d", 12, len(collapsedGrants))
|
||||
}
|
||||
if expiration.After(time.Now().Add(time.Hour*5)) || expiration.Before(time.Now()) {
|
||||
t.Fatalf("Unexpected expiration time: %s", expiration.String())
|
||||
}
|
||||
g = NewMemoryGraph(collapsedGrants)
|
||||
|
||||
testNotVerified(t, g, keys[0].PublicKey(), "user-key-1", "/user-1", 0x0f)
|
||||
testNotVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2", 0x0f)
|
||||
testNotVerified(t, g, keys[6].PublicKey(), "user-key-7", "/user-6/sub-project/specific-app", 0x0f)
|
||||
|
||||
testVerified(t, g, keys[1].PublicKey(), "user-key-2", "/user-2", 0x07)
|
||||
}
|
||||
|
||||
func TestFilterStatements(t *testing.T) {
|
||||
grantCount := 8
|
||||
grants, keys := createTestKeysAndGrants(grantCount)
|
||||
linkGrants := make([]*Grant, 3)
|
||||
linkGrants[0] = &Grant{
|
||||
Subject: "/user-3",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-2",
|
||||
}
|
||||
linkGrants[1] = &Grant{
|
||||
Subject: "/user-5",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-4",
|
||||
}
|
||||
linkGrants[2] = &Grant{
|
||||
Subject: "/user-7",
|
||||
Permission: 0x0f,
|
||||
Grantee: "/user-6",
|
||||
}
|
||||
|
||||
trustKey, _, chain := generateTrustChain(t, 3)
|
||||
|
||||
statements := make([]*Statement, 5)
|
||||
var err error
|
||||
statements[0], err = generateStatement(grants[0:2], trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating statement: %s", err)
|
||||
}
|
||||
statements[1], err = generateStatement(grants[2:4], trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating statement: %s", err)
|
||||
}
|
||||
statements[2], err = generateStatement(grants[4:6], trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating statement: %s", err)
|
||||
}
|
||||
statements[3], err = generateStatement(grants[6:], trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating statement: %s", err)
|
||||
}
|
||||
statements[4], err = generateStatement(linkGrants, trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error generating statement: %s", err)
|
||||
}
|
||||
collapsed, _, err := CollapseStatements(statements, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Error collapsing grants: %s", err)
|
||||
}
|
||||
|
||||
// Filter 1, all 5 statements
|
||||
filter1, err := FilterStatements(collapsed)
|
||||
if err != nil {
|
||||
t.Fatalf("Error filtering statements: %s", err)
|
||||
}
|
||||
if len(filter1) != 5 {
|
||||
t.Fatalf("Wrong number of statements, expected %d, received %d", 5, len(filter1))
|
||||
}
|
||||
|
||||
// Filter 2, one statement
|
||||
filter2, err := FilterStatements([]*Grant{collapsed[0]})
|
||||
if err != nil {
|
||||
t.Fatalf("Error filtering statements: %s", err)
|
||||
}
|
||||
if len(filter2) != 1 {
|
||||
t.Fatalf("Wrong number of statements, expected %d, received %d", 1, len(filter2))
|
||||
}
|
||||
|
||||
// Filter 3, 2 statements, from graph lookup
|
||||
g := NewMemoryGraph(collapsed)
|
||||
lookupGrants, err := g.GetGrants(keys[1], "/user-3", 0x0f)
|
||||
if err != nil {
|
||||
t.Fatalf("Error looking up grants: %s", err)
|
||||
}
|
||||
if len(lookupGrants) != 1 {
|
||||
t.Fatalf("Wrong numberof grant chains returned from lookup, expected %d, received %d", 1, len(lookupGrants))
|
||||
}
|
||||
if len(lookupGrants[0]) != 2 {
|
||||
t.Fatalf("Wrong number of grants looked up, expected %d, received %d", 2, len(lookupGrants))
|
||||
}
|
||||
filter3, err := FilterStatements(lookupGrants[0])
|
||||
if err != nil {
|
||||
t.Fatalf("Error filtering statements: %s", err)
|
||||
}
|
||||
if len(filter3) != 2 {
|
||||
t.Fatalf("Wrong number of statements, expected %d, received %d", 2, len(filter3))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestCreateStatement(t *testing.T) {
|
||||
grantJSON := bytes.NewReader([]byte(`[
|
||||
{
|
||||
"subject": "/user-2",
|
||||
"permission": 15,
|
||||
"grantee": "/user-1"
|
||||
},
|
||||
{
|
||||
"subject": "/user-7",
|
||||
"permission": 1,
|
||||
"grantee": "/user-9"
|
||||
},
|
||||
{
|
||||
"subject": "/user-3",
|
||||
"permission": 15,
|
||||
"grantee": "/user-2"
|
||||
}
|
||||
]`))
|
||||
revocationJSON := bytes.NewReader([]byte(`[
|
||||
{
|
||||
"subject": "user-8",
|
||||
"revocation": 12,
|
||||
"grantee": "user-9"
|
||||
}
|
||||
]`))
|
||||
|
||||
trustKey, pool, chain := generateTrustChain(t, 3)
|
||||
|
||||
statement, err := CreateStatement(grantJSON, revocationJSON, testStatementExpiration, trustKey, chain)
|
||||
if err != nil {
|
||||
t.Fatalf("Error creating statement: %s", err)
|
||||
}
|
||||
|
||||
b, err := statement.Bytes()
|
||||
if err != nil {
|
||||
t.Fatalf("Error retrieving bytes: %s", err)
|
||||
}
|
||||
|
||||
verified, err := LoadStatement(bytes.NewReader(b), pool)
|
||||
if err != nil {
|
||||
t.Fatalf("Error loading statement: %s", err)
|
||||
}
|
||||
|
||||
if len(verified.Grants) != 3 {
|
||||
t.Errorf("Unexpected number of grants, expected %d, received %d", 3, len(verified.Grants))
|
||||
}
|
||||
|
||||
if len(verified.Revocations) != 1 {
|
||||
t.Errorf("Unexpected number of revocations, expected %d, received %d", 1, len(verified.Revocations))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user