mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-18 12:37:02 +02:00
Merge pull request #1498 from hashicorp/pki-list
PKI List Functionality
This commit is contained in:
commit
c21ef90dba
@ -48,6 +48,7 @@ func Backend() *framework.Backend {
|
|||||||
pathFetchCRL(&b),
|
pathFetchCRL(&b),
|
||||||
pathFetchCRLViaCertPath(&b),
|
pathFetchCRLViaCertPath(&b),
|
||||||
pathFetchValid(&b),
|
pathFetchValid(&b),
|
||||||
|
pathFetchListCerts(&b),
|
||||||
pathRevoke(&b),
|
pathRevoke(&b),
|
||||||
pathTidy(&b),
|
pathTidy(&b),
|
||||||
},
|
},
|
||||||
|
@ -1784,6 +1784,133 @@ func generateRoleSteps(t *testing.T, useCSRs bool) []logicaltest.TestStep {
|
|||||||
return ret
|
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 (
|
const (
|
||||||
rsaCAKey string = `-----BEGIN RSA PRIVATE KEY-----
|
rsaCAKey string = `-----BEGIN RSA PRIVATE KEY-----
|
||||||
MIIEpAIBAAKCAQEA1eKB2nFbRqTFs7KyZjbzB5VRCBbnLZfEXVP1c3bHe+YGjlfl
|
MIIEpAIBAAKCAQEA1eKB2nFbRqTFs7KyZjbzB5VRCBbnLZfEXVP1c3bHe+YGjlfl
|
||||||
|
@ -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) {
|
func (b *backend) pathFetchRead(req *logical.Request, data *framework.FieldData) (response *logical.Response, retErr error) {
|
||||||
var serial, pemType, contentType string
|
var serial, pemType, contentType string
|
||||||
var certEntry, revokedEntry *logical.StorageEntry
|
var certEntry, revokedEntry *logical.StorageEntry
|
||||||
|
@ -423,6 +423,50 @@ subpath for interactive help output.
|
|||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</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
|
### /pki/config/ca
|
||||||
#### POST
|
#### POST
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user