From a21ace7b4dc27cc9fcbecbe8dee6046c4fc355ba Mon Sep 17 00:00:00 2001 From: Andrew Siplas Date: Sun, 25 Nov 2018 00:56:39 -0500 Subject: [PATCH] Implement elementary `.pem` file parsing. e.g. `jose jws sig -p ~/gcloud.pem -I payload.json` --- cmd/jose.c | 35 +++++++++++++++++++++++++++++++++++ cmd/jose.h | 7 +++++++ cmd/jws/sig.c | 6 ++++++ cmd/meson.build | 2 +- 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/cmd/jose.c b/cmd/jose.c index 0d908b97..3dea14e9 100644 --- a/cmd/jose.c +++ b/cmd/jose.c @@ -23,6 +23,10 @@ #include #include +#include +#include +#include + #define MAXBUFLEN 1024 #define RQARG required_argument #define NOARG no_argument @@ -376,6 +380,37 @@ jcmd_opt_set_jwks(const jcmd_cfg_t *cfg, void *vopt, const char *arg) } } +bool +jcmd_opt_set_pem(const jcmd_cfg_t *cfg, void *vopt, const char *arg) +{ + bool retval; + json_t **jwks = vopt; + EVP_PKEY *pkey = EVP_PKEY_new(); + + if (!pkey) + return false; + + if (!*jwks) + *jwks = json_array(); + + if (strcmp(arg, "-") == 0) { + if (!PEM_read_PrivateKey(stdin, &pkey, NULL, NULL)) + return false; + } else { + FILE_AUTO *file = fopen(arg, "r"); + // TODO: encrypted key callback for password. + if (!(file && PEM_read_PrivateKey(file, &pkey, NULL, NULL))) + return false; + } + + retval = json_array_append_new(*jwks, + jose_openssl_jwk_from_EVP_PKEY(NULL, pkey)) == 0; + + EVP_PKEY_free(pkey); + + return retval; +} + bool jcmd_opt_set_flag(const jcmd_cfg_t *cfg, void *vopt, const char *arg) { diff --git a/cmd/jose.h b/cmd/jose.h index d1dcb2c7..bf82d81e 100644 --- a/cmd/jose.h +++ b/cmd/jose.h @@ -84,6 +84,12 @@ static const jcmd_doc_t jcmd_doc_key[] = { {} }; +static const jcmd_doc_t jcmd_doc_pem[] = { + { .arg = "FILE", .doc="Import JWK from '.PEM' FILE" }, + { .arg = "-", .doc="Import JWK from '.PEM' on standard input" }, + {} +}; + void jcmd_push(jcmd_t *cmd); @@ -98,6 +104,7 @@ jcmd_set_t jcmd_opt_set_jsons; /* Takes json_t** */ jcmd_set_t jcmd_opt_set_json; /* Takes json_t** */ jcmd_set_t jcmd_opt_set_jwkt; /* Takes json_t** */ jcmd_set_t jcmd_opt_set_jwks; /* Takes json_t** */ +jcmd_set_t jcmd_opt_set_pem; /* Takes json_t** */ jcmd_set_t jcmd_opt_set_flag; /* Takes bool* */ void diff --git a/cmd/jws/sig.c b/cmd/jws/sig.c index b04ec35b..08828dce 100644 --- a/cmd/jws/sig.c +++ b/cmd/jws/sig.c @@ -72,6 +72,12 @@ static const jcmd_cfg_t cfgs[] = { .set = jcmd_opt_set_jwks, .doc = jcmd_doc_key, }, + { + .opt = { "pem", required_argument, .val = 'p' }, + .off = offsetof(jcmd_opt_t, keys), + .set = jcmd_opt_set_pem, + .doc = jcmd_doc_pem, + }, { .opt = { "output", required_argument, .val = 'o' }, .off = offsetof(jcmd_opt_t, io.output), diff --git a/cmd/meson.build b/cmd/meson.build index 64f206c2..dba953ba 100644 --- a/cmd/meson.build +++ b/cmd/meson.build @@ -21,7 +21,7 @@ executable(meson.project_name(), 'jwe/enc.c', 'alg.c', 'fmt.c', - dependencies: jansson, + dependencies: [ jansson, libcrypto ], link_with: libjose, install: true )