Skip to content

Commit 6de1fdd

Browse files
committed
wolfKeyMgr v0.11:
* Fix to use fingerprint to find keys * Improved the fingerprint calculation code and added hash * Added multiple server support using `contextStr` * Add unit test to `make check` * Improve `src/wolfkeymgr` exit documentation * Added example output for demo to `README.md`
1 parent 3be4a6f commit 6de1fdd

File tree

12 files changed

+246
-171
lines changed

12 files changed

+246
-171
lines changed

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,6 @@ include docs/include.am
3636
check_SCRIPTS+= $(dist_noinst_SCRIPTS)
3737

3838
TESTS += $(check_SCRIPTS)
39+
TESTS += $(check_PROGRAMS)
40+
3941
test: check

README.md

Lines changed: 80 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ This application handles secure distribution and optional storage of the generat
115115

116116
```sh
117117
$ ./src/wolfkeymgr -?
118-
wolfKeyManager 0.9
118+
wolfKeyManager 0.11
119119
-? Help, print this usage
120120
-i Do not chdir / in daemon mode
121121
-b Daemon mode, run in background
@@ -133,13 +133,15 @@ wolfKeyManager 0.9
133133
-K <keyt> Key Type: SECP256R1, FFDHE_2048, X25519 or X448 (default SECP256R1)
134134
```
135135

136+
To exit the key manager use ctrl+c.
137+
136138
### ETSI Test client
137139

138140
This demonstrates secure interactions with the key manager service using the ETSI HTTPS GET/PUT commands for different key types.
139141

140142
```sh
141143
$ ./examples/etsi_test/etsi_test -?
142-
etsi_test 0.9
144+
etsi_test 0.11
143145
-? Help, print this usage
144146
-e Error mode, force error response
145147
-h <str> Host to connect to, default localhost
@@ -155,46 +157,27 @@ etsi_test 0.9
155157
-c <pem> TLS Client Certificate, default certs/client-cert.pem
156158
-A <pem> TLS CA Certificate, default certs/ca-cert.pem
157159
-K <keyt> Key Type: SECP256R1, FFDHE_2048, X25519 or X448 (default SECP256R1)
158-
-F <fprint> Fingerprint used for multiple servers (first 80-bit of pkey hash as hex string)
159-
-n <name> Find key using public key name (hex string)
160+
-F <fprint> Fingerprint of ephemeral public key (first 80-bit of pkey hash as hex string)
161+
-C <ctxstr> Context string (used for multiple servers)
160162
```
161163

162164
This client also support stress testing options:
163165
* Use the thread pool "-t" to spin up more threads.
164166
* Use the ETSI test client "-r" to make additional requests per thread.
165-
* Use the "-n" command to find key using public key name (hex string of first 64 bytes of public key).
166167
* Use the "-F" argument to get key for specific fingerprint (hex string of hash of public key - first 80 bits / 10 bytes)
168+
* Use the "-C" command to include context string (used for multiple servers).
167169

168-
#### ETSI Fingerprint Names
169-
170-
The fingerprint is a SHA-256 hash of the long term public key with the first 80 bits returned in big endian format. This is used when keys are served for multiple servers concurrently where each server should use a different ephemeral key. If the fingerprint is blank the same key will be returned assuming it is within the expiration and use count restrictions.
171-
172-
#### ETSI Context Names
170+
#### ETSI Fingerprint
173171

174-
The context is used to lookup an ephemeral key based on public key using the following scheme:
175-
* ECC: Public X and Y limited to 32 digits each (64 total)
176-
* DH: Public key truncated to 64 digits.
172+
The fingerprint is a SHA-256 hash of the ephemeral public key with the first 80 bits (10 bytes) in big endian format. If the fingerprint is blank the current active key for that TLS group will be returned (assuming it is within the expiration and use count restrictions).
177173

178-
The "contextStr" used in the HTTP GET is converted to a hex string up to 128 characters.
174+
The fingerprint is used to lookup an ephemeral key based on public key using the following scheme:
175+
* ECC: Public X and Y hashed with SHA256 (first 10 bytes)
176+
* DH: Public key hashed with SHA256 (first 10 bytes)
179177

180-
For example: An ECC public key printed like this:
178+
#### ETSI Context String
181179

182-
```sh
183-
ECC Pub X: 5D2DA665BDD597EC3AAA6AA2E999F115CED9F1016324C7F1711294C8871608CC
184-
ECC Pub Y: 38006E20B8EDE358CF23CED1FF46593AC0CED787C55B360F35ED3B5D2854018B
185-
186-
# Retrieved using:
187-
$ ./examples/etsi_test/etsi_test -n 5D2DA665BDD597EC3AAA6AA2E999F115CED9F1016324C7F1711294C8871608CC38006E20B8EDE358CF23CED1FF46593AC0CED787C55B360F35ED3B5D2854018B
188-
189-
# Example Key Manager output:
190-
HTTP GET
191-
Version: HTTP/1.1
192-
URI: /.well-known/enterprise-transport-security/keys?fingerprints=&groups=0x0017&contextstr=5D2DA665BDD597EC3AAA6AA2E999F115CED9F1016324C7F1711294C8871608CC38006E20B8EDE358CF23CED1FF46593AC0CED787C55B360F35ED3B5D2854018
193-
Headers: 1
194-
Accept: : application/pkcs8
195-
Context: 5D2DA665BDD597EC3AAA6AA2E999F115CED9F1016324C7F1711294C8871608CC38006E20B8EDE358CF23CED1FF46593AC0CED787C55B360F35ED3B5D2854018
196-
Group: SECP256R1 (23)
197-
```
180+
The context string is used to specify additional information to the key manager to distribute keys for multiple servers.
198181

199182
### HTTP Server / Client
200183

@@ -217,8 +200,7 @@ Jun 15 14:26:54 2021: [DEBUG] Content-Length: : 121
217200
Jun 15 14:26:54 2021: [DEBUG] Body Size: 121
218201
Jun 15 14:26:54 2021: [INFO] Got ETSI response (121 bytes)
219202
Got ETSI static ephemeral key (121 bytes)
220-
Jun 15 14:26:54 2021: [INFO] ECC Pub X: C30E4D7E99B80D561736640FE108DB577DC399C9E9CAAA5338989D7B06978BA7
221-
Jun 15 14:26:54 2021: [INFO] ECC Pub Y: E446F67FED21B8B4267CD91738AC078CD32BB6E039875A4484CA07E859658526
203+
Jun 15 14:26:54 2021: [INFO] SECP256R1: E24EF332747DF70CD4E5
222204
223205
TLS Accept 127.0.0.1
224206
Jun 15 14:27:01 2021: [DEBUG] HTTP GET
@@ -254,7 +236,6 @@ usage: ./decrypt or ./decrypt dumpFile keyServerURL [server] [port] [password]
254236
3. Run the middle-box decryption `./examples/middlebox/decrypt` and use the default parameters.
255237
4. Open a web browser to `https://localhost` or run the HTTP client example `./examples/https/client`.
256238
5. In the middle-box decryption window you will see the decrypted HTTPS traffic.
257-
co
258239

259240
Notes:
260241

@@ -270,10 +251,73 @@ Notes:
270251
4) If you get "Permission denied" errors try adding `sudo` to the commands.
271252

272253

254+
### Demo example output
255+
256+
```
257+
% ./src/wolfkeymgr
258+
Aug 03 15:05:21 2021: [INFO] Starting Key Manager
259+
Aug 03 15:05:21 2021: [INFO] To exit use ctrl+c
260+
Aug 03 15:05:21 2021: [INFO] loaded CA certificate file ./certs/ca-cert.pem
261+
Aug 03 15:05:21 2021: [INFO] loaded key file ./certs/server-rsa-key.pem
262+
Aug 03 15:05:21 2021: [INFO] loaded certificate file ./certs/server-rsa-cert.pem
263+
Aug 03 15:05:21 2021: [ERRO] Vault open failed, creating new
264+
Aug 03 15:05:21 2021: [INFO] Vault ./wolfkeymgr.vault opened (0 bytes)
265+
Aug 03 15:05:21 2021: [INFO] Version: 1
266+
Aug 03 15:05:21 2021: [INFO] Header Size: 296
267+
Aug 03 15:05:21 2021: [INFO] Item Count: 0
268+
Aug 03 15:05:21 2021: [INFO] Total Size: 0
269+
Aug 03 15:05:21 2021: [WARN] Generating new SECP256R1 key
270+
Aug 03 15:05:21 2021: [INFO] Binding listener :::8119
271+
Aug 03 15:05:21 2021: [INFO] Setting up new ETSI conn item pool
272+
Aug 03 15:05:21 2021: [INFO] Growing ETSI service conn pool
273+
Aug 03 15:05:21 2021: [INFO] Growing ETSI service conn pool
274+
Aug 03 15:05:21 2021: [INFO] SECP256R1: E24EF332747DF70CD4E5
275+
Aug 03 15:05:21 2021: [WARN] Vault Auth: Setting up new encryption key
276+
Aug 03 15:05:21 2021: [INFO] Next key renewal 3600 seconds
277+
```
278+
279+
```
280+
% ./examples/https/server
281+
HTTPS Server: Port 443
282+
Aug 03 15:09:50 2021: [INFO] Connected to ETSI service
283+
```
284+
285+
```
286+
% ./examples/middlebox/decrypt
287+
1. lo0 (No description available)
288+
2. en0 (No description available)
289+
Enter the interface number (1-2) [default: 1]:
290+
server = 127.0.0.1
291+
server = ::1
292+
server = fe80::1
293+
Enter the port to scan [default: 443]:
294+
Enter the server key [default: https://localhost:8119]:
295+
Aug 03 15:07:33 2021: [INFO] Connected to ETSI service
296+
...
297+
298+
Got ETSI static ephemeral key (121 bytes)
299+
Aug 03 15:07:33 2021: [INFO] SECP256R1: E24EF332747DF70CD4E5
300+
Loaded key for fe80::1:443
301+
SSL App Data(30:323):GET / HTTP/1.1
302+
Host: localhost
303+
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
304+
Accept-Language: en-us
305+
Connection: keep-alive
306+
Accept-Encoding: gzip, deflate, br
307+
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1 Safari/605.1.15
308+
309+
310+
SSL App Data(32:132):HTTP/1.1 200 OK
311+
Content-Type: text/html
312+
Connection: keep-alive
313+
Content-Length: 44
314+
315+
<html><body><h1>It works!</h1></body></html>
316+
```
317+
273318
## Features Missing
274-
* Finish adding multiple server support with "fingerprint" (see `ETSI_SVC_MAX_SERVERS`)
275319
* Find error response message (currently disconnects with socket FIN)
276-
* ED25519 and ED448
320+
* Curve25519 and Curve448
277321
* X509 Visibility support
278322
* TLS v1.2 ephemeral key support
279323

configure.ac

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
AC_PREREQ(2.59)
77

8-
AC_INIT([wolfKeyManager],[0.10],[http://www.wolfssl.com])
8+
AC_INIT([wolfKeyManager],[0.11],[http://www.wolfssl.com])
99
AC_CONFIG_AUX_DIR(config)
1010
AC_CONFIG_HEADERS([wolfkeymgr/config.h])
1111
AC_CONFIG_MACRO_DIR(m4)
@@ -71,7 +71,7 @@ LT_PREREQ([2.2])
7171
LT_INIT([disable-static win32-dll])
7272

7373
# Shared library versioning
74-
WOLFKM_LIBRARY_VERSION=6:0:0
74+
WOLFKM_LIBRARY_VERSION=7:0:0
7575
# | | |
7676
# +------+ | +---+
7777
# | | |

examples/etsi_test/etsi_test.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ typedef struct WorkThreadInfo {
4343
int requests;
4444
int timeoutSec;
4545
int requestType;
46-
const char* findName; /* contextStr */
46+
const char* contextStr;
4747
const char* fingerprint;
4848
char* saveResp;
4949
word16 port;
@@ -111,8 +111,8 @@ static int DoKeyRequest(EtsiClientCtx* client, WorkThreadCtx* tctx)
111111
/* push: will wait for server to push new keys */
112112
/* get: will ask server for key and return */
113113
if (info->requestType == REQ_TYPE_GET) {
114-
ret = wolfEtsiClientGet(client, &tctx->key, info->keyType, NULL, NULL,
115-
info->timeoutSec);
114+
ret = wolfEtsiClientGet(client, &tctx->key, info->keyType, NULL,
115+
info->contextStr, info->timeoutSec);
116116
/* positive return means new key returned */
117117
/* zero means, same key is used */
118118
/* negative means error */
@@ -134,7 +134,7 @@ static int DoKeyRequest(EtsiClientCtx* client, WorkThreadCtx* tctx)
134134
else if (info->requestType == REQ_TYPE_FIND) {
135135
/* find key from server call and new keys from server will issue callback */
136136
ret = wolfEtsiClientFind(client, &tctx->key, info->keyType,
137-
info->fingerprint, info->findName, info->timeoutSec);
137+
info->fingerprint, info->contextStr, info->timeoutSec);
138138
if (ret > 0) {
139139
/* use same "push" callback to test key use / print */
140140
keyCb(client, &tctx->key, tctx);
@@ -217,7 +217,7 @@ static void Usage(void)
217217
printf("-K <keyt> Key Type: SECP256R1, FFDHE_2048, X25519 or X448 (default %s)\n",
218218
wolfEtsiKeyGetTypeStr(ETSI_TEST_KEY_TYPE));
219219
printf("-F <fprint> Fingerprint used for multiple servers (first 80-bit of pkey hash as hex string)\n");
220-
printf("-n <name> Find key using public key name (hex string)\n");
220+
printf("-C <name> Find key using public key name (hex string)\n");
221221
}
222222

223223
int etsi_test(int argc, char** argv)
@@ -242,7 +242,7 @@ int etsi_test(int argc, char** argv)
242242
info.keyType = ETSI_TEST_KEY_TYPE;
243243

244244
/* argument processing */
245-
while ((ch = getopt(argc, argv, "?eh:p:t:l:r:f:gus:k:w:c:A:K:F:n:")) != -1) {
245+
while ((ch = getopt(argc, argv, "?eh:p:t:l:r:f:gus:k:w:c:A:K:F:C:")) != -1) {
246246
switch (ch) {
247247
case '?' :
248248
Usage();
@@ -308,14 +308,13 @@ int etsi_test(int argc, char** argv)
308308
break;
309309
}
310310
case 'F':
311-
/* optional ID for server on key GET / PUT */
312311
/* sha256 hash of public key - 10 bytes (80 bits) as hex string */
312+
info.requestType = REQ_TYPE_FIND;
313313
info.fingerprint = optarg;
314314
break;
315-
case 'n':
316-
/* Find key based on first 64 bytes of public key as hex string */
317-
info.requestType = REQ_TYPE_FIND;
318-
info.findName = optarg;
315+
case 'C':
316+
/* optional ID for server on key GET / PUT */
317+
info.contextStr = optarg;
319318
break;
320319
default:
321320
Usage();

examples/middlebox/decrypt.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,12 @@ static int etsi_client_find(char* urlStr, EtsiKey* key, int namedGroup,
142142

143143
ret = etsi_client_connect(urlStr);
144144
if (ret == 0 && key) {
145-
char name[ETSI_MAX_KEY_NAME_STR];
146-
word32 nameSz = (word32)sizeof(name);
147-
ret = wolfEtsiGetPubKeyName((EtsiKeyType)namedGroup, pub, pubSz,
148-
name, &nameSz);
145+
char fpStr[ETSI_MAX_FINGERPRINT_STR];
146+
word32 fpStrSz = (word32)sizeof(fpStr);
147+
ret = wolfEtsiCalcTlsFingerprint((EtsiKeyType)namedGroup, pub, pubSz,
148+
fpStr, &fpStrSz);
149149
if (ret == 0) {
150-
ret = wolfEtsiClientFind(gEtsiClient, key, namedGroup, name,
150+
ret = wolfEtsiClientFind(gEtsiClient, key, namedGroup, fpStr,
151151
NULL, ETSI_TEST_TIMEOUT_MS);
152152
}
153153
if (ret < 0) {
@@ -159,6 +159,7 @@ static int etsi_client_find(char* urlStr, EtsiKey* key, int namedGroup,
159159
key->responseSz);
160160
wolfEtsiKeyPrint(key);
161161
}
162+
(void)fpStrSz;
162163
}
163164
return ret;
164165
}
@@ -171,11 +172,6 @@ static int myKeyCb(void* vSniffer, int namedGroup,
171172
int ret;
172173
static EtsiKey key;
173174

174-
if (!isOfflinePcap) {
175-
/* decrypt is real-time, don't use find */
176-
return 0;
177-
}
178-
179175
ret = etsi_client_find(NULL, &key, namedGroup, srvPub, srvPubSz);
180176
if (ret >= 0) {
181177
byte* keyBuf = NULL;

src/keymanager.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ int main(int argc, char** argv)
207207
/* start log */
208208
wolfKeyMgr_SetLogFile(logName, daemon, logLevel);
209209
XLOG(WOLFKM_LOG_INFO, "Starting Key Manager\n");
210+
XLOG(WOLFKM_LOG_INFO, "\tTo exit use ctrl+c\n");
210211

211212
if (CheckCtcSettings() != 1) {
212213
XLOG(WOLFKM_LOG_ERROR, "wolfSSL math library mismatch in settings\n");

0 commit comments

Comments
 (0)