From 5d945067dedf250add87c589f7dc4a56d2424287 Mon Sep 17 00:00:00 2001 From: Laura Bennett Date: Wed, 8 Jun 2016 11:46:58 -0400 Subject: [PATCH 1/4] Add PKI listing --- builtin/logical/pki/backend.go | 1 + builtin/logical/pki/backend_test.go | 101 ++++++++++++++++++++++++++++ builtin/logical/pki/path_fetch.go | 23 +++++++ 3 files changed, 125 insertions(+) diff --git a/builtin/logical/pki/backend.go b/builtin/logical/pki/backend.go index 210c710c2b..bf514df38e 100644 --- a/builtin/logical/pki/backend.go +++ b/builtin/logical/pki/backend.go @@ -48,6 +48,7 @@ func Backend() *framework.Backend { pathFetchCRL(&b), pathFetchCRLViaCertPath(&b), pathFetchValid(&b), + pathFetchListCerts(&b), pathRevoke(&b), pathTidy(&b), }, diff --git a/builtin/logical/pki/backend_test.go b/builtin/logical/pki/backend_test.go index f1efe6d3f3..f71a4c29a5 100644 --- a/builtin/logical/pki/backend_test.go +++ b/builtin/logical/pki/backend_test.go @@ -1784,6 +1784,107 @@ func generateRoleSteps(t *testing.T, useCSRs bool) []logicaltest.TestStep { return ret } +func TestBackend_PathFetchCertList(t *testing.T) { + // create the backend + config := logical.TestBackendConfig() + storage := &logical.InmemStorage{} + config.StorageView = storage + + b := Backend() + _, err := b.Setup(config) + if err != nil { + t.Fatal(err) + } + + // generate root + rootData := map[string]interface{}{ + "common_name": "test.com", + "ttl": "6h", + } + + resp, err := b.HandleRequest(&logical.Request{ + Operation: logical.UpdateOperation, + Path: "root/generate/internal", + Storage: storage, + Data: rootData, + }) + if resp != nil && resp.IsError() { + t.Fatalf("failed to generate root, %#v", resp) + } + if err != nil { + t.Fatal(err) + } + + // config urls + urlsData := map[string]interface{}{ + "issuing_certificates": "http://127.0.0.1:8200/v1/pki/ca", + "crl_distribution_points": "http://127.0.0.1:8200/v1/pki/crl", + } + + resp, err = b.HandleRequest(&logical.Request{ + Operation: logical.UpdateOperation, + Path: "config/urls", + Storage: storage, + Data: urlsData, + }) + if resp != nil && resp.IsError() { + t.Fatalf("failed to config urls, %#v", resp) + } + if err != nil { + t.Fatal(err) + } + + // create a role entry + roleData := map[string]interface{}{ + "allowed_domains": "test.com", + "allow_subdomains": "true", + "max_ttl": "4h", + } + + resp, err = b.HandleRequest(&logical.Request{ + Operation: logical.UpdateOperation, + Path: "roles/test-example", + Storage: storage, + Data: roleData, + }) + if resp != nil && resp.IsError() { + t.Fatalf("failed to create a role, %#v", resp) + } + if err != nil { + t.Fatal(err) + } + + // issue a couple of certs + certData := map[string]interface{}{ + "common_name": "example.test.com", + } + resp, err = b.HandleRequest(&logical.Request{ + Operation: logical.UpdateOperation, + Path: "issue/test-example", + Storage: storage, + Data: certData, + }) + if resp != nil && resp.IsError() { + t.Fatalf("failed to issue a cert, %#v", resp) + } + if err != nil { + t.Fatal(err) + } + + // list certs + resp, err = b.HandleRequest(&logical.Request{ + Operation: logical.ListOperation, + Path: "certs", + Storage: storage, + }) + if resp != nil && resp.IsError() { + t.Fatalf("failed to list certs, %#v", resp) + } + if err != nil { + t.Fatal(err) + } +} + const ( rsaCAKey string = `-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA1eKB2nFbRqTFs7KyZjbzB5VRCBbnLZfEXVP1c3bHe+YGjlfl diff --git a/builtin/logical/pki/path_fetch.go b/builtin/logical/pki/path_fetch.go index ed63682e2b..b37e9ff0fe 100644 --- a/builtin/logical/pki/path_fetch.go +++ b/builtin/logical/pki/path_fetch.go @@ -73,6 +73,29 @@ func pathFetchCRLViaCertPath(b *backend) *framework.Path { } } +// This returns the list of serial numbers for certs +func pathFetchListCerts(b *backend) *framework.Path { + return &framework.Path{ + Pattern: "certs/?$", + + Callbacks: map[logical.Operation]framework.OperationFunc{ + logical.ListOperation: b.pathFetchCertList, + }, + + HelpSynopsis: pathFetchHelpSyn, + HelpDescription: pathFetchHelpDesc, + } +} + +func (b *backend) pathFetchCertList(req *logical.Request, data *framework.FieldData) (response *logical.Response, retErr error) { + entries, err := req.Storage.List("certs/") + if err != nil { + return nil, err + } + + return logical.ListResponse(entries), nil +} + func (b *backend) pathFetchRead(req *logical.Request, data *framework.FieldData) (response *logical.Response, retErr error) { var serial, pemType, contentType string var certEntry, revokedEntry *logical.StorageEntry From 44b1f5fc2532c9c7f67aae1cd8ec54fd1c1a647c Mon Sep 17 00:00:00 2001 From: LLBennett Date: Wed, 8 Jun 2016 16:49:10 +0000 Subject: [PATCH 2/4] Updates to the test based on feedback. --- builtin/logical/pki/backend_test.go | 56 +++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/builtin/logical/pki/backend_test.go b/builtin/logical/pki/backend_test.go index f71a4c29a5..29ab6fe8e0 100644 --- a/builtin/logical/pki/backend_test.go +++ b/builtin/logical/pki/backend_test.go @@ -1854,21 +1854,26 @@ func TestBackend_PathFetchCertList(t *testing.T) { t.Fatal(err) } - // issue a couple of certs - certData := map[string]interface{}{ - "common_name": "example.test.com", - } - resp, err = b.HandleRequest(&logical.Request{ - Operation: logical.UpdateOperation, - Path: "issue/test-example", - Storage: storage, - Data: certData, - }) - if resp != nil && resp.IsError() { - t.Fatalf("failed to issue a cert, %#v", resp) - } - if err != nil { - t.Fatal(err) + // issue some certs + i := 1 + for i < 10 { + certData := map[string]interface{}{ + "common_name": "example.test.com", + } + resp, err = b.HandleRequest(&logical.Request{ + Operation: logical.UpdateOperation, + Path: "issue/test-example", + Storage: storage, + Data: certData, + }) + if resp != nil && resp.IsError() { + t.Fatalf("failed to issue a cert, %#v", resp) + } + if err != nil { + t.Fatal(err) + } + + i = i + 1 } // list certs @@ -1883,6 +1888,27 @@ func TestBackend_PathFetchCertList(t *testing.T) { if err != nil { t.Fatal(err) } + // check that the root and 9 additional certs are all listed + if len(resp.Data["keys"].([]string)) != 10 { + t.Fatalf("failed to list all 10 certs") + } + + // list certs/ + resp, err = b.HandleRequest(&logical.Request{ + Operation: logical.ListOperation, + Path: "certs/", + Storage: storage, + }) + if resp != nil && resp.IsError() { + t.Fatalf("failed to list certs, %#v", resp) + } + if err != nil { + t.Fatal(err) + } + // check that the root and 9 additional certs are all listed + if len(resp.Data["keys"].([]string)) != 10 { + t.Fatalf("failed to list all 10 certs") + } } const ( From 2b3f6d59a5cd6777a664b241eab4f2175bd71a28 Mon Sep 17 00:00:00 2001 From: Laura Bennett Date: Wed, 8 Jun 2016 14:37:57 -0400 Subject: [PATCH 3/4] Updates for pki/certs list functionality --- website/source/docs/secrets/pki/index.html.md | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/website/source/docs/secrets/pki/index.html.md b/website/source/docs/secrets/pki/index.html.md index f8da8092c3..9814414498 100644 --- a/website/source/docs/secrets/pki/index.html.md +++ b/website/source/docs/secrets/pki/index.html.md @@ -423,6 +423,50 @@ subpath for interactive help output. +### /pki/certs/ +#### LIST + +
+
Description
+
+ Returns a list of the current certificates by serial number only. +
+ +
Method
+
GET
+ +
URL
+
`/certs/?list=true`
+ +
Parameters
+
+ None +
+ +
Returns
+
+ + ```javascript + { + "lease_id":"", + "renewable":false, + "lease_duration":0, + "data":{ + "keys":[ + "17:67:16:b0:b9:45:58:c0:3a:29:e3:cb:d6:98:33:7a:a6:3b:66:c1", + "26:0f:76:93:73:cb:3f:a0:7a:ff:97:85:42:48:3a:aa:e5:96:03:21" + ] + }, + "wrap_info":null, + "warnings":null, + "auth":null + } + ... + ``` + +
+
+ ### /pki/config/ca #### POST From 8fb5ca046ca99fa13a218ae2afdec252e878b1ce Mon Sep 17 00:00:00 2001 From: Laura Bennett Date: Wed, 8 Jun 2016 14:53:33 -0400 Subject: [PATCH 4/4] url fix --- website/source/docs/secrets/pki/index.html.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/docs/secrets/pki/index.html.md b/website/source/docs/secrets/pki/index.html.md index 9814414498..f0f9d13d8c 100644 --- a/website/source/docs/secrets/pki/index.html.md +++ b/website/source/docs/secrets/pki/index.html.md @@ -436,7 +436,7 @@ subpath for interactive help output.
GET
URL
-
`/certs/?list=true`
+
`/pki/certs/?list=true`
Parameters