lgtti / rfc7030-est-client

RFC 7030 (EST - Enrollment over Secure Transport) SSL pluggable client implementation.
MIT License
3 stars 1 forks source link
c99 enrollment enrollment-over-secure-transport est iot libest openssl rfc7030

Library and client implementation of EST Enrollment Protocol RFC 7030 https://www.rfc-editor.org/rfc/rfc7030.html

Update 27/12/23: thanks to https://github.com/61131 a first support for the RFC 8951 https://datatracker.ietf.org/doc/html/rfc8951 has been added.

Summary

  1. Why another EST Client

  2. EST Endpoints

  3. Build 3.1. Linux/MacOS 3.2. Windows

  4. Supported Backends

  5. Custom TLS/X.509 Backend 5.1. Function map 5.2. Example

  6. Usage 6.1. Client 6.1.1 Example 6.2. Library 6.2.1 With CMake 6.2.2 Without CMake

  7. Tests

  8. Logging

  9. Custom parameters

  10. Contribution

  11. RFC Requirements

  12. Why another EST Client

    Actually, the standard reference implementation https://github.com/cisco/libest is very complex (Android support, BRSKI support, ...). Another problem with libest is the OpenSSL library used to implements all crypto capabilities because is the only supported library and the references are scattered in the code so is't easy to port to another library.

In the IoT world, we have devices with different SSL libraries (e.g. WolfSSL, BoringSSL, MbedTLS...) or different platforms that needs non-standard compilation methods or build chainsd (e.g. FreeRTOS and some market PLCs).

To support different platforms and libraries we need a 'pluggable' and configurable client.

  1. EST Endpoints

    /cacerts IMPLEMENTED /simpleenroll IMPLEMENTED /simplereenroll IMPLEMENTED /fullcmc NOT IMPLEMENTED /csrattrs NOT IMPLEMENTED

  2. Build

    Compile Dependencies:

    • picohttpparser
    • munit (test only)
    • cargs (cli client only)

** Note: all dependencies are downloaded automatically using git submodules.

Current cmake build configuration provides some default arguments you can on/off as you wish:

3.1. Linux/MacOS

  1. Supported Backends

    Here the table of native supported TLS/X.509 backends.

Name Folder Version
OpenSSL src/openssl >= 1.x
  1. Custom TLS/X.509 Backend

    As described in the general description, this EST implementation is agnostic regarding the runtime crypto library. If you need a non-compliant library you must create your backend following some rules and configuring the plugin.

The logic of the EST client is written in the src/lib folder but, to invoke the provided client with a backend, you need some additional operations, such as parse authentication certificates, parse certificate output result and other.

A new backend need to expose and implement ALL function definitions located in the header file src/lib/include/rfc7030.h

** Note: an example for OpenSSL is located in src/openssl/openssl_rfc.c

5.1. Function map

The core of the backend plugin is the config function map. Basically, is a set of function pointers used by the EST core library to invoke implementation-specific functions.

Two different maps are required:

These maps MUST be configured by the backend (for example see the src/openssl/openssl_rfc.c file) and ALL function MUST be implemented. There aren't optional functions.

5.2. Example

For example, you want to add a myssl library implementation:

  1. Usage

    Due to the generic nature of this EST implementation, you have the freedom to choose the type of usage you want.

You can compile the project and generate the command line client, you can build your own client logic using another backend or you can use the low level library and build you entire client from scratch. In addition you can use the current client logic without all "cli" feature importing the code in your project.

6.1. Client

Located in the src/client directory, this is a command line interface client. You can run

./rfc7030_est_client -h

to view the list of input parameters.

6.1.1 Example

First of all, from the http://testrfc7030.com website you must download the server chain dstcax3.pem using the command: wget http://testrfc7030.com/dstcax3.pem

With the client you can run three main operations:

6.2. Library

If you don't want (o you can't) use the pre-compiled client or you want to include the EST client in your code, you can write your own using the EST core library.

This project is not developed with the idea to generate a shared or dynamic library. To address PLC or low level hardware implementations, the code MUST be compiled with the source code of the client. This makes the library compatible with FreeRTOS also.

The drawback is that you must clone this repo and add to your build toolchain all required headers and source files.

To use all library functions you need to include only one header file

#include <est.h>

and this provides to you the access to all low level functions (prefixed with est_xxx) and all low level "client" functions (prefixed with est_client_xxx).

** Note: see the src/openssl/openssl_rfc.c file to check how to use low level EST library functions.

6.2.1 With CMake

If you are using cmake, you can add all required file using the provided cmake import file

include(${MODULE_ROOT_DIR}/src/lib/est_library.cmake)

** Note: this include provides to you cmake config some variables:
- EST_SRC
- EST_HEADERS

In addition, if you want to use an already implemented backend, you must add it in the same way. Here the example for OpenSSL:

include(${MODULE_ROOT_DIR}/src/openssl/ossl_est_client_library.cmake)

** Note: this include provides to you cmake config some variables:
- EST_OPENSSL_SRC
- EST_OPENSSL_SRC_TEST
- EST_OPENSSL_HEADERS

6.2.2 Without CMake

If you don't want to use cmake or you need another compile manager you can directly link all required headers and source files.

To link the selected backend you need to do the same.

  1. Tests

    • Run unit tests:

    ./bin/rfc7030-est-client-tests

  1. Logging

    Some HW platforms requires a specific logging implementation. This library doesn't provided any default one, instead offers some macros to be implemented using platform-specific code. The default implementation is a no-ops impl.

The src/lib/include/config.h header file contains

#ifdef EST_CONFIG_CUSTOM_FILE
#include EST_CONFIG_CUSTOM_FILE
#endif

During CMake build you can define this macro specifing a header file that redefines the logging functions. For exampke, if you call cmake with

cmake ... -DEST_CONFIG_CUSTOM_FILE=mylog.h

the file must contains

#include "logger.h"

#undef LOG_INFO
#define LOG_INFO(m) log_info m;

#undef LOG_DEBUG
#define LOG_DEBUG(m) log_debug m;

#undef LOG_WARN
#define LOG_WARN(m) log_warn m;

#undef LOG_ERROR
#define LOG_ERROR(m) log_error m;

where log_xxx are platform specific logging functions implemented and linked in your code.

  1. Custom parameters

    Same as for logging, you can use the macro

    cmake ... -DEST_CONFIG_CUSTOM_FILE=mylog.h

you can undefine and redefine all EST runtime parameters, adapting them to you specific HW or environment. For example

#undef HTTP_RESP_CHUNK_LEN
#define HTTP_RESP_CHUNK_LEN 10000

changes the default value of the HTTP download payload from the default to 10KB.

  1. Contribution

    If you want to submit a fix or a new backend implementation feel free to provide the pull request. Any contribution is welcome :)

Please open a github issue for any question.

  1. RFC Requirements

    The list of RFC requirements.

Level RFC Status


MUST Verifying the EST server's HTTPS URI against IMPLEMENTED the EST server's certificate using Implicit TAs (similar to a common HTTPS exchange).

MUST The client MUST NOT respond to the server's HTTP IMPLEMENTED authentication request unless the client has authorized the EST server.

MUST Certificate validation MUST be performed as per IMPLEMENTED [RFC5280]. The EST server certificate MUST conform to the [RFC5280] certificate profile.

OPTIONAL The client can leverage the binding of a shared NOT IMPLEMENTED credential to a specific EST server with a certificate-less TLS cipher suite.

OPTIONAL TLS with a previously issued client certificate IMPLEMENTED (e.g., an existing certificate issued by the EST CA).

OPTIONAL TLS with a previously installed certificate IMPLEMENTED (e.g., manufacturer-installed certificate or a certificate issued by some other party).

? Certificate-less TLS (e.g., with a shared NOT IMPLEMENTED credential distributed out-of-band);

MUST HTTP-based with a username/password distributed IMPLEMENTED out-of-band.

OPTIONAL A client MAY set the username to the IMPLEMENTED empty string ("""") if it is presenting a password that is not associated with a username.

OPTIONAL The client is expected to retry the request, NOT IMPLEMENTED including the appropriate Authorization Request header ([RFC2617], Section 3.2.2), if the client is capable of using the Basic or Digest authentication.

MUST The client MUST wait at least the specified NOT IMPLEMENTED "retry-after" time before repeating the same request. The client repeats the initial enrollment request after the appropriate "retry-after" interval has expired

MUST EST clients request a certificate from the EST IMPLEMENTED server with an HTTPS POST using the operation path value of "/simpleenroll"

MUST EST clients request a renew/rekey of existing IMPLEMENTED certificates with an HTTP POST using the operation path value of "/simplereenroll"

MUST The client MUST also be able to request CA IMPLEMENTED certificates from the EST server and parse the returned ""bag"" of certificates using /cacerts.

MUST The EST client uses the /cacerts response to IMPLEMENTED establish an Explicit Trust Anchor database for subsequent TLS authentication of the EST server.

MUST EST clients MUST NOT engage in any other protocol IMPLEMENTED exchange until after the /cacerts response has been accepted and a new TLS session has been established (using TLS certificate-based authentication)

OPTIONAL Clients SHOULD request an up-to-date response NOT IMPLEMENTED before stored information has expired in order to ensure the EST CA TA database is up to date.

MUST If the client disables the Implicit TA database NOT IMPLEMENTED and if the EST server certificate was verified using an Implicit TA database entry then the client MUST include the "Trusted CA Indication" extension in future TLS sessions [RFC6066].

MUST The EST server SHOULD include the three NOT IMPLEMENTED "Root CA Key Update" certificates OldWithOld, OldWithNew, and NewWithOld in the response chain. The EST client MUST be able to handle these certificates in the response.

OPTIONAL Implementations conforming to this standard MUST IMPLEMENTED provide the ability to designate Explicit Tas.

MUST After out-of-band validation occurs, all the other IMPLEMENTED certificates MUST be validated using normal [RFC5280] certificate path validation (using the most recent CA certificate as the TA) before they can be used to build certificate paths during certificate validation.

OPTIONAL For human usability reasons, a "fingerprint" of an NOT IMPLEMENTED Explicit TA database entry can be configured for bootstrapping as discussed in Section 4.1.1.

MUST Implementations conforming to this standard MUST IMPLEMENTED provide the ability to disable use of any Implicit TA database.

MUST The client MUST maintain a distinction between the IMPLEMENTED use of Explicit and Implicit TA databases during authentication in order to support proper authorization.

OPTIONAL The client MAY provisionally continue the TLS NOT IMPLEMENTED handshake to completion for the purposes of accessing the /cacerts or /fullcmc method.

OPTIONAL If the EST client continues with an unauthenticated NOT IMPLEMENTED connection, the client MUST extract the HTTP content data from the response (Sections 4.1.3 or 4.3.2) and engage a human user to authorize the CA certificate using out-of-band data such as a CA certificate "fingerprint" (e.g., a SHA-256 or SHA-512 [SHS] hash on the whole CA certificate).

OPTIONAL The EST client can be configured with a tuple IMPLEMENTED composed of the authority portion of the URI along with the OPTIONAL label (e.g., "www.example.com:80" and "arbitraryLabel1")

OPTIONAL HTTP redirections (3xx status codes) to the same NOT IMPLEMENTED web origin (see [RFC6454]) SHOULD be handled by the client without user input so long as all applicable security checks.

MUST HTTPS MUST be used. TLS 1.1 [RFC4346] (or a later IMPLEMENTED version) MUST be used for all EST communications.

OPTIONAL TLS session resumption [RFC5077] SHOULD be supported NOT IMPLEMENTED When performing renegotiation, TLS ""secure_renegotiation"" RFC5746 MUST be used"

OPTIONAL The client can determine if the server requires MOT IMPLEMENTED the linking of identity and POP by examining the CSR Attributes Response.

OPTIONAL Regardless of the CSR Attributes Response, clients IMPLEMENTED SHOULD link identity and POP by embedding tls-unique information in the certification request.

MUST RFC-8951 This document updates [RFC7030] to require IMPLEMENTED the POST request and payload response of all endpoints using base64 encoding, as specified in Section 4 of [RFC4648]. In both cases, the Distinguished Encoding Rules (DER) [X.690] are used to produce the input for the base64 encoding routine. This format is to be used regardless of any Content-Transfer-Encoding header, and any value in such a header MUST be ignored.