In an Enterprise Security Extension’s pipeline, you can add preprocessing steps before authentication and before authorization.

The X.509 preprocessor makes it possible to use information that is provided in the X.509 certificate of a connecting MQTT client for authentication and authorization of the client in HiveMQ.

Among others, The HiveMQ X.509 preprocessor can extract values from the following X.509 certificate field:

This article provides an example of how to generate a client certificate with SAN.

(blue star) Instructions

Create a step-by-step guide:

  1. Prepare an OpenSSL configuration file req.cnf:

    [req]
    distinguished_name = req_distinguished_name
    req_extensions = v3_req
    prompt = no
    
    [req_distinguished_name]
    C = DE
    ST = Bayern
    L = Landshut
    O = HiveMQ GmbH
    CN = client1
    
    [v3_req]
    subjectAltName = dirName:dir_sect
    
    [dir_sect]
    C = DE
    O = HiveMQ GmbH
    OU = HiveMQ Support
    CN = client1

    The OpenSSL configuration file configures a Certificate Signing Request (CSR) for a client with the Common Name (CN) of "client1" and subjectAltName extension with a directory section named "dir_sect". The CSR is intended to be used to request a digital certificate from a Certificate Authority (CA) for the client.

    The [req] section specifies that the CSR will include a distinguished name (DN) and a v3 extension.

    The [req_distinguished_name] section specifies the DN of the client, with country (C) set to "DE", state (ST) set to "Bayern", location (L) set to "Landshut", organization (O) set to "HiveMQ GmbH", and the common name (CN) set to "client1".

    The [v3_req] section specifies that the CSR will include the subjectAltName extension with a directory section named "dir_sect".

    The [dir_sect] section specifies the values for the subjectAltName extension, with country (C) set to "DE", organization (O) set to "HiveMQ GmbH", organizational unit (OU) set to "HiveMQ Support", and the common name (CN) set to "client1".

  2. Generate the client certificate using the OpenSSL configuration file req.cnf:

    #!/usr/bin/env bash
    
    #Create a new Certificate Signing Request (CSR) and a new Key file
    openssl req \
      -new \
      -out 'client1.csr' \
      -newkey rsa:2048 \
      -nodes \
      -sha256 \
      -keyout 'client1-key.temp' \
      -config 'req.cnf'
    
    #verify the CSR
    openssl req -text -noout -verify -in 'client1.csr'
    
    #write RSA key
    openssl rsa -in 'client1-key.temp' -out 'client1-key.pem'
    
    #generate client certificate using the CSR and the OpenSSL configuration file
    openssl x509 -req -in 'client1.csr' \
      -signkey 'client1-key.pem' \
      -out 'client1-cert.pem' \
      -days 365 \
      -extensions 'v3_req' \
      -extfile 'req.cnf'
    
    #convert the client certificate from PEM to CRT
    openssl x509 -outform der \
      -in 'client1-cert.pem' -out 'client1-cert.crt'
      
    #import the client certificate to the broker's truststore
    printf "yes\n" |keytool -import -file 'client1-cert.crt' \
      -alias 'client1' \
      -keystore 'broker-truststore.jks' \
      -storepass 'passwordillo'

    where:
    - client1 is an example client name;
    - broker-truststore.jks is an example broker’s trust store file path;
    - passwordillo is an example password to the broker's trust store.

  3. Example test command:

    mqtt sh
    mqtt> connect --host localhost --port 8883 \
      --cafile server.pem \
      --cert client1-cert.pem \
      --key client1-key.pem
  4. Example X.509 ESE preprocessor configuration:

    <x509-preprocessor prefix="{{" postfix="}}">
            <x509-extraction>
                <x509-field>subject-alternative-common-names</x509-field>
                <ese-variable>string-4</ese-variable>
            </x509-extraction>
        </x509-extractions>
    </x509-preprocessor>

    This will extract the SAN from the X.509 certificate presented by the client and store it in the ESE Variable string-4.

  5. Example ESE Logging Preprocessor configuration:

    <logging-preprocessor>
        <message>ESE-Variable string-4(subject-alternative-common-names): ${string-4}</message>
        <level>debug</level>
        <name>com.example.logger</name>
    </logging-preprocessor>

    This will log a debug message ESE-Variable string-4(subject-alternative-common-names): ${string-4}.

(blue star) Related articles

The content by label feature automatically displays related articles based on labels you choose. To edit options for this feature, select the placeholder and tap the pencil icon.