-
Notifications
You must be signed in to change notification settings - Fork 282
/
vault.go
70 lines (65 loc) · 2.09 KB
/
vault.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package credentialstores
import (
"encoding/pem"
"fmt"
"strings"
"github.com/hashicorp/boundary/internal/errors"
)
// extractClientCertAndPk takes the values passed into the api for client
// certificate and client certificate key and parses them into pem blocks.
// Any non certificate pem blocks are treated as a private key. An error is
// returned if there is more than 1 private key provided across both fields.
func extractClientCertAndPk(cert, pk string) ([]*pem.Block, *pem.Block, error) {
const op = "credentialstores.extractClientCertAndPk"
pks, err := decodePemBlocks(pk)
if err != nil {
return nil, nil, errors.WrapDeprecated(err, op, errors.WithMsg("failed to parse client certificate private key"))
}
var pkPem *pem.Block
switch len(pks) {
case 0:
case 1:
pkPem = pks[0]
default:
return nil, nil, errors.NewDeprecated(errors.InvalidParameter, op, "private key payload contained multiple pem blocks")
}
bs, err := decodePemBlocks(cert)
if err != nil {
return nil, nil, errors.WrapDeprecated(err, op, errors.WithMsg("failed to parse client certificate into pem blocks"))
}
pkIdx := -1
for i, b := range bs {
if !strings.Contains(b.Type, "CERTIFICATE") {
switch {
case pkPem == nil:
pkIdx, pkPem = i, b
case pkIdx < 0:
return nil, nil, errors.NewDeprecated(errors.InvalidParameter, op, "client certificate contains a private key when one was also provided separately")
default:
return nil, nil, errors.NewDeprecated(errors.InvalidParameter, op, fmt.Sprintf("second primary key found at %d after previous one found at %d", i, pkIdx))
}
}
}
if pkIdx >= 0 {
bs = append(bs[:pkIdx], bs[pkIdx+1:]...)
}
return bs, pkPem, nil
}
func decodePemBlocks(input string) ([]*pem.Block, error) {
const op = "credentialstores.decodePemBlocks"
cpIn := make([]byte, len(input))
copy(cpIn, input)
var p *pem.Block
var ret []*pem.Block
for {
p, cpIn = pem.Decode(cpIn)
if p == nil {
break
}
ret = append(ret, p)
}
if len(cpIn) > 0 {
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "not all data parseable by pem block")
}
return ret, nil
}