Sample code for 30+ languages & platforms
DataFlex

SSH HSM Public Key Authentication

See more SSH Examples

Demonstrates SSH public-key authentication using a private key stored on an HSM — a USB token or smart card — accessed through PKCS#11. A session is opened with the vendor's driver, the key handles are located, and an SshKey object is bound to them with UsePkcs11.

Background: The point of an HSM is that the private key is generated on the device and cannot be exported: the signing operation happens on the hardware, so the key material never reaches your application's memory or disk. Even a fully compromised host cannot yield a copy of the key. PKCS#11 is the vendor-neutral interface to such devices, which is why the driver path and the object-finding template are the only vendor-specific parts of this example.

Chilkat DataFlex Downloads

DataFlex
Use ChilkatAx-win32.pkg

Procedure Test
    Boolean iSuccess
    Variant vPkcs11
    Handle hoPkcs11
    String sPin
    Integer iUserType
    Variant vJson
    Handle hoJson
    UInteger iPriv_handle
    UInteger iPub_handle
    Variant vKey
    Handle hoKey
    String sKeyType
    Handle hoSsh
    Integer iPort
    String sTemp1

    Move False To iSuccess

    //  This example requires the Chilkat API to have been previously unlocked.
    //  See Global Unlock Sample for sample code.

    //  Demonstrates SSH public-key authentication using a private key stored on an HSM (a USB token
    //  or smart card) accessed through PKCS#11.
    //  
    //  Note: Chilkat's PKCS#11 implementation runs on Windows, Linux, macOS, and other supported
    //  operating systems.

    Get Create (RefClass(cComChilkatPkcs11)) To hoPkcs11
    If (Not(IsComObjectCreated(hoPkcs11))) Begin
        Send CreateComObject of hoPkcs11
    End

    //  The PKCS#11 driver supplied by your HSM vendor: a .dll on Windows, a .so on Linux, or a
    //  .dylib on macOS.
    Set ComSharedLibPath Of hoPkcs11 To "C:/Program Files (x86)/Gemalto/IDGo 800 PKCS#11/IDPrimePKCS1164.dll"

    //  The PIN should come from a secure source rather than being hard-coded.
    Move "0000" To sPin

    //  Normal user = 1
    Move 1 To iUserType

    Get ComQuickSession Of hoPkcs11 iUserType sPin To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoPkcs11 To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    //  Describe the private key object to be located on the HSM.
    Get Create (RefClass(cComChilkatJsonObject)) To hoJson
    If (Not(IsComObjectCreated(hoJson))) Begin
        Send CreateComObject of hoJson
    End
    Get ComUpdateString Of hoJson "class" "private_key" To iSuccess
    Get ComUpdateString Of hoJson "label" "MySshKey" To iSuccess

    Get pvComObject of hoJson to vJson
    Get ComFindObject Of hoPkcs11 vJson To iPriv_handle
    If (iPriv_handle = 0) Begin
        Get ComLastErrorText Of hoPkcs11 To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    //  Find the corresponding public key by changing the class in the same template.
    Get ComUpdateString Of hoJson "class" "public_key" To iSuccess

    Get pvComObject of hoJson to vJson
    Get ComFindObject Of hoPkcs11 vJson To iPub_handle
    If (iPub_handle = 0) Begin
        Get ComLastErrorText Of hoPkcs11 To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    //  Create an SSH key object that uses the HSM handles.  The key type may be "rsa" or "ec".
    Get Create (RefClass(cComChilkatSshKey)) To hoKey
    If (Not(IsComObjectCreated(hoKey))) Begin
        Send CreateComObject of hoKey
    End
    Move "rsa" To sKeyType
    Get pvComObject of hoPkcs11 to vPkcs11
    Get ComUsePkcs11 Of hoKey vPkcs11 iPriv_handle iPub_handle sKeyType To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoKey To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Get Create (RefClass(cComChilkatSsh)) To hoSsh
    If (Not(IsComObjectCreated(hoSsh))) Begin
        Send CreateComObject of hoSsh
    End

    Move 22 To iPort
    Get ComConnect Of hoSsh "ssh.example.com" iPort To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    //  The corresponding public key must already be installed on the SSH server for the account.
    //  The signing operation happens on the HSM -- the private key never leaves the device.
    Get pvComObject of hoKey to vKey
    Get ComAuthenticatePk Of hoSsh "mySshLogin" vKey To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoSsh To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Showln "Public-key authentication successful."

    Send ComDisconnect To hoSsh

    Get ComLogout Of hoPkcs11 To iSuccess
    Get ComCloseSession Of hoPkcs11 To iSuccess


End_Procedure