-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathREADME
582 lines (422 loc) · 19.9 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
Library and client implementation of EST Enrollment Protocol RFC 7030
https://www.rfc-editor.org/rfc/rfc7030.html
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
11.1 RFC 8951
1. 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.
2. EST Endpoints
----------------
/cacerts IMPLEMENTED
/simpleenroll IMPLEMENTED
/simplereenroll IMPLEMENTED
/fullcmc NOT IMPLEMENTED
/csrattrs NOT IMPLEMENTED
3. 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:
- BUILD_CLONE_SUBMODULES=ON set to off to avoid close third parts compile
dependencies.
- USE_OPENSSL=ON current default TLS/X.509 backend implementation.
- USE_OPENSSL_CUSTOM_ROOT=OFF enable the variable USE_OPENSSL_CUSTOM_ROOT_PATH
- USE_OPENSSL_CUSTOM_ROOT_PATH="" enabled using USE_OPENSSL_CUSTOM_ROOT=ON,
sets the path used to find the openssl root dir.
- USE_OPENSSL_MANUAL_LINK=OFF enable manual link to openssl implementation (skip find_package)
- USE_OPENSSL_MANUAL_LINK_INC="" if manual link is ON, set the openssl include directory
- USE_OPENSSL_MANUAL_LINK_LIB="" if manual link is ON, set the openssl lib path (you need to set
at least two libs, libssl and libcrypto). To setup multiple
libraries use cmake list format eg.
USE_OPENSSL_MANUAL_LINK_LIB=/path/libssl.so\;/path/libcrypto.so
3.1. Linux/MacOS
----------------
- Setup cmake artifacts:
If you want to change the build output directory update the -B flag.
cmake -Ssrc -Bbuild
- Compile the code:
cd build
make
** Note: at the end you will find the artifact build/rfc7030-est-client
- Run unit tests:
./bin/rfc7030-est-client-tests
- Run integration tests:
./bin/rfc7030-est-integration-tests
4. Supported Backends
---------------------
Here the table of native supported TLS/X.509 backends.
| Name | Folder | Version |
|-------------------|-------------------|-----------|
| OpenSSL | src/openssl | >= 1.x |
5. 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:
- ESTTLSInterface_t: used to invoke TLS specific functions, such as init TLS channel and read/write bytes.
- ESTX509Interface_t: used to parse, decode and encode specific X.509 objects such as
Certificates, Store, PKCS7 formats.
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:
- Create new folder:
src/myssl
- Create new file:
src/myssl/myssl_rfc.c
** Note: this file must implement all functions definitions:
- rfc7030_init
- rfc7030_get_config
- rfc7030_request_cachain
- rfc7030_request_certificate
- rfc7030_renew_certificate
- Create new cmake file:
src/myssl/myssl_est_client_library.cmake
This file must expose all headers and source files required by the backend implementation.
An example is src/openssl/ossl_est_client_library.cmake.
- Add the library to the src/CMakeLists.txt file:
Please remember to add a new cmake option (disabled by default) to enable/disable the new backend.
For this example could be
OPTION(USE_MYSSL "Compile using myssl backend" OFF)
** Note: search in the file for the ### BEGIN OPENSSL SECTION
and replicate the OpenSSL section as example.
- Prepare cmake with flags:
cmake -Ssrc -Bbuild -DUSE_MYSSL=ON -DUSE_OPENSSL=OFF
- Build the code:
cd build
make
- Run unit tests:
./bin/rfc7030-est-client-tests
- Run integration tests:
./bin/rfc7030-est-integration-tests
6. 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:
- CACerts
This command request to the EST server the list of CA certificates.
No authentication is required here.
./rfc7030-est-client -s testrfc7030.com \
-p 8443 \
--server-chain dstcax3.pem \
--output cachain.pem \
cacerts
- Enroll
This command request to the EST Server the emission of a certificate
providing a local csr (p10) file in PEM format.
Here we need authentication:
- Basic Auth
./rfc7030-est-client -s testrfc7030.com \
-p 8443 \
--server-chain dstcax3.pem \
--csr req.p10 \
--basic-auth "estuser:estpwd" \
--output-ca cachain.pem \
--output-crt enrolled.pem \
enroll
- TLS Auth
./rfc7030-est-client -s testrfc7030.com \
-p 9443 \
--server-chain dstcax3.pem \
--csr req.p10 \
--p12 preenrollment.p12 \
--p12-password "12345" \
--output-ca cachain.pem \
--output-crt enrolled.pem \
enroll
- Renew
This command request to the EST Server the emission of a certificate
that renews an old one providing a local csr (p10) file in PEM format
and the old certificate (and its key) in P12.
The syntax of the command is the same as the Enroll changing the p12 file
and the last command renew.
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.
- Set the include directory
src/lib/include
src/third_party/picohttpparser
- Set the src files to link
src/lib/cacerts.c
src/lib/client.c
src/lib/enroll.c
src/lib/error.c
src/lib/est.c
src/lib/http.c
src/lib/picohttp.c
src/third_party/picohttpparser/picohttpparser.c
To link the selected backend you need to do the same.
7. Tests
--------
- Run unit tests:
./bin/rfc7030-est-client-tests
- Run integration tests:
./bin/rfc7030-est-integration-tests
** Note: integration tests need internet connection to reach the EST public welome server.
8. 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.
9. 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.
10. 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.
11. 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.
11.1 RFC 8951
------------
Thanks to https://github.com/61131 a first support
for the RFC 8951 https://datatracker.ietf.org/doc/html/rfc8951 has been
added.
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.
* New client flag (propagated in the EST library in option structure)
has been add to skip this RFC implementation.