5

I'm using HSM via pkcs11 openssl engine. ENGINE_load_private_key() is used to load keys to use. It works fine, except after key pair generation:

After generating a new key-pair to HSM, ENGINE_load_private_key() still returns the old key.

Obviously later calls of ENGINE_load_private_key() does not read the key from HSM. Instead ENGINE_load_private_key() seems to return some cached value.

Is there some way to force openssl to read the new key from the HSM, and not returning some old key that does not anymore exists in the HSM?

This code piece was used to figure out the problem:

static void print_public_key_via_openssl( const char* name )
{
    ENGINE *e = ENGINE_by_id( "pkcs11");

    if ( e )
    {
        if ( ENGINE_init( e ) )
        {
            EVP_PKEY* key = ENGINE_load_private_key( e, name, NULL, NULL );
            if( key )
            {
                printf( "Public key:\n%s", public_key_to_str(key) );
                EVP_PKEY_free( key );
            }
            ENGINE_finish( e );
        }
        ENGINE_free( e );
    }
}

int main( int argc, char** argv )
{
    ...

    // Load the key and print it to stdout
    print_public_key_via_openssl( "slot_1-label_Private02" );

    // Generate new key pair value. 
    system( "hsmtool --dump_key 2" );
    system( "hsmtool --gen_key 2" );
    system( "hsmtool --dump_key 2" );

    // Load the key and print it to stdout
    print_public_key_via_openssl( "slot_1-label_Private02" );
    ...
}

Result: key in the HSM did change, but openssl still returns the old key:

Public key:
    Public-Key: (256 bit)
    pub:
        04:da:6e:4a:5f:e8:80:e4:e8:07:b8:79:7c:62:f6:
        57:78:91:c4:42:89:13:da:72:61:e7:69:07:51:84:
        6a:a2:a2:74:7b:79:7b:31:74:1d:b0:74:16:d7:9f:
        fa:fd:2f:12:34:b9:80:06:16:84:c0:a3:0a:46:27:
        a5:90:30:38:c9
    ASN1 OID: prime256v1
    NIST CURVE: P-256

Key #2:
    X   : DA6E4A5FE880E4E807B8797C62F6577891C4428913DA7261E7690751846AA2A2
    Y   : 747B797B31741DB07416D79FFAFD2F1234B980061684C0A30A4627A5903038C9

Key #2:
    X   : D6321B2DAAC592DB1E06D43F674804D0107252012BBDD214A7BB519109DD5D6E
    Y   : 0315E667625CBECA08A1D61BD0087D20D888A41AAE0E28D8789B8BDC8F6D09FF

Public key:
    Public-Key: (256 bit)
    pub:
        04:da:6e:4a:5f:e8:80:e4:e8:07:b8:79:7c:62:f6:
        57:78:91:c4:42:89:13:da:72:61:e7:69:07:51:84:
        6a:a2:a2:74:7b:79:7b:31:74:1d:b0:74:16:d7:9f:
        fa:fd:2f:12:34:b9:80:06:16:84:c0:a3:0a:46:27:
        a5:90:30:38:c9
    ASN1 OID: prime256v1
    NIST CURVE: P-256

Several programs will use the keypair from the HSM. And Those programs also uses other key pairs actively for TLS. So, restarting a process is not solution.

SKi
  • 8,007
  • 2
  • 26
  • 57
  • Can you verify whether the new key is in the same slot and does override the old one or not? – Yaser Nov 28 '16 at 01:28
  • Yes, the new key is generated over the old key in HSM. That is verified. – SKi Nov 29 '16 at 10:37
  • The only thing that comes to my mind is to call ENGINE_cleanup(), ENGINE_finish() and ENGINE_init() after key generation and see if it loads the new key or not – Yaser Nov 29 '16 at 10:48
  • Yes, that works. I already implement crazy workaround, that uses the clean-up and re-opening of openssl/crypto. The workaround is slow and it affects to existing TLS connections (which are using other key-pairs). But maybe we need to live with that.. – SKi Nov 29 '16 at 10:54
  • Why do you map a different key over another key in the first place? Create a new one with a new label, then destroy the old one when required. That way you've got more control. Usually you can also setup a counter in a HSM, by the way. – Maarten Bodewes Jan 07 '17 at 00:07

0 Answers0