-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #28 from adavis10006/multiple-key-usage
address issue #26 multiple key usage error
- Loading branch information
Showing
18 changed files
with
612 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"TLSServerName": "foo.example.com", | ||
"TLSClientAuthMode": 4, | ||
"X509CACertLocation":"testdata/cacert.pem", | ||
"Keys": [ | ||
{"Identifier": "key1", "KeyLabel": "foo", "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"}, | ||
{"Identifier": "key1", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"}, | ||
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz"} | ||
], | ||
"KeyUsages": [ | ||
{"Endpoint": "/sig/x509-cert", "Identifiers": ["key1", "key3"], "MaxValidity": 3600}, | ||
{"Endpoint": "/sig/ssh-host-cert", "Identifiers": ["key1", "key2"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/ssh-user-cert", "Identifiers": ["key3"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/blob", "Identifiers": ["key1"], "MaxValidity": 36000} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"TLSServerName": "foo.example.com", | ||
"TLSClientAuthMode": 4, | ||
"X509CACertLocation":"testdata/cacert.pem", | ||
"Keys": [ | ||
{"KeyLabel": "foo", "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"}, | ||
{"Identifier": "key2", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"}, | ||
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz"} | ||
], | ||
"KeyUsages": [ | ||
{"Endpoint": "/sig/x509-cert", "Identifiers": ["key1", "key3"], "MaxValidity": 3600}, | ||
{"Endpoint": "/sig/ssh-host-cert", "Identifiers": ["key1", "key2"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/ssh-user-cert", "Identifiers": ["key3"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/blob", "Identifiers": ["key1"], "MaxValidity": 36000} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"TLSServerName": "foo.example.com", | ||
"TLSClientAuthMode": 4, | ||
"X509CACertLocation":"testdata/cacert.pem", | ||
"Keys": [ | ||
{"Identifier": "key1", "KeyLabel": "foo", "SlotNumber": 1, "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"}, | ||
{"Identifier": "key2", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"}, | ||
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz"} | ||
], | ||
"KeyUsages": [ | ||
{"Endpoint": "/sig/x509-cert", "Identifiers": ["key1", "key3"], "MaxValidity": 3600}, | ||
{"Endpoint": "/sig/ssh-host-cert", "Identifiers": ["key1", "key2"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/ssh-user-cert", "Identifiers": ["key3"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/blob", "Identifiers": ["key1"], "MaxValidity": 36000} | ||
] | ||
} |
8 changes: 5 additions & 3 deletions
8
...stdata/testconf-bad-unknown-endpoint.json → ...nf-bad-non-specify-x509-ca-cert-path.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,16 @@ | ||
{ | ||
"TLSClientAuthMode": 4, | ||
"TLSServerName": "foo.example.com", | ||
"TLSClientAuthMode": 4, | ||
"X509CACertLocation":"testdata/cacert.pem", | ||
"Keys": [ | ||
{"Identifier": "key1", "KeyLabel": "foo", "SlotNumber": 1, "UserPinPath" : "/path/1", "CreateCACertIfNotExist": true, "CommonName": "My CA"}, | ||
{"Identifier": "key2", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"}, | ||
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz"} | ||
], | ||
"KeyUsages": [ | ||
{"Endpoint": "/sig/x509-cert", "Identifiers": ["key1", "key3"]}, | ||
{"Endpoint": "/foo/bar", "Identifiers": ["key1", "key2"]} | ||
{"Endpoint": "/sig/x509-cert", "Identifiers": ["key1", "key3"], "MaxValidity": 3600}, | ||
{"Endpoint": "/sig/ssh-host-cert", "Identifiers": ["key1", "key2"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/ssh-user-cert", "Identifiers": ["key3"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/blob", "Identifiers": ["key1"], "MaxValidity": 36000} | ||
] | ||
} |
16 changes: 16 additions & 0 deletions
16
config/testdata/testconf-bad-non-x509-cert-for-x509-endpoint.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"TLSServerName": "foo.example.com", | ||
"TLSClientAuthMode": 4, | ||
"X509CACertLocation":"testdata/cacert.pem", | ||
"Keys": [ | ||
{"Identifier": "key1", "KeyLabel": "foo", "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"}, | ||
{"Identifier": "key2", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"}, | ||
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3"} | ||
], | ||
"KeyUsages": [ | ||
{"Endpoint": "/sig/x509-cert", "Identifiers": ["key1", "key3"], "MaxValidity": 3600}, | ||
{"Endpoint": "/sig/ssh-host-cert", "Identifiers": ["key1", "key2"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/ssh-user-cert", "Identifiers": ["key3"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/blob", "Identifiers": ["key1"], "MaxValidity": 36000} | ||
] | ||
} |
17 changes: 17 additions & 0 deletions
17
config/testdata/testconf-bad-same-slot-different-pin-path.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"TLSServerName": "foo.example.com", | ||
"TLSClientAuthMode": 4, | ||
"X509CACertLocation":"testdata/cacert.pem", | ||
"Keys": [ | ||
{"Identifier": "key1", "KeyLabel": "foo", "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"}, | ||
{"Identifier": "key2", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"}, | ||
{"Identifier": "key2-1", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2-1"}, | ||
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz"} | ||
], | ||
"KeyUsages": [ | ||
{"Endpoint": "/sig/x509-cert", "Identifiers": ["key1", "key3"], "MaxValidity": 3600}, | ||
{"Endpoint": "/sig/ssh-host-cert", "Identifiers": ["key1", "key2"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/ssh-user-cert", "Identifiers": ["key3"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/blob", "Identifiers": ["key1"], "MaxValidity": 36000} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"TLSServerName": "foo.example.com", | ||
"TLSClientAuthMode": 4, | ||
"X509CACertLocation":"testdata/cacert.pem", | ||
"Keys": [ | ||
{"Identifier": "key1", "KeyLabel": "foo", "KeyType":3, "SlotNumber": 1, "UserPinPath" : "/path/1", "X509CACertLocation": "/path/foo", "CreateCACertIfNotExist": true, "CommonName": "My CA"}, | ||
{"Identifier": "key2", "KeyLabel": "bar", "SlotNumber": 2, "UserPinPath" : "/path/2"}, | ||
{"Identifier": "key3", "KeyLabel": "baz", "SlotNumber": 3, "UserPinPath" : "/path/3", "X509CACertLocation": "/path/baz"} | ||
], | ||
"KeyUsages": [ | ||
{"Endpoint": "/sig/x509-cert", "Identifiers": ["key1", "key3"], "MaxValidity": 3600}, | ||
{"Endpoint": "/sig/ssh-host-cert", "Identifiers": ["key1", "key2"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/ssh-user-cert", "Identifiers": ["key3"], "MaxValidity": 36000}, | ||
{"Endpoint": "/sig/blob", "Identifiers": ["key1"], "MaxValidity": 36000} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package pkcs11 | ||
|
||
import ( | ||
"bytes" | ||
"crypto/rand" | ||
"errors" | ||
"fmt" | ||
"io/ioutil" | ||
|
||
p11 "github.com/miekg/pkcs11" | ||
|
||
"github.com/yahoo/crypki/config" | ||
) | ||
|
||
// secureBuffer cached an array of bytes as secret. | ||
// It has a `clear` method to overwrite secret with random data. | ||
type secureBuffer struct { | ||
secret []byte | ||
} | ||
|
||
func (b *secureBuffer) get() string { | ||
return string(b.secret) | ||
} | ||
|
||
func (b *secureBuffer) clear() { | ||
_, _ = rand.Read(b.secret) | ||
} | ||
|
||
func newSecureBuffer(secret []byte) *secureBuffer { | ||
return &secureBuffer{secret: bytes.TrimSpace(secret)} | ||
} | ||
|
||
type loginHelper interface { | ||
getUserPinCode(string) (*secureBuffer, error) | ||
} | ||
|
||
type defaultHelper struct{} | ||
|
||
func (h *defaultHelper) getUserPinCode(path string) (*secureBuffer, error) { | ||
return getUserPinCode(path) | ||
} | ||
|
||
// openLoginSession opens a PKCS11 session and tries to log in. | ||
func openLoginSession(context PKCS11Ctx, slot uint, userPin string) (p11.SessionHandle, error) { | ||
session, err := context.OpenSession(slot, p11.CKF_SERIAL_SESSION) | ||
if err != nil { | ||
return 0, errors.New("makeLoginSession: error in OpenSession: " + err.Error()) | ||
} | ||
|
||
if err = context.Login(session, p11.CKU_USER, userPin); err != nil { | ||
context.CloseSession(session) | ||
return 0, errors.New("makeSigner: error in Login: " + err.Error()) | ||
} | ||
return session, nil | ||
} | ||
|
||
type loginOption interface { | ||
config(map[uint]*secureBuffer) loginHelper | ||
} | ||
|
||
// getLoginSessions opens the PKCS11 login session for all keys in the configuration. | ||
// The pin codes used to login are stored in the secure buffer and are overwritten with random data just before function | ||
// returns. | ||
func getLoginSessions(p11ctx PKCS11Ctx, keys []config.KeyConfig, opts ...loginOption) (map[uint]p11.SessionHandle, error) { | ||
login := make(map[uint]p11.SessionHandle) | ||
keyMap := make(map[uint]*secureBuffer) | ||
defer func() { | ||
for _, buffer := range keyMap { | ||
buffer.clear() | ||
} | ||
}() | ||
|
||
// `helper` provides the `getUserPinCode` method to get the pin code from input path. | ||
// This helper is also used to help unit test to check the status of the function-scoped variable. | ||
helper := loginHelper(&defaultHelper{}) | ||
for _, opt := range opts { | ||
helper = opt.config(keyMap) | ||
} | ||
|
||
for _, key := range keys { | ||
// config validation makes sure the pin code paths are equal for the same slot. | ||
if _, exist := keyMap[key.SlotNumber]; !exist { | ||
pin, err := helper.getUserPinCode(key.UserPinPath) | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to read user pin for key with identifier %q, pin path: %v, err: %v", key.Identifier, key.UserPinPath, err) | ||
} | ||
keyMap[key.SlotNumber] = pin | ||
session, err := openLoginSession(p11ctx, key.SlotNumber, pin.get()) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to create a login session for key with identifier %q, pin path: %v, err: %v", key.Identifier, key.UserPinPath, err) | ||
} | ||
login[key.SlotNumber] = session | ||
} | ||
} | ||
return login, nil | ||
} | ||
|
||
// getUserPinCode reads the pin code from the path and stores the pin code into the secure buffer. | ||
func getUserPinCode(path string) (*secureBuffer, error) { | ||
pin, err := ioutil.ReadFile(path) | ||
if err != nil { | ||
return nil, errors.New("Failed to open pin file: " + err.Error()) | ||
} | ||
return newSecureBuffer(pin), nil | ||
} |
Oops, something went wrong.