Advanced usage#

In this section, more complex uses of the session helper are described. All examples and walkthroughs will be categorized and be referable from the menu to the right.

Protecting credentials#

One main tenet for devices or users outside of our control is to reduce the attack surface if or when the device is compromised. These uses cover different scenarios.

PKCS#11 on Canonical Ubuntu walkthrough#

This walkthrough demonstrated how to use the session helper with SoftHSM. It covers how to use a private key stored within a PKCS#11 environment.

Prerequisites#

  • AWS IoT Role Alias configured with thing, certificate, and AWS IoT policy

  • A registered X.509 certificate and corresponding private key

  • An Ubuntu desktop or server environment with sudo access - the walkthrough uses Ubuntu 22.04.1 LTS

  • Python with the awsiot-credentialhelper installed

Steps#

  1. Login to the Ubuntu system (host system) and start a command line interface.

  2. Create a directory and copy the certificate and private key there

    $ mkdir $HOME/hsm_test
    $ cd $HOME/hsm_test
    $ cp /path/to/certificate thing-cert.pem
    $ cp /path/to/private-key thing-key.pem
    
  3. Install dependencies, SoftHSM2, initialize and record slot number

    $ sudo apt update && sudo apt install -y softhsm2 pcregrep opensc gnutls-bin
    $ mkdir -p $HOME/lib/softhsm/tokens
    $ cd $HOME/lib/softhsm/
    $ echo "directories.tokendir = $PWD/tokens" > softhsm2.conf
    $ export SOFTHSM2_CONF=$HOME/lib/softhsm/softhsm2.conf
    $ cd $HOME/hsm_test
    $ echo $(softhsm2-util --init-token --free \
      --so-pin 1234 --pin 1234 --label hsm_thing|pcregrep -o1 \
      '.* to slot (.*)') > slot.txt
    
  4. Verify the private key is in PKCS#8 format. This the first major challenge in getting keys into the right format. SoftHSM2 will alert if the key is not in the correct format.

    $ # Covert PCKS#1 (--BEGIN RSA PRIVATE KEY--) to PKCS#8 (--BEGIN PRIVATE KEY--)
    $ mv thing-key.pem thing-key-pkcs1.pem
    $ openssl pkcs8 -in thing-key-pkcs1.pem -topk8 -nocrypt -out thing-key.pem
    
  5. Import the private key into newly initialized slot and verify content.

    $ softhsm2-util --import thing-key.pem --slot $(cat slot.txt) --label hsm_thing_key \
    --id 0000 --pin 1234
    The key pair has been imported.
    $ p11-tool --list-tokens
     Token 0:
         URL: pkcs11:model=p11-kit-trust;manufacturer=PKCS%2311%20Kit;serial=1;token=System%20Trust
         Label: System Trust
         Type: Trust module
         Flags: uPIN uninitialized
         Manufacturer: PKCS#11 Kit
         Model: p11-kit-trust
         Serial: 1
         Module: p11-kit-trust.so
    
    
     Token 1:
         URL: pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=050524a5fd9dec1d;token=hsm_thing
         Label: hsm_thing
         Type: Generic token
         Flags: RNG, Requires login
         Manufacturer: SoftHSM project
         Model: SoftHSM v2
         Serial: 050524a5fd9dec1d
         Module: /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so
    
  6. Create a Python file with the follow code (pkcs11.py), replacing the endpoint, role_alias, and thing_name values. The pkcs11 entry uses values for the imported key.

    from awsiot_credentialhelper.boto3_session import (
        Boto3SessionProvider,
    )
    from awsiot_credentialhelper.boto3_session import (
        Pkcs11Config,
    )
    # from awscrt.io import LogLevel
    
    boto3_session = Boto3SessionProvider(
        endpoint="YOUR_ENDPOINT.credentials.iot.REGION.amazonaws.com",
        role_alias="YOUR_ROLE_ALIAS",
        certificate="thing-cert.pem",
        thing_name="YOUR_THING_NAME",
        pkcs11=Pkcs11Config(
            pkcs11_lib="/usr/lib/softhsm/libsofthsm2.so",
            user_pin="1234",
            token_label="hsm_thing",
            private_key_label="hsm_thing_key",
        ),
        # awscrt_log_level=LogLevel.Trace,
    ).get_session()
    print(boto3_session.client("sts").get_caller_identity())
    
  7. Test the code by running and verifying a response.

    $ python3 pkcs11.py
    {'UserId': 'AROA...F3D:4686...0a0d', 'Account': '1234567890', 'Arn': 'arn:aws:sts::1234567890:assumed-role/test_iot_role_alias/4686...0a0d', 'ResponseMetadata': {'RequestId': 'd6598737-9b63-4dd2-a0d3-cdf3a719bb39', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'd6598737-9b63-4dd2-a0d3-cdf3a719bb39', 'content-type': 'text/xml', 'content-length': '554', 'date': 'Fri, 24 Feb 2023 23:36:50 GMT'}, 'RetryAttempts': 0}}
    

That confirms that the session helper used the SoftHSM2 to perform the cryptographic operations. This walkthrough doesn’t cover the nuances of PKCS#11–there are many! However, if you uncomment the from awscrt.io and awscrt_log_level lines, this will provide details on what the awscrt runtime is doing.