Merge pull request #1498 from hashicorp/pki-list

PKI List Functionality
This commit is contained in:
Laura Bennett 2016-06-08 15:42:50 -04:00
commit c21ef90dba
4 changed files with 195 additions and 0 deletions

View File

@ -48,6 +48,7 @@ func Backend() *framework.Backend {
pathFetchCRL(&b),
pathFetchCRLViaCertPath(&b),
pathFetchValid(&b),
pathFetchListCerts(&b),
pathRevoke(&b),
pathTidy(&b),
},

View File

@ -1784,6 +1784,133 @@ 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 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
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")
}
// 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 (
rsaCAKey string = `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA1eKB2nFbRqTFs7KyZjbzB5VRCBbnLZfEXVP1c3bHe+YGjlfl

View File

@ -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

View File

@ -423,6 +423,50 @@ subpath for interactive help output.
</dd>
</dl>
### /pki/certs/
#### LIST
<dl class="api">
<dt>Description</dt>
<dd>
Returns a list of the current certificates by serial number only.
</dd>
<dt>Method</dt>
<dd>GET</dd>
<dt>URL</dt>
<dd>`/pki/certs/?list=true`</dd>
<dt>Parameters</dt>
<dd>
None
</dd>
<dt>Returns</dt>
<dd>
```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
}
...
```
</dd>
</dl>
### /pki/config/ca
#### POST