Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Look up PKCS#11 keys by key label, regardless of slot #321

Closed
wants to merge 8 commits into from

Conversation

bifurcation
Copy link
Contributor

In some PKCS#11 modules, slots are not distinguished by name, but it is possible to assign distinct names to private keys. This PR updates the PKCS#11 key object handle this situation better:

  • Each time the key is used, we search for it across all slots
  • The slot description is used to filter slots in this search

@kisom
Copy link
Contributor

kisom commented Sep 15, 2015

@bifurcation Looks like go vet failed; %u on line 144 of crypto/pkcs11key/pkcs11key.go isn't recognised.

@kisom
Copy link
Contributor

kisom commented Sep 15, 2015

Actually a number of places where %u is used:

2.24s$ go vet github.com/cloudflare/cfssl/...
crypto/pkcs11key/pkcs11key.go:144: unrecognized printf verb 'u'
crypto/pkcs11key/pkcs11key.go:148: unrecognized printf verb 'u'
crypto/pkcs11key/pkcs11key.go:155: unrecognized printf verb 'u'
crypto/pkcs11key/pkcs11key.go:161: unrecognized printf verb 'u'
crypto/pkcs11key/pkcs11key.go:172: unrecognized printf verb 'u'
crypto/pkcs11key/pkcs11key.go:179: unrecognized printf verb 'u'
crypto/pkcs11key/pkcs11key.go:184: unrecognized printf verb 'u'

@@ -158,31 +129,67 @@ func (ps *PKCS11Key) Destroy() {
}
}

func (ps *PKCS11Key) openSession() (session pkcs11.SessionHandle, err error) {
// Look up the token that contains the desired private key
func (ps *PKCS11Key) openSession() (session pkcs11.SessionHandle, keyHandle pkcs11.ObjectHandle, err error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is now too long to used named returns, please use positional returns instead for clarity, per Go style.

@bifurcation
Copy link
Contributor Author

Thanks, @kisom, forgot to remove some printfs from debugging. go vet looks good locally now.

// Find slot by description
slots, err := ps.module.GetSlotList(true)
if err != nil {
return
}
for _, slot := range slots {
slotInfo, err := ps.module.GetSlotInfo(slot)
// If ps.slotDescription is provided, we will only check matching slots
slotInfo, err2 := ps.module.GetSlotInfo(slot)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why err2 here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shadowing, but now not necessary.

@kisom
Copy link
Contributor

kisom commented Sep 15, 2015

I'll be able to actually review this in a few hours. Thanks @jsha for the review, too.

// The name of the slot to be used, or "" to use any slot
slotDescription string

// The label of the token to be used, or "" to use any token
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with slotDescription being optional, but I think at least tokenLabel should be mandatory. Otherwise it's easy to accidentally leave out the token label, attempt to log into the wrong token, fail repeatedly, and lock that incorrect token.

jsha added a commit to jsha/cfssl that referenced this pull request Sep 17, 2015
Fixes cloudflare#329
Fixes cloudflare#325
Fixes cloudflare#322
Incorporates cloudflare#321

pkcs11key used to log in and log out for each Sign request. This created a
performance problem, because logins are slow. It also created a concurrency
problem.

Logged in / logged out state is a property of a PKCS#11 application, not a
session. So it was possible for two Sign operations on separate threads to log
in at the same time, and for one Sign operation to finish and call Logout before
the other Sign operation called SignInit. This would result in a
CKR_OBJECT_HANDLE_INVALID error.

To fix both of these issues, I made the session a persistent property of a
PKCS11Key, and protected it with a mutex. Now each PKCS11Key maintains a single
session throughout its lifetime, increasing signing performance.

Also, some of the field names for PKCS11Key were incorrect, and there was no
provision to select by token label, only slot label. In general, token label is
more unique, and the better choice. This change incorporates the elements of
cloudflare#321 fixing that. That is, it renames
Token to SlotDescription, Label to PrivateKeyLabel, and adds a new field
TokenLabel. Note for people updating configs: In your configs, don't rename
Token to TokenLabel. The value you currently have in Token is actually a
SlotDescription, and should be named such. You should add a name field
TokenLabel, whose value you can find with pkcs11-tool --list-slots.

I also changed where the PKCS11Key Config object is defined, to make it more
straightforward to share between different components, and added object label
support to pkcs11uri, so private keys can be selected by label.
@bifurcation
Copy link
Contributor Author

@jsha Now I'm confused. Is this being pursued here or in your branch? Happy to pass this to you if you want to get it finished.

@jsha
Copy link
Contributor

jsha commented Sep 17, 2015

@bifurcation: I wound up pulling this into a larger branch I was working on for concurrency problems. Sorry I neglected to let you know! I'll take it over from here, thanks for getting it this far.

@bifurcation
Copy link
Contributor Author

@jsha No problem. I consider the ball passed.

jsha added a commit to jsha/cfssl that referenced this pull request Sep 17, 2015
Fixes cloudflare#329
Fixes cloudflare#325
Fixes cloudflare#322
Incorporates cloudflare#321

pkcs11key used to log in and log out for each Sign request. This created a
performance problem, because logins are slow. It also created a concurrency
problem.

Logged in / logged out state is a property of a PKCS#11 application, not a
session. So it was possible for two Sign operations on separate threads to log
in at the same time, and for one Sign operation to finish and call Logout before
the other Sign operation called SignInit. This would result in a
CKR_OBJECT_HANDLE_INVALID error.

To fix both of these issues, I made the session a persistent property of a
PKCS11Key, and protected it with a mutex. Now each PKCS11Key maintains a single
session throughout its lifetime, increasing signing performance.

Also, some of the field names for PKCS11Key were incorrect, and there was no
provision to select by token label, only slot label. In general, token label is
more unique, and the better choice. This change incorporates the elements of
cloudflare#321 fixing that. That is, it renames
Token to SlotDescription, Label to PrivateKeyLabel, and adds a new field
TokenLabel. Note for people updating configs: In your configs, don't rename
Token to TokenLabel. The value you currently have in Token is actually a
SlotDescription, and should be named such. You should add a name field
TokenLabel, whose value you can find with pkcs11-tool --list-slots.

I also changed where the PKCS11Key Config object is defined, to make it more
straightforward to share between different components, and added object label
support to pkcs11uri, so private keys can be selected by label.
jsha added a commit to jsha/cfssl that referenced this pull request Sep 17, 2015
Fixes cloudflare#329
Fixes cloudflare#325
Fixes cloudflare#322
Incorporates cloudflare#321

pkcs11key used to log in and log out for each Sign request. This created a
performance problem, because logins are slow. It also created a concurrency
problem.

Logged in / logged out state is a property of a PKCS#11 application, not a
session. So it was possible for two Sign operations on separate threads to log
in at the same time, and for one Sign operation to finish and call Logout before
the other Sign operation called SignInit. This would result in a
CKR_OBJECT_HANDLE_INVALID error.

To fix both of these issues, I made the session a persistent property of a
PKCS11Key, and protected it with a mutex. Now each PKCS11Key maintains a single
session throughout its lifetime, increasing signing performance.

Also, some of the field names for PKCS11Key were incorrect, and there was no
provision to select by token label, only slot label. In general, token label is
more unique, and the better choice. This change incorporates the elements of
cloudflare#321 fixing that. That is, it renames
Token to SlotDescription, Label to PrivateKeyLabel, and adds a new field
TokenLabel. Note for people updating configs: In your configs, don't rename
Token to TokenLabel. The value you currently have in Token is actually a
SlotDescription, and should be named such. You should add a name field
TokenLabel, whose value you can find with pkcs11-tool --list-slots.

I also changed where the PKCS11Key Config object is defined, to make it more
straightforward to share between different components, and added object label
support to pkcs11uri, so private keys can be selected by label.
@jsha jsha mentioned this pull request Sep 17, 2015
jsha added a commit to letsencrypt/pkcs11key that referenced this pull request Feb 22, 2016
Fixes cloudflare/cfssl#329
Fixes cloudflare/cfssl#325
Fixes cloudflare/cfssl#322
Incorporates cloudflare/cfssl#321

pkcs11key used to log in and log out for each Sign request. This created a
performance problem, because logins are slow. It also created a concurrency
problem.

Logged in / logged out state is a property of a PKCS#11 application, not a
session. So it was possible for two Sign operations on separate threads to log
in at the same time, and for one Sign operation to finish and call Logout before
the other Sign operation called SignInit. This would result in a
CKR_OBJECT_HANDLE_INVALID error.

To fix both of these issues, I made the session a persistent property of a
PKCS11Key, and protected it with a mutex. Now each PKCS11Key maintains a single
session throughout its lifetime, increasing signing performance.

Also, some of the field names for PKCS11Key were incorrect, and there was no
provision to select by token label, only slot label. In general, token label is
more unique, and the better choice. This change incorporates the elements of
cloudflare/cfssl#321 fixing that. That is, it renames
Token to SlotDescription, Label to PrivateKeyLabel, and adds a new field
TokenLabel. Note for people updating configs: In your configs, don't rename
Token to TokenLabel. The value you currently have in Token is actually a
SlotDescription, and should be named such. You should add a name field
TokenLabel, whose value you can find with pkcs11-tool --list-slots.

I also changed where the PKCS11Key Config object is defined, to make it more
straightforward to share between different components, and added object label
support to pkcs11uri, so private keys can be selected by label.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants