Opensc: PIV: Need to use longer PUK

Created on 16 May 2018  路  5Comments  路  Source: OpenSC/OpenSC

Problem Description

To generate key pair on a token, I need to provide the management key. The interface seems to be willing to accept it as --so-pin, however it appears that OpenSC checks the PIN length, determines that 48 (length of the management key) is longer than 8, and aborts with an error.

Proposed Resolution

Either add a configuration parameter for so-pin min and max length, or at least point me at where in the code this check occurs, so I can temporarily switch it off.

Steps to reproduce

Try

$ pkcs11-tool -k --key-type rsa:2048 --usage-sign --login --id 02 --login-type so --so-pin env:SOPIN --private --sensitive

Logs

$ pkcs11-tool --module /Library/OpenSC/lib/pkcs11-spy.dylib -k --key-type rsa:2048 --usage-sign --login --id 02 --login-type so --so-pin env:SOPIN --private --sensitive


*************** OpenSC PKCS#11 spy *****************
Loaded: "/Library/OpenSC/lib/opensc-pkcs11.dylib"

0: C_GetFunctionList
2018-05-15 21:05:33.465
Returned:  0 CKR_OK

1: C_Initialize
2018-05-15 21:05:33.467
[in] pInitArgs = 0x0
Returned:  0 CKR_OK

2: C_GetSlotList
2018-05-15 21:05:33.557
[in] tokenPresent = 0x0
[out] pSlotList: 
Count is 1
[out] *pulCount = 0x1
Returned:  0 CKR_OK

3: C_GetSlotList
2018-05-15 21:05:33.558
[in] tokenPresent = 0x0
[out] pSlotList: 
Slot 0
[out] *pulCount = 0x1
Returned:  0 CKR_OK

4: C_GetSlotInfo
2018-05-15 21:05:33.559
[in] slotID = 0x0
[out] pInfo: 
      slotDescription:        'Yubico Yubikey 4 OTP+U2F+CCID   '
                              '                                '
      manufacturerID:         'Yubico                          '
      hardwareVersion:         4.55
      firmwareVersion:         0.0
      flags:                   7
        CKF_TOKEN_PRESENT                
        CKF_REMOVABLE_DEVICE             
        CKF_HW_SLOT                      
Returned:  0 CKR_OK
Using slot 0 with a present token (0x0)

5: C_OpenSession
2018-05-15 21:05:33.562
[in] slotID = 0x0
[in] flags = 0x6
pApplication=0x0
Notify=0x0
[out] *phSession = 0x7fc101f1f470
Returned:  0 CKR_OK

6: C_GetTokenInfo
2018-05-15 21:05:33.562
[in] slotID = 0x0
[out] pInfo: 
      label:                  'PIV_II                          '
      manufacturerID:         'piv_II                          '
      model:                  'PKCS#15 emulated'
      serialNumber:           'f05f6fe956a5e163'
      ulMaxSessionCount:       0
      ulSessionCount:          0
      ulMaxRwSessionCount:     0
      ulRwSessionCount:        0
      ulMaxPinLen:             8
      ulMinPinLen:             4
      ulTotalPublicMemory:     -1
      ulFreePublicMemory:      -1
      ulTotalPrivateMemory:    -1
      ulFreePrivateMemory:     -1
      hardwareVersion:         0.0
      firmwareVersion:         0.0
      time:                   '                '
      flags:                   40d
        CKF_RNG                          
        CKF_LOGIN_REQUIRED               
        CKF_USER_PIN_INITIALIZED         
        CKF_TOKEN_INITIALIZED            
Returned:  0 CKR_OK

7: C_Login
2018-05-15 21:05:33.565
[in] hSession = 0x7fc101f1f470
[in] userType = CKU_SO
[in] pPin[ulPinLen] 00007ffee230acce / 48
    00000000  . . . . .
Returned:  162 CKR_PIN_LEN_RANGE

8: C_Finalize
2018-05-15 21:05:33.565
Returned:  0 CKR_OK
error: PKCS11 function C_Login failed: rv = CKR_PIN_LEN_RANGE (0xa2)
Aborting.
$ 

I know the problem is with OpenSC, because when I use YKCS11 library it works:

$ pkcs11-tool --module /Library/OpenSC/lib/pkcs11-spy.dylib -k --key-type rsa:2048 --usage-sign --login --id 02 --login-type so --so-pin env:SOPIN --private --sensitive


*************** OpenSC PKCS#11 spy *****************
Loaded: "/usr/local/lib/libykcs11.dylib"

0: C_GetFunctionList
2018-05-15 21:07:09.336
Returned:  0 CKR_OK

1: C_Initialize
2018-05-15 21:07:09.336
[in] pInitArgs = 0x0
Returned:  0 CKR_OK

2: C_GetSlotList
2018-05-15 21:07:09.382
[in] tokenPresent = 0x0
[out] pSlotList: 
Count is 1
[out] *pulCount = 0x1
Returned:  0 CKR_OK

3: C_GetSlotList
2018-05-15 21:07:09.382
[in] tokenPresent = 0x0
[out] pSlotList: 
Slot 0
[out] *pulCount = 0x1
Returned:  0 CKR_OK

4: C_GetSlotInfo
2018-05-15 21:07:09.382
[in] slotID = 0x0
[out] pInfo: 
      slotDescription:        '   Yubico Yubikey 4 OTP+U2F+CCID'
                              '                               ]'
      manufacturerID:         'Yubico                          '
      hardwareVersion:         1.0
      firmwareVersion:         1.0
      flags:                   5
        CKF_TOKEN_PRESENT                
        CKF_HW_SLOT                      
Returned:  0 CKR_OK
Using slot 0 with a present token (0x0)

5: C_OpenSession
2018-05-15 21:07:09.382
[in] slotID = 0x0
[in] flags = 0x6
pApplication=0x0
Notify=0x0
[out] *phSession = 0x51b660
Returned:  0 CKR_OK

6: C_GetTokenInfo
2018-05-15 21:07:09.525
[in] slotID = 0x0
[out] pInfo: 
      label:                  'YubiKey PIV                     '
      manufacturerID:         'Yubico                          '
      model:                  'YubiKey YK4     '
      serialNumber:           '1234            '
      ulMaxSessionCount:       -1
      ulSessionCount:          -1
      ulMaxRwSessionCount:     -1
      ulRwSessionCount:        -1
      ulMaxPinLen:             8
      ulMinPinLen:             6
      ulTotalPublicMemory:     -1
      ulFreePublicMemory:      -1
      ulTotalPrivateMemory:    -1
      ulFreePrivateMemory:     -1
      hardwareVersion:         0.0
      firmwareVersion:         4.51
      time:                   '                '
      flags:                   40d
        CKF_RNG                          
        CKF_LOGIN_REQUIRED               
        CKF_USER_PIN_INITIALIZED         
        CKF_TOKEN_INITIALIZED            
Returned:  0 CKR_OK

7: C_Login
2018-05-15 21:07:09.525
[in] hSession = 0x51b660
[in] userType = CKU_SO
[in] pPin[ulPinLen] 00007ffee9378cd6 / 48
    00000000  . . . . .
Returned:  0 CKR_OK

8: C_GetMechanismList
2018-05-15 21:07:09.530
[in] slotID = 0x0
[out] pMechanismList[20]: 
Count is 20
Returned:  0 CKR_OK

9: C_GetMechanismList
2018-05-15 21:07:09.530
[in] slotID = 0x0
[out] pMechanismList[20]: 
 CKM_RSA_PKCS_KEY_PAIR_GEN     
 CKM_RSA_PKCS                  
 CKM_RSA_PKCS_PSS              
 CKM_RSA_X_509                 
 CKM_SHA1_RSA_PKCS             
 CKM_SHA256_RSA_PKCS           
 CKM_SHA384_RSA_PKCS           
 CKM_SHA512_RSA_PKCS           
 CKM_SHA1_RSA_PKCS_PSS         
 CKM_SHA256_RSA_PKCS_PSS       
 CKM_SHA384_RSA_PKCS_PSS       
 CKM_SHA512_RSA_PKCS_PSS       
 CKM_EC_KEY_PAIR_GEN           
 CKM_ECDSA                     
 CKM_ECDSA_SHA1                
 Unknown Mechanism (00001044)  
 CKM_SHA_1                     
 CKM_SHA256                    
 CKM_SHA384                    
 CKM_SHA512                    
Returned:  0 CKR_OK

. . . . .

30: C_GenerateKeyPair
2018-05-15 21:07:09.531
[in] hSession = 0x51b660
pMechanism->type=CKM_RSA_PKCS_KEY_PAIR_GEN    
[in] pPublicKeyTemplate[8]: 
    CKA_CLASS             CKO_PUBLIC_KEY       
    CKA_TOKEN             True
    CKA_MODULUS_BITS      00007ffee9376b20 / 8
    00000000  00 08 00 00 00 00 00 00                          ........        
    CKA_PUBLIC_EXPONENT   00007ffee9376b3a / 3
    00000000  01 00 01                                         ...             
    CKA_VERIFY            True
    CKA_WRAP              True
    CKA_ID                00000001068a5730 / 1
    00000000  02                                               .               
    CKA_PRIVATE           True
[in] pPrivateKeyTemplate[7]: 
    CKA_CLASS             CKO_PRIVATE_KEY      
    CKA_TOKEN             True
    CKA_PRIVATE           True
    CKA_SENSITIVE         True
    CKA_SIGN              True
    CKA_UNWRAP            True
    CKA_ID                00000001068a5730 / 1
    00000000  02                                               .               
Attempt to generate RSA key, key_len=2048
[out] hPublicKey = 0x59
[out] hPrivateKey = 0x40
Returned:  0 CKR_OK
Key pair generated:

31: C_GetAttributeValue
2018-05-15 21:07:14.843
[in] hSession = 0x51b660
[in] hObject = 0x40
[in] pTemplate[1]: 
    CKA_CLASS             00007ffee9376aa0 / 8
[out] pTemplate[1]: 
    CKA_CLASS             CKO_PRIVATE_KEY      
Returned:  0 CKR_OK

32: C_GetAttributeValue
2018-05-15 21:07:14.844
[in] hSession = 0x51b660
[in] hObject = 0x40
[in] pTemplate[1]: 
    CKA_KEY_TYPE          00007ffee9376aa0 / 8
[out] pTemplate[1]: 
    CKA_KEY_TYPE          CKK_RSA            
Returned:  0 CKR_OK

. . . . .

56: C_CloseSession
2018-05-15 21:07:14.846
[in] hSession = 0x51b660
Returned:  0 CKR_OK

57: C_Finalize
2018-05-15 21:07:14.849
Returned:  0 CKR_OK
$ 
wontfix

All 5 comments

The PIV's PUK is fixed to a maximum of 8 digits, which is the reason for this behavior, I suppose. Maybe @dengert has some idea on how to make this more flexible...

The PUK is a 8 byte PIN and is not the same as the admin 9B key which is 3DES, 2DES or AES.

The PIV driver does not support trying to pass a 48 byte key as a PIN.

NIST 800-73 specifically left card provisioning up to the card vendors. (And it does not define any commands to write a private key to the card only how to generate a key pair on the card returning the public key as part of the command.)

The OpenSC piv-tool does provide a way to use a 3DES or AES key with external or mutual authentication to the card as defined in NIST 800-73, but a vendor is not required to use the 9B key to provision their cards. You need to look at the card's documentation to see what the card requires. The piv-tool was designed to allow for doing some card provisioning for test purposes. Get a Card Management System or use the Yubico piv tool if needed.

piv-tool Wiki page describes how to:

  1. Delete an existing certificate
  2. Authenticate using the 9B admin 3DES or AES key
  3. Generate a key pair saving the public key as a file
  4. Generate a certificate request using the private key on the card and public key from the file
  5. Write the new certificate to the card

@dengert, understood, thank you! You're perfectly correct in everything you said, and thanks for the reference to piv-tool that can do the job!

Still, since pkcs11-tool does offer the option of generating key pairs (--keypairgen), it would be nice if there was a way to pass the 9B key along with the --keypairgen request. Otherwise one wonders what's the point of allowing an operation you've no way of authenticating for.

What is your opinion?

P.S. Could you point me at the place in the code where the PIV PUK length is checked? I'd like to introduce a command-line parameter to disable that check that could be used in a special case (generating key pair), while for all the "normal" operations this check would still be present.

"what's the point?" The point some cards are designed (and documented) to do things other cards are not. The PIV driver is sticking to the documented standards PIV standards. There are security risks too with the 9B key. Each card should have a different 9B key. NIST does not define how to change it. A card management system would do that for you.

I keep talking about using the card vendor's tools for card management. Yubico is the card vendor in your case and they know all the features of their device and how to manage it. Use their tools for card management. You could ask the Yubico people to add the feature to their pkcs11 module. If not they have open source, you could modify their code too.

P.S. I am not going to point you at the place in the code teh PIV PUK length is checked. Its not just checking the length, you then have to use it.

Yubico is the card vendor in your case and they know all the features of their device and how to manage it. Use their tools for card management.

I am cross-checking their tools. Also, their tools use different naming/addressing for the objects on the token, which is a pain.

You could ask the Yubico people to add the feature to their pkcs11 module.

I already did.

If not they have open source, you could modify their code too.

I already did.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alex-nitrokey picture alex-nitrokey  路  13Comments

michaelweiser picture michaelweiser  路  8Comments

jursonovicst picture jursonovicst  路  15Comments

szszszsz picture szszszsz  路  11Comments

alex-nitrokey picture alex-nitrokey  路  5Comments