Version 5

    Analysis

     

    Summary

     

    WFCORE-3305 added more advanced Elytron key-store manipulation management operations, providing the ability to generate self-signed certificates, generate certificate signing requests (CSRs), and import the response from a CSR using the CLI. WFCORE-3447 will be adding security actions to the CLI that leverage these new key-store manipulation management operations in order to hide the details of the management model representation. Currently, submitting a CSR to a certificate authority (CA), proving ownership of the domain name(s) specified in the CSR, and obtaining the response from the CA need to be handled by the user. This process is often time-consuming and confusing. This task is to add new runtime-only management operations to the Elytron subsystem key-store resource to obtain a signed certificate using the Let’s Encrypt CA, revoke such a certificate, and check if a certificate is due for renewal. As in WFCORE-3447, corresponding high-level security actions should also be added. This analysis focuses on just the new key-store resource management operations.

     

    Background

     

    Let’s Encrypt is a free CA that makes it possible to automate the process of obtaining a signed certificate without the need for user intervention. This is done via Let’s Encrypt’s Automatic Certificate Management Environment (ACME) protocol. In particular, an ACME client can request a signed certificate by sending JSON messages to an ACME server over HTTPS. The ACME server then issues challenges to the ACME client to prove ownership of the domain name(s) requested in the certificate. The challenges usually require having the ACME client set up resources at specific paths with specific content to prove control of the domain name(s). If the ACME client is able to complete these challenges successfully, the ACME server will issue a signed certificate.

     

    For a user wanting to use Let’s Encrypt with WildFly, it is currently necessary to obtain an ACME client (there are many different ACME clients out there), execute some commands to obtain the signed certificate, and then import the certificate into their key-store. As mentioned in a blog post by the Let's Encrypt team, it would be ideal if ACME clients were built into server software in order to simplify the process so that a user no longer needs to obtain an ACME client on their own. Let’s Encrypt is currently working on version 2 of their ACME protocol (the latest draft can be found here), with a new ACME v2 API endpoint being planned for release early in 2018 (a public test API endpoint will be available on Jan. 4th and the full launch is currently being planned for Feb. 27th). ACME v2 will be an IETF standard and should be usable by other CAs as well.

     

    Requirements

     

    Hard requirements

     

    Management operations for automatic certificate management

    Additional runtime-only management operations should be added to the Elytron subsystem key-store resource in order to:

     

    • Obtain a signed certificate from a CA that implements the server side of the ACME protocol (the only such CA right now is Let’s Encrypt but other CAs may implement this in the future).
      • obtain-certificate --alias=<alias> --domain-names=<domainNames> [--certificate-authority-account=<certificateAuthorityAccount>] [--agree-to-terms-of-service=<true,false>] [--staging=<true,false>] [--algorithm=<keyAlgorithmName>] [--key-size=<keySize>] [--credential-reference=<keyPassword>]
        • --alias: The alias of the new KeyStore entry
        • --domain-names: The list of DNS name(s) to request a certificate for
        • --certificate-authority-account: A reference to the certificate authority account information that should be used to obtain the certificate. The default value is “LetsEncrypt” (see the next section for details).
        • --agree-to-terms-of-service: Indicates whether or not the user agrees to the CA’s terms of service. (The ACME protocol suggests requiring a user to agree to the terms instead of automatically agreeing for the user.)
        • --staging: Indicates whether or not the CA’s staging URL should be used. The default value is false. This should only be set to true for testing purposes. This should never be set to true in a production environment.
        • --algorithm: The algorithm to be used to generate the key pair. The default value is RSA.
        • --key-size: The key size to use when generating the key pair. The default value is 2048.
        • --credential-reference: The credential reference to be used to protect the generated private key. The default value is the KeyStore password.

     

      • The obtain-certificate operation will do the following:
        1. Generate a key pair

        2. Generate a CSR using the key pair

        3. Create an account with the CA if an account hasn’t been created yet as specified by the ACME protocol (if agree-to-terms-of-service hasn't been set to true, account creation will fail)

        4. Send the CSR to the CA as specified by the ACME protocol

        5. Answer challenges from the CA to prove ownership of the domain name(s) requested in the certificate as specified by the ACME protocol

          • This will involve using Undertow to provision files at specific paths with specific content based on challenges from the CA (e.g., for the www.example.com domain name, responding to the “http-01” challenge would involve provisioning a specific file at www.example.com/.well-known/acme-challenge/FILE)

        6. Obtain the resulting signed certificate from the CA as specified by the ACME protocol

        7. Import the signed certificate into the KeyStore

     

    • Revoke a signed certificate.
      • revoke-certificate --alias=<alias> [--reason=<reason>] [--certificate-authority-account=<certificateAuthorityAccount>] [--staging=<true,false>]
        • --alias: The alias that identifies the certificate to revoke

        • --reason: The reason for revocation. Must be one of the revocation strings from https://tools.ietf.org/html/rfc5280#section-5.3.1

        • --certificate-authority-account: A reference to the certificate authority account information that should be used to revoke the certificate. The CA that's being asked to revoke the certificate must be the same as the CA that issued the certificate. The default value is “LetsEncrypt” (see the next section for details).

        • --staging: Indicates whether or not the CA’s staging URL should be used. The default value is false. This should only be set to true for testing purposes. This should never be set to true in a production environment.

     

      • The revoke-certificate operation will send a certificate revocation request to the CA as specified by the ACME protocol. If this request succeeds, the certificate should also be deleted from the KeyStore.

     

    • Check if a signed certificate is due for renewal.
      • should-renew-certificate --alias=<alias>
        • --alias: The alias that identifies the certificate to check
      • The should-renew-certificate operation will return true if the certificate expires in less than 30 days and false otherwise. If a certificate is due for renewal, a user can use the obtain-certificate operation again to renew it.
      • A user will be able to automate the renewal process by creating a cron job that runs a CLI script that checks if the certificate is due for renewal and if so, uses the obtain-certificate operation to renew it automatically. Let’s Encrypt suggests running such a cron job twice a day.

     

    Ability to configure and manage certificate authority account information needed for automatic certificate management

    It should be possible to configure the account information needed for CAs that implement the server side of the ACME protocol in the Elytron subsystem, as shown below:

     

    <certificate-authority-accounts>

        <certificate-authority-account name="..." contact="..." url="..." staging-url="...">

            <account-key key-store="..." alias="..."/>

        </certificate-authority-account>

    </certificate-authority-accounts>

     

    • The certificate-authority-accounts element will specify a listing of account information for CAs. The certificate-authority-account element will be used to configure the account information needed in order to be able to communicate with an ACME server. This information is needed by both the obtain-certificate and revoke-certificate management operations. In particular, a certificate-authority-account element will contain the following attributes and element:
      • name - The name of the certificate authority account
      • contact: The list of URLs that the CA can use to contact the user about issues related to their account (e.g., "mailto:wildfly-cert-admin@example.com”, “tel:+12025551212")
      • url: The URL for the CA. The only possible value for now is https://acme-v02.api.letsencrypt.org/directory
      • staging-url: The staging URL for the CA. The only possible value for now is https://acme-staging.api.letsencrypt.org/directory
      • account-key: The location of the account key that will be used to communicate with the ACME server. (An ACME client represents itself to the ACME server using an account key pair.)
        • key-store: A reference to the Elytron key-store that contains the account key. (The file that backs the KeyStore doesn’t need to exist initially. If it doesn’t exist, it will be created when obtain-certificate is called.)
        • alias: The alias that identifies the account key entry in the KeyStore.

     

    • The default out-of-the-box Elytron subsystem configuration should contain the following configuration for Let’s Encrypt:

     

    <certificate-authority-accounts>

        <certificate-authority-account name="LetsEncrypt" url="https://acme-v02.api.letsencrypt.org/directory" staging-url="https://acme-staging.api.letsencrypt.org/directory">

              <account-key key-store="accountsKeyStore" alias="LetsEncrypt"/>

        </certificate-authority-account>

        </certificate-authority-accounts>

     

    • A certificate-authority-account resource should have runtime-only management operations for ACME account management in order to:
      • Create an account with the CA
        • create-account --agree-to-terms-of-service=<true,false> [--staging=<true,false>]
          • --agree-to-terms-of-service: Indicates whether or not the user agrees to the CA’s terms of service. The default value is false.
          • --staging: Indicates whether or not the certificate authority’s staging URL should be used. The default value is false. This should only be set to true for testing purposes. This should never be set to true in a production environment.
        • If an account key has not been created yet, this operation will first generate a key pair and store it in the account KeyStore. It will then send an account creation request to the CA using the key pair as specified by the ACME protocol.

     

      • Change the account key
        • change-account-key [--staging=<true,false>]
        • This operation will generate a new key pair and send an account key change request to the CA as specified by the ACME protocol. If this request succeeds, the old key pair will be removed from the account KeyStore.

     

      • Deactivate the account
        • deactivate-account [--staging=<true,false>]
        • This operation will send an account deactivation request to the CA as specified by the ACME protocol.

     

    Non-requirements

     

    As with the other new key-store management operations for WFCORE-3305, atomic updates coordinated by the Domain Controller of multiple servers in a managed domain is a non-requirement (i.e., the ability to perform the new management operations on the DC and then have these operations get rolled out to servers in the managed domain is a non-requirement).

     

    Design Notes

     

    As with the other new key-store management operations for WFCORE-3305, the key-store "store" management operation will need to be executed after obtaining or revoking a signed certificate in order to save the resulting changes to the file that backs the key-store.

     

    General

     

    Tracking Issues

     

    Main tracking issue - WFCORE-3396

     

    Developer Resources

     

    Elytron subsystem:

    https://github.com/wildfly/wildfly-core/tree/master/elytron

     

    Developer Contact

     

    Farah Juma - fjuma@redhat.com