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

pkcs11-tool sets CKA_DECRYPT=true rather then CKA_DERIVE=true when generating EC keys #277

Closed
CardContact opened this Issue Aug 22, 2014 · 6 comments

Comments

Projects
None yet
2 participants
@CardContact
Member

CardContact commented Aug 22, 2014

An EC key pair generated with pkcs11-tool has the wrong key usage. Rather than setting CKA_DERIVE to true in the template, it sets CKA_DECRYPT, which has no relevance for EC keys.

As a result, --derive - correctly - fails, as it checks CKA_DECRYPT to be true.

@dengert

This comment has been minimized.

Show comment
Hide comment
@dengert

dengert Aug 22, 2014

Member

On 8/22/2014 3:07 PM, CardContact Software & System Consulting wrote:

An EC key pair generated with pkcs11-tool has the wrong key usage. Rather than setting CKA_DERIVE to true in the template, it sets CKA_DECRYPT, which has no relevance for EC keys.

As a result, --derive - correctly - fails, as it checks CKA_DECRYPT to be true.

Looks like incomplete code. The publicKeyTemplate and publicKeyTemplate were setup for RSA.
Yet with RSA, CKA_MODULUS_BITS and CKA_PUBLIC_EXPONENT are appended to the Template.
With EC, CKA_EC_PARAMS is appended. Maybe the CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP
and CKA_DERIVE could be handled in a similar fashion.

pkcs-11v2-30m1-d7.pdf Section 6.1 says RSA supports Encrypt, Decrypt, Sign, Verify, SignRecovery,
VerifyRecovery, Wrap and Unwrap.

Section 6.3 says EC only supports Sign, Verify and Derive.

But there may not be one set of parameters that fits all keys, as they may have different keyUsage.

This could get complicated, how much control do you need?
What additional parameters are needed?

For example with the PIV card, The 4 main certs/keys are predefined and use different
PKCS#15 flags that are then used for PKCS#11 attributes for each.

pkcs15-piv.c has for the pub keys:
static const pubdata pubkeys[PIV_NUM_CERTS_AND_KEYS] = {
{ "1", "PIV AUTH pubkey",
/RSA/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
SC_PKCS15_PRKEY_USAGE_WRAP |
SC_PKCS15_PRKEY_USAGE_VERIFY |
SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
/EC/SC_PKCS15_PRKEY_USAGE_VERIFY,
"9A06", 0x9A, "1", 0, "PIV_9A_KEY"},
{ "2", "SIGN pubkey",
/RSA/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
SC_PKCS15_PRKEY_USAGE_VERIFY |
SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER |
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
/EC/SC_PKCS15_PRKEY_USAGE_VERIFY |
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
"9C06", 0x9C, "1", 0, "PIV_9C_KEY"},
{ "3", "KEY MAN pubkey",
/RSA/SC_PKCS15_PRKEY_USAGE_ENCRYPT| SC_PKCS15_PRKEY_USAGE_WRAP,
/EC/SC_PKCS15_PRKEY_USAGE_DERIVE,
"9D06", 0x9D, "1", 0, "PIV_9D_KEY"},
{ "4", "CARD AUTH pubkey",
/RSA/SC_PKCS15_PRKEY_USAGE_VERIFY |
SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
/EC/SC_PKCS15_PRKEY_USAGE_VERIFY,
"9E06", 0x9E, "0", 0, "PIV_9E_KEY"}, /* no pin, and avail in contactless */

And a similar set for the private keys:
static const prdata prkeys[PIV_NUM_CERTS_AND_KEYS] = {
{ "1", "PIV AUTH key",
/RSA/SC_PKCS15_PRKEY_USAGE_DECRYPT |
SC_PKCS15_PRKEY_USAGE_UNWRAP |
SC_PKCS15_PRKEY_USAGE_SIGN |
SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
/EC/SC_PKCS15_PRKEY_USAGE_SIGN,
"", 0x9A, "1", SC_PKCS15_CO_FLAG_PRIVATE, 0},
{ "2", "SIGN key",
/RSA/SC_PKCS15_PRKEY_USAGE_DECRYPT |
SC_PKCS15_PRKEY_USAGE_SIGN |
SC_PKCS15_PRKEY_USAGE_SIGNRECOVER |
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
/EC/SC_PKCS15_PRKEY_USAGE_SIGN |
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
"", 0x9C, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
{ "3", "KEY MAN key",
/RSA/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
/EC/SC_PKCS15_PRKEY_USAGE_DERIVE,
"", 0x9D, "1", SC_PKCS15_CO_FLAG_PRIVATE, 0},
{ "4", "CARD AUTH key",
/RSA/SC_PKCS15_PRKEY_USAGE_SIGN |
SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
/EC/SC_PKCS15_PRKEY_USAGE_SIGN,
"", 0x9E, NULL, 0, 0}, /* no PIN needed, works with wireless */

In addition key generation is done via the piv-tool, not pkcs11-tool. pkcs15-piv.c also
addresses how to allow a EC Derive type key to be used to sign a cert req:

             /*
              * When no cert is present and a pubkey in a file was found,
              * means the caller is initilaizeing a card. A sign operation
              * will be required to sign a certificate request even if
              * normal usage would not allow it. Set SC_PKCS15_PRKEY_USAGE_SIGN
              * TODO if code is added to allow key generation and reqest
              * sign in the same session, similiar code will be needed.
              */

             if (ckis[i].pubkey_from_file == 1) {
                     prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN;
                     sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Adding SC_PKCS15_PRKEY_USAGE_SIGN");
             }


Reply to this email directly or view it on GitHub #277.

Douglas E. Engert DEEngert@gmail.com

Member

dengert commented Aug 22, 2014

On 8/22/2014 3:07 PM, CardContact Software & System Consulting wrote:

An EC key pair generated with pkcs11-tool has the wrong key usage. Rather than setting CKA_DERIVE to true in the template, it sets CKA_DECRYPT, which has no relevance for EC keys.

As a result, --derive - correctly - fails, as it checks CKA_DECRYPT to be true.

Looks like incomplete code. The publicKeyTemplate and publicKeyTemplate were setup for RSA.
Yet with RSA, CKA_MODULUS_BITS and CKA_PUBLIC_EXPONENT are appended to the Template.
With EC, CKA_EC_PARAMS is appended. Maybe the CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP
and CKA_DERIVE could be handled in a similar fashion.

pkcs-11v2-30m1-d7.pdf Section 6.1 says RSA supports Encrypt, Decrypt, Sign, Verify, SignRecovery,
VerifyRecovery, Wrap and Unwrap.

Section 6.3 says EC only supports Sign, Verify and Derive.

But there may not be one set of parameters that fits all keys, as they may have different keyUsage.

This could get complicated, how much control do you need?
What additional parameters are needed?

For example with the PIV card, The 4 main certs/keys are predefined and use different
PKCS#15 flags that are then used for PKCS#11 attributes for each.

pkcs15-piv.c has for the pub keys:
static const pubdata pubkeys[PIV_NUM_CERTS_AND_KEYS] = {
{ "1", "PIV AUTH pubkey",
/RSA/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
SC_PKCS15_PRKEY_USAGE_WRAP |
SC_PKCS15_PRKEY_USAGE_VERIFY |
SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
/EC/SC_PKCS15_PRKEY_USAGE_VERIFY,
"9A06", 0x9A, "1", 0, "PIV_9A_KEY"},
{ "2", "SIGN pubkey",
/RSA/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
SC_PKCS15_PRKEY_USAGE_VERIFY |
SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER |
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
/EC/SC_PKCS15_PRKEY_USAGE_VERIFY |
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
"9C06", 0x9C, "1", 0, "PIV_9C_KEY"},
{ "3", "KEY MAN pubkey",
/RSA/SC_PKCS15_PRKEY_USAGE_ENCRYPT| SC_PKCS15_PRKEY_USAGE_WRAP,
/EC/SC_PKCS15_PRKEY_USAGE_DERIVE,
"9D06", 0x9D, "1", 0, "PIV_9D_KEY"},
{ "4", "CARD AUTH pubkey",
/RSA/SC_PKCS15_PRKEY_USAGE_VERIFY |
SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
/EC/SC_PKCS15_PRKEY_USAGE_VERIFY,
"9E06", 0x9E, "0", 0, "PIV_9E_KEY"}, /* no pin, and avail in contactless */

And a similar set for the private keys:
static const prdata prkeys[PIV_NUM_CERTS_AND_KEYS] = {
{ "1", "PIV AUTH key",
/RSA/SC_PKCS15_PRKEY_USAGE_DECRYPT |
SC_PKCS15_PRKEY_USAGE_UNWRAP |
SC_PKCS15_PRKEY_USAGE_SIGN |
SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
/EC/SC_PKCS15_PRKEY_USAGE_SIGN,
"", 0x9A, "1", SC_PKCS15_CO_FLAG_PRIVATE, 0},
{ "2", "SIGN key",
/RSA/SC_PKCS15_PRKEY_USAGE_DECRYPT |
SC_PKCS15_PRKEY_USAGE_SIGN |
SC_PKCS15_PRKEY_USAGE_SIGNRECOVER |
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
/EC/SC_PKCS15_PRKEY_USAGE_SIGN |
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
"", 0x9C, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
{ "3", "KEY MAN key",
/RSA/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
/EC/SC_PKCS15_PRKEY_USAGE_DERIVE,
"", 0x9D, "1", SC_PKCS15_CO_FLAG_PRIVATE, 0},
{ "4", "CARD AUTH key",
/RSA/SC_PKCS15_PRKEY_USAGE_SIGN |
SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
/EC/SC_PKCS15_PRKEY_USAGE_SIGN,
"", 0x9E, NULL, 0, 0}, /* no PIN needed, works with wireless */

In addition key generation is done via the piv-tool, not pkcs11-tool. pkcs15-piv.c also
addresses how to allow a EC Derive type key to be used to sign a cert req:

             /*
              * When no cert is present and a pubkey in a file was found,
              * means the caller is initilaizeing a card. A sign operation
              * will be required to sign a certificate request even if
              * normal usage would not allow it. Set SC_PKCS15_PRKEY_USAGE_SIGN
              * TODO if code is added to allow key generation and reqest
              * sign in the same session, similiar code will be needed.
              */

             if (ckis[i].pubkey_from_file == 1) {
                     prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN;
                     sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Adding SC_PKCS15_PRKEY_USAGE_SIGN");
             }


Reply to this email directly or view it on GitHub #277.

Douglas E. Engert DEEngert@gmail.com

@CardContact

This comment has been minimized.

Show comment
Hide comment
@CardContact

CardContact Aug 23, 2014

Member

For the time being, I'm happy if new EC keys had SIGN and DERIVE as default.

pkcs11-tool has --usage-sign, --usage-decrypt and --usage-nonrepudiation, however they don't seem to have any effect. So maybe we should add --usage-derive and use these options if at least one was defined on the command line. This would keep the default behaviour of setting all key usages and allowing the user to define a list on the command line.

Member

CardContact commented Aug 23, 2014

For the time being, I'm happy if new EC keys had SIGN and DERIVE as default.

pkcs11-tool has --usage-sign, --usage-decrypt and --usage-nonrepudiation, however they don't seem to have any effect. So maybe we should add --usage-derive and use these options if at least one was defined on the command line. This would keep the default behaviour of setting all key usages and allowing the user to define a list on the command line.

@dengert

This comment has been minimized.

Show comment
Hide comment
@dengert

dengert Aug 23, 2014

Member

How about the attached patch.
The -usage-repudiation was dropped, as it was not implemented and not a PKCS#11 attribute for key generation.

It compiles, but I don't have a good way to test it.

On 8/23/2014 5:48 AM, CardContact Software & System Consulting wrote:

For the time being, I'm happy if new EC keys had SIGN and DERIVE as default.

pkcs11-tool has --usage-sign, --usage-decrypt and --usage-nonrepudiation, however they don't seem to have any effect. So maybe we should add --usage-derive and use these options if at least one was
defined on the command line. This would keep the default behaviour of setting all key usages and allowing the user to define a list on the command line.


Reply to this email directly or view it on GitHub #277 (comment).

Douglas E. Engert DEEngert@gmail.com

Member

dengert commented Aug 23, 2014

How about the attached patch.
The -usage-repudiation was dropped, as it was not implemented and not a PKCS#11 attribute for key generation.

It compiles, but I don't have a good way to test it.

On 8/23/2014 5:48 AM, CardContact Software & System Consulting wrote:

For the time being, I'm happy if new EC keys had SIGN and DERIVE as default.

pkcs11-tool has --usage-sign, --usage-decrypt and --usage-nonrepudiation, however they don't seem to have any effect. So maybe we should add --usage-derive and use these options if at least one was
defined on the command line. This would keep the default behaviour of setting all key usages and allowing the user to define a list on the command line.


Reply to this email directly or view it on GitHub #277 (comment).

Douglas E. Engert DEEngert@gmail.com

@CardContact

This comment has been minimized.

Show comment
Hide comment
@CardContact

CardContact Aug 25, 2014

Member

Hi Douglas,

the attachment was dropped. Can you send me a personal e-mail and I test the patch ?

You could also test with your SmartCard-HSM and the description at [1].

[1] http://www.smartcard-hsm.com/2014/08/22/using-smartcard-hsm-with-ecc-and-opensc.html

Member

CardContact commented Aug 25, 2014

Hi Douglas,

the attachment was dropped. Can you send me a personal e-mail and I test the patch ?

You could also test with your SmartCard-HSM and the description at [1].

[1] http://www.smartcard-hsm.com/2014/08/22/using-smartcard-hsm-with-ecc-and-opensc.html

@CardContact

This comment has been minimized.

Show comment
Hide comment
@CardContact

CardContact Aug 25, 2014

Member

Hi Douglas,

works for me. Can you put in a pull request for the change ?

One issue remains, but that probably caused somewhere in the intestines of OpenSC: When I dump with pkcs15-tool -D, then EC keys have signRecover key usage bit set in the PKCS#15 structure.

It's probably set automatically somewhere.

Member

CardContact commented Aug 25, 2014

Hi Douglas,

works for me. Can you put in a pull request for the change ?

One issue remains, but that probably caused somewhere in the intestines of OpenSC: When I dump with pkcs15-tool -D, then EC keys have signRecover key usage bit set in the PKCS#15 structure.

It's probably set automatically somewhere.

@dengert

This comment has been minimized.

Show comment
Hide comment
@dengert

dengert Oct 14, 2014

Member

Fixed

Member

dengert commented Oct 14, 2014

Fixed

@dengert dengert closed this Oct 14, 2014

philipWendland added a commit to philipWendland/OpenSC that referenced this issue Oct 17, 2014

pkcs11-tool sets CKA_DECRYPT=true rather then CKA_DERIVE=true when ge…
…nerating EC keys (OpenSC#277)

RSA and EC keys have different usage attributes. Appropriate attributes are set
When using --keypairgen the user can use the --usage-sign, --usage-decrypt,
and --usage-derive. to get finer control.

 Changes to be committed:
	modified:   tools/pkcs11-tool.c

philipWendland added a commit to philipWendland/OpenSC that referenced this issue Oct 19, 2014

pkcs11-tool sets CKA_DECRYPT=true rather then CKA_DERIVE=true when ge…
…nerating EC keys (OpenSC#277)

RSA and EC keys have different usage attributes. Appropriate attributes are set
When using --keypairgen the user can use the --usage-sign, --usage-decrypt,
and --usage-derive. to get finer control.

 Changes to be committed:
	modified:   tools/pkcs11-tool.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment