Skip to content

Commit f83ec8a

Browse files
committed
wolfKeyMgr v0.8:
* Added DH key support. * Added HTTP support for fingerprints, groups and contextstr. * Added ETSI client key argument (`-K`) * Fixes for URI encoding. * Refactor of service to support more key types. * Refactor of internal structure names to leading upper case. * Removed the "noTLS" build option.
1 parent 86bdfb7 commit f83ec8a

File tree

12 files changed

+734
-327
lines changed

12 files changed

+734
-327
lines changed

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.7],[http://www.wolfssl.com])
8+
AC_INIT([wolfKeyManager],[0.8],[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=4:1:0
74+
WOLFKM_LIBRARY_VERSION=5:0:0
7575
# | | |
7676
# +------+ | +---+
7777
# | | |

examples/etsi_client/etsi_client.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ typedef struct WorkThreadInfo {
4545
const char* clientCertFile;
4646
const char* caFile;
4747
EtsiKey key;
48+
EtsiKeyType keyType;
4849
WOLFSSL_CTX* ctx; /* test ctx loading static ephemeral key */
4950
} WorkThreadInfo;
5051

@@ -61,11 +62,12 @@ static int keyCb(EtsiClientCtx* client, EtsiKey* key, void* userCtx)
6162
{
6263
int ret = 0;
6364
WorkThreadInfo* info = (WorkThreadInfo*)userCtx;
65+
int keyAlgo = wolfEtsiKeyGetPkType(key);
6466

6567
/* test use-case setting static ephemeral key */
6668
if (info->ctx) {
6769
ret = wolfSSL_CTX_set_ephemeral_key(info->ctx,
68-
WC_PK_TYPE_ECDH, key->response, key->responseSz,
70+
keyAlgo, key->response, key->responseSz,
6971
WOLFSSL_FILETYPE_ASN1);
7072
}
7173
wolfEtsiKeyPrint(key);
@@ -80,12 +82,11 @@ static int keyCb(EtsiClientCtx* client, EtsiKey* key, void* userCtx)
8082
static int DoKeyRequest(EtsiClientCtx* client, WorkThreadInfo* info)
8183
{
8284
int ret;
83-
EtsiKeyType keyType = ETSI_KEY_TYPE_SECP256R1;
8485

8586
/* push: will wait for server to push new keys */
8687
/* get: will ask server for key and return */
8788
if (info->useGet) {
88-
ret = wolfEtsiClientGet(client, &info->key, keyType, NULL, NULL,
89+
ret = wolfEtsiClientGet(client, &info->key, info->keyType, NULL, NULL,
8990
info->timeoutSec);
9091
/* positive return means new key returned */
9192
/* zero means, same key is used */
@@ -103,7 +104,7 @@ static int DoKeyRequest(EtsiClientCtx* client, WorkThreadInfo* info)
103104
}
104105
else {
105106
/* blocking call and new keys from server will issue callback */
106-
ret = wolfEtsiClientPush(client, keyType, NULL, NULL, keyCb, info);
107+
ret = wolfEtsiClientPush(client, info->keyType, NULL, NULL, keyCb, info);
107108
}
108109

109110
if (ret != 0) {
@@ -177,6 +178,7 @@ static void Usage(void)
177178
printf("-w <pass> TLS Client Key Password, default %s\n", WOLFKM_ETSICLIENT_PASS);
178179
printf("-c <pem> TLS Client Certificate, default %s\n", WOLFKM_ETSICLIENT_CERT);
179180
printf("-A <pem> TLS CA Certificate, default %s\n", WOLFKM_ETSICLIENT_CA);
181+
printf("-K <keyt> Key Type: SECP256R1 (default), FFDHE_2048, X25519 or X448\n");
180182
}
181183

182184
int main(int argc, char** argv)
@@ -199,13 +201,10 @@ int main(int argc, char** argv)
199201
info.clientCertFile = WOLFKM_ETSICLIENT_CERT;
200202
info.caFile = WOLFKM_ETSICLIENT_CA;
201203
info.useGet = 1;
202-
203-
#ifdef DISABLE_SSL
204-
usingTLS = 0; /* can only disable at build time */
205-
#endif
204+
info.keyType = ETSI_KEY_TYPE_SECP256R1;
206205

207206
/* argument processing */
208-
while ((ch = getopt(argc, argv, "?eh:p:t:l:r:f:gus:k:w:c:A:")) != -1) {
207+
while ((ch = getopt(argc, argv, "?eh:p:t:l:r:f:gus:k:w:c:A:K:")) != -1) {
209208
switch (ch) {
210209
case '?' :
211210
Usage();
@@ -256,7 +255,20 @@ int main(int argc, char** argv)
256255
case 'A':
257256
info.caFile = optarg;
258257
break;
259-
258+
case 'K':
259+
{
260+
/* find key type */
261+
for (i=(int)ETSI_KEY_TYPE_MIN; i<=(int)ETSI_KEY_TYPE_FFDHE_8192; i++) {
262+
const char* keyStr = wolfEtsiKeyGetTypeStr((EtsiKeyType)i);
263+
if (keyStr != NULL) {
264+
if (XSTRNCMP(optarg, keyStr, XSTRLEN(keyStr)) == 0) {
265+
info.keyType = (EtsiKeyType)i;
266+
break;
267+
}
268+
}
269+
}
270+
break;
271+
}
260272
default:
261273
Usage();
262274
exit(EX_USAGE);

src/keymanager.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static void Usage(void)
4848
}
4949

5050
static int wolfKeyMgr_AddSigHandler(struct event_base* mainBase,
51-
signalArg* sigArg, int sig)
51+
SignalArg* sigArg, int sig)
5252
{
5353
struct event* signalEvent = event_new(mainBase, sig,
5454
(EV_SIGNAL | EV_PERSIST), wolfKeyMgr_SignalCb, sigArg);
@@ -70,15 +70,15 @@ int main(int argc, char** argv)
7070
char* pidName = WOLFKM_DEFAULT_PID;
7171
struct event_base* mainBase = NULL; /* main thread's base */
7272
FILE* pidF = 0;
73-
svcInfo* etsiSvc = NULL;
73+
SvcInfo* etsiSvc = NULL;
7474
int sec;
7575
word32 timeoutSec = WOLFKM_DEFAULT_TIMEOUT, renewSec = WOLFKM_KEY_RENEW_TIMEOUT;
7676
int disableMutualAuth = 0; /* on by default */
7777
const char* serverKey = WOLFKM_ETSISVC_KEY;
7878
const char* serverKeyPass = WOLFKM_ETSISVC_KEY_PASSWORD;
7979
const char* serverCert = WOLFKM_ETSISVC_CERT;
8080
const char* caCert = WOLFKM_ETSISVC_CA;
81-
signalArg sigArgInt, sigArgTerm;
81+
SignalArg sigArgInt, sigArgTerm;
8282

8383
/* argument processing */
8484
while ((ch = getopt(argc, argv, "?bis:t:o:f:l:dk:w:c:A:r:")) != -1) {

src/mod_etsi.c

Lines changed: 101 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ int wolfEtsiClientMakeRequest(EtsiClientType type, const char* fingerprint,
130130
const char* groups, const char* contextstr, byte* request, word32* requestSz)
131131
{
132132
int ret;
133-
char uri[256];
133+
char uri[HTTP_MAX_URI*3]; /* fingerprint, groups, contextStr */
134+
size_t uriLen;
134135
HttpHeader headers[1];
135136
HttpMethodType httpType;
136137
headers[0].type = HTTP_HDR_ACCEPT;
@@ -145,11 +146,36 @@ int wolfEtsiClientMakeRequest(EtsiClientType type, const char* fingerprint,
145146
else {
146147
/* use GET with either fingerprint (with optional groups/context) */
147148
httpType = HTTP_METHOD_GET;
148-
snprintf(uri, sizeof(uri),
149-
"/.well-known/enterprise-transport-security/keys?fingerprints=%s%s%s%s%s",
150-
fingerprint == NULL ? "" : fingerprint,
151-
groups == NULL ? "" : "&groups=", groups == NULL ? "" : groups,
152-
contextstr == NULL ? "" : "&contextstr=", contextstr == NULL ? "" : contextstr);
149+
strncpy(uri,
150+
"/.well-known/enterprise-transport-security/keys?fingerprints=",
151+
sizeof(uri));
152+
uriLen = strlen(uri);
153+
if (fingerprint != NULL) {
154+
ret = wolfHttpUriEncode(fingerprint, strlen(fingerprint),
155+
uri+uriLen, sizeof(uri)-uriLen);
156+
if (ret < 0)
157+
return WOLFKM_BAD_ARGS;
158+
uriLen += ret;
159+
}
160+
if (groups != NULL) {
161+
strncpy(uri+uriLen, "&groups=", sizeof(uri)-uriLen);
162+
uriLen = strlen(uri);
163+
ret = wolfHttpUriEncode(groups, strlen(groups),
164+
uri+uriLen, sizeof(uri)-uriLen);
165+
if (ret < 0)
166+
return WOLFKM_BAD_ARGS;
167+
uriLen += ret;
168+
}
169+
if (contextstr != NULL) {
170+
strncpy(uri+uriLen, "&contextstr=", sizeof(uri)-uriLen);
171+
uriLen = strlen(uri);
172+
ret = wolfHttpUriEncode(contextstr, strlen(contextstr),
173+
uri+uriLen, sizeof(uri)-uriLen);
174+
if (ret < 0)
175+
return WOLFKM_BAD_ARGS;
176+
uriLen += ret;
177+
}
178+
uri[uriLen] = '\0'; /* null term */
153179
}
154180
ret = wolfHttpClient_EncodeRequest(httpType, uri, request,
155181
requestSz, headers, sizeof(headers)/sizeof(HttpHeader));
@@ -353,6 +379,57 @@ int wolfEtsiKeyGetPkType(EtsiKey* key)
353379
return WC_PK_TYPE_NONE;
354380
}
355381

382+
const char* wolfEtsiKeyGetTypeStr(EtsiKeyType type)
383+
{
384+
switch (type) {
385+
case ETSI_KEY_TYPE_SECP160K1:
386+
return "SECP160K1";
387+
case ETSI_KEY_TYPE_SECP160R1:
388+
return "SECP160R1";
389+
case ETSI_KEY_TYPE_SECP160R2:
390+
return "SECP160R2";
391+
case ETSI_KEY_TYPE_SECP192K1:
392+
return "SECP192K1";
393+
case ETSI_KEY_TYPE_SECP192R1:
394+
return "SECP192R1";
395+
case ETSI_KEY_TYPE_SECP224K1:
396+
return "SECP224K1";
397+
case ETSI_KEY_TYPE_SECP224R1:
398+
return "SECP224R1";
399+
case ETSI_KEY_TYPE_SECP256K1:
400+
return "SECP256K1";
401+
case ETSI_KEY_TYPE_SECP256R1:
402+
return "SECP256R1";
403+
case ETSI_KEY_TYPE_SECP384R1:
404+
return "SECP384R1";
405+
case ETSI_KEY_TYPE_SECP521R1:
406+
return "SECP521R1";
407+
case ETSI_KEY_TYPE_BRAINPOOLP256R1:
408+
return "BRAINPOOLP256R1";
409+
case ETSI_KEY_TYPE_BRAINPOOLP384R1:
410+
return "BRAINPOOLP384R1";
411+
case ETSI_KEY_TYPE_BRAINPOOLP512R1:
412+
return "BRAINPOOLP512R1";
413+
case ETSI_KEY_TYPE_X25519:
414+
return "X25519";
415+
case ETSI_KEY_TYPE_X448:
416+
return "X448";
417+
case ETSI_KEY_TYPE_FFDHE_2048:
418+
return "FFDHE_2048";
419+
case ETSI_KEY_TYPE_FFDHE_3072:
420+
return "FFDHE_3072";
421+
case ETSI_KEY_TYPE_FFDHE_4096:
422+
return "FFDHE_4096";
423+
case ETSI_KEY_TYPE_FFDHE_6144:
424+
return "FFDHE_6144";
425+
case ETSI_KEY_TYPE_FFDHE_8192:
426+
return "FFDHE_8192";
427+
default:
428+
break;
429+
}
430+
return NULL;
431+
}
432+
356433
int wolfEtsiKeyLoadCTX(EtsiKey* key, WOLFSSL_CTX* ctx)
357434
{
358435
int keyAlgo;
@@ -406,7 +483,8 @@ int wolfEtsiKeyPrint(EtsiKey* key)
406483
ret = wc_EccPrivateKeyDecode((byte*)key->response, &idx, &ecKey,
407484
key->responseSz);
408485
if (ret == 0) {
409-
byte pubX[32*2+1], pubY[32*2+1];
486+
byte pubX[MAX_ECC_BYTES*2+1];
487+
byte pubY[MAX_ECC_BYTES*2+1];
410488
word32 pubXLen = sizeof(pubX), pubYLen = sizeof(pubY);
411489
ret = wc_ecc_export_ex(&ecKey,
412490
pubX, &pubXLen,
@@ -423,9 +501,22 @@ int wolfEtsiKeyPrint(EtsiKey* key)
423501
#endif
424502
#ifndef NO_DH
425503
if (keyAlgo == WC_PK_TYPE_DH) {
426-
/* TODO: add example for loading DHE key and print */
427-
//DhKey dh;
428-
XLOG(WOLFKM_LOG_INFO, "DH Pub: TODO\n");
504+
/* example for loading DHE key */
505+
DhKey dhKey;
506+
ret = wc_InitDhKey(&dhKey);
507+
if (ret == 0) {
508+
word32 idx = 0;
509+
ret = wc_DhKeyDecode((byte*)key->response, &idx, &dhKey, key->responseSz);
510+
if (ret == 0) {
511+
byte pubKey[MAX_DH_PUB_SZ];
512+
word32 pubKeyLen = sizeof(pubKey);
513+
ret = wc_DhExportKeyPair(&dhKey, NULL, NULL, pubKey, &pubKeyLen);
514+
if (ret == 0) {
515+
XLOG(WOLFKM_LOG_INFO, "DH Pub: %d\n", pubKeyLen);
516+
}
517+
}
518+
wc_FreeDhKey(&dhKey);
519+
}
429520
}
430521
#endif
431522
#ifdef HAVE_CURVE25519

src/mod_http.c

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -433,21 +433,26 @@ void wolfHttpResponsePrint(HttpRsp* rsp)
433433
}
434434

435435

436-
char* wolfHttpUriEncode(const byte *s, char *enc)
436+
int wolfHttpUriEncode(const char *s, size_t sSz, char *enc, size_t encSz)
437437
{
438-
for (; *s; s++){
438+
int idx = 0;
439+
for (; idx < sSz && *s; s++){
440+
if (idx + 3 > encSz)
441+
return -1;
439442
if (*s == '*' || *s == '-' || *s == '.' || *s == '_') {
440443
char a = (char)(*s >> 4), b = (char)(*s & 0xff);
441-
*enc++ = '%';
442-
*enc++ = (a < 10) ? '0' + a : 'A' + a - 10;
443-
*enc++ = (b < 10) ? '0' + b : 'A' + b - 10;
444+
enc[idx++] = '%';
445+
enc[idx++] = (a < 10) ? '0' + a : 'A' + a - 10;
446+
enc[idx++] = (b < 10) ? '0' + b : 'A' + b - 10;
447+
}
448+
else if (*s == ' ') {
449+
enc[idx++] = '+';
450+
}
451+
else {
452+
enc[idx++] = *s;
444453
}
445-
else if (*s == ' ')
446-
*enc++ = '+';
447-
else
448-
*enc++ = *s;
449454
}
450-
return enc;
455+
return idx;
451456
}
452457

453458
static int hex_to_char(char a, byte* out)
@@ -464,24 +469,27 @@ static int hex_to_char(char a, byte* out)
464469
return 1;
465470
}
466471

467-
byte* wolfHttpUriDecode(const char *s, byte *dec)
472+
int wolfHttpUriDecode(const char *s, size_t sSz, char *dec, size_t decSz)
468473
{
474+
int idx = 0;
469475
byte a, b;
470-
for (; *s; s++){
471-
if (*s == '%' &&
476+
for (; idx < sSz && *s; s++){
477+
if (idx + 1 > decSz)
478+
return -1;
479+
if (*s == '%' &&
472480
hex_to_char((char)s[1], &a) &&
473481
hex_to_char((char)s[2], &b)) {
474-
*dec++ = (a << 4 | b);
482+
dec[idx++] = (a << 4 | b);
475483
s+=2;
476484
}
477485
else if (*s == '+') {
478-
*dec++ = ' ';
486+
dec[idx++] = ' ';
479487
}
480488
else {
481-
*dec++ = *s;
489+
dec[idx++] = *s;
482490
}
483491
}
484-
return dec;
492+
return idx;
485493
}
486494

487495
int wolfHttpUrlDecode(HttpUrl* url, char* s)
@@ -519,3 +527,28 @@ int wolfHttpUrlDecode(HttpUrl* url, char* s)
519527
}
520528
return 0;
521529
}
530+
531+
/* item should include equal sign. Example: "fingerprint=" */
532+
int wolfHttpUriGetItem(const char* uri, const char* itemName, char* item,
533+
size_t itemSz)
534+
{
535+
int ret = -1; /* not found */
536+
const char *begin, *end;
537+
size_t len = 0;
538+
/* find item= */
539+
begin = strstr(uri, itemName);
540+
if (begin) {
541+
begin += strlen(itemName);
542+
543+
/* find next & or null term */
544+
end = strstr(begin, "&");
545+
if (end != NULL)
546+
len = (size_t)end - (size_t)begin;
547+
else
548+
len = strlen(begin);
549+
550+
/* perform URI decode */
551+
ret = wolfHttpUriDecode(begin, len, item, itemSz);
552+
}
553+
return ret;
554+
}

0 commit comments

Comments
 (0)