diff --git a/include/pcp/mgmt.h b/include/pcp/mgmt.h
index c9b3469..508fed7 100644
--- a/include/pcp/mgmt.h
+++ b/include/pcp/mgmt.h
@@ -271,6 +271,7 @@ json_t *pcp_sk2json(pcp_key_t *sk, byte *sig,size_t siglen);
json_t *pcp_pk2json(pcp_pubkey_t *pk);
pcp_ks_bundle_t *pcp_import_pub_json(PCPCTX *ptx, byte *raw, size_t rawsize);
+Buffer *pcp_import_secret_json(PCPCTX *ptx, Buffer *json);
#endif
diff --git a/libpcp/mgmt.c b/libpcp/mgmt.c
index e80cb07..e2ec346 100644
--- a/libpcp/mgmt.c
+++ b/libpcp/mgmt.c
@@ -656,36 +656,27 @@ Buffer *pcp_export_secret(PCPCTX *ptx, pcp_key_t *sk, char *passphrase) {
buffer_add(raw, sk->secret, 32);
buffer_add(raw, sk->edsecret, 64);
-#ifdef HAVE_JSON
- if(! ptx->json) {
- /* only encrypt everything if exporting in native format */
-#endif
+ buffer_add(raw, sk->masterpub, 32);
+ buffer_add(raw, sk->pub, 32);
+ buffer_add(raw, sk->edpub, 32);
- buffer_add(raw, sk->masterpub, 32);
- buffer_add(raw, sk->pub, 32);
- buffer_add(raw, sk->edpub, 32);
-
- if(strlen(sk->owner) > 0) {
- buffer_add16be(raw, strlen(sk->owner));
- buffer_add(raw, sk->owner, strlen(sk->owner));
- }
- else
- buffer_add16be(raw, 0);
-
- if(strlen(sk->mail) > 0) {
- buffer_add16be(raw, strlen(sk->mail));
- buffer_add(raw, sk->mail, strlen(sk->mail));
- }
- else
- buffer_add16be(raw, 0);
-
- buffer_add64be(raw, sk->ctime);
- buffer_add32be(raw, sk->version);
- buffer_add32be(raw, sk->serial);
-
-#ifdef HAVE_JSON
+ if(strlen(sk->owner) > 0) {
+ buffer_add16be(raw, strlen(sk->owner));
+ buffer_add(raw, sk->owner, strlen(sk->owner));
}
-#endif
+ else
+ buffer_add16be(raw, 0);
+
+ if(strlen(sk->mail) > 0) {
+ buffer_add16be(raw, strlen(sk->mail));
+ buffer_add(raw, sk->mail, strlen(sk->mail));
+ }
+ else
+ buffer_add16be(raw, 0);
+
+ buffer_add64be(raw, sk->ctime);
+ buffer_add32be(raw, sk->version);
+ buffer_add32be(raw, sk->serial);
nonce = ucmalloc(crypto_secretbox_NONCEBYTES);
arc4random_buf(nonce, crypto_secretbox_NONCEBYTES);
@@ -769,6 +760,16 @@ pcp_key_t *pcp_import_secret_native(PCPCTX *ptx, Buffer *cipher, char *passphras
uint16_t notationlen = 0;
Buffer *blob = buffer_new(512, "secretdecryptbuf");
+
+#ifdef HAVE_JSON
+ if(ptx->json) {
+ Buffer *parsed = pcp_import_secret_json(ptx, cipher);
+ if(parsed == NULL) {
+ goto impserr1;
+ }
+ cipher = parsed; /* re-used */
+ }
+#endif
if(buffer_get_chunk(cipher, nonce, crypto_secretbox_NONCEBYTES) == 0)
goto impserr1;
@@ -954,7 +955,7 @@ Buffer *pcp_export_json_secret(PCPCTX *ptx, pcp_key_t *sk, byte *nonce, byte *ci
jdump = json_dumps(jout, JSON_INDENT(4) | JSON_PRESERVE_ORDER);
if(jdump != NULL) {
- buffer_add_str(b, jdump);
+ buffer_add(b, jdump, strlen(jdump));
free(jdump);
}
else {
@@ -990,6 +991,57 @@ Buffer *pcp_export_json_pub(PCPCTX *ptx, pcp_key_t *sk, byte *sig, size_t siglen
return b;
}
+Buffer *pcp_import_secret_json(PCPCTX *ptx, Buffer *json) {
+ json_error_t jerror;
+ json_t *jtmp, *jin;
+ size_t maxblob = 2048;
+ size_t binlen;
+ char *hexerr = "failed to decode hex string";
+
+ jin = json_loadb((char *)buffer_get(json), buffer_size(json), JSON_DISABLE_EOF_CHECK, &jerror);
+ if(jin == NULL)
+ goto jirr1;
+
+ byte *blob = ucmalloc(maxblob);
+ /* re-use the buffer */
+ json->end = 0;
+ json->offset = 0;
+
+ jtmp = json_object_get(jin, "nonce");
+ if(jtmp == NULL)
+ goto jirr2;
+ binlen = _hex2bin(json_string_value(jtmp), blob, maxblob);
+ if(binlen > 1)
+ buffer_add(json, blob, binlen);
+ else {
+ strcpy(jerror.text, hexerr);
+ goto jirr2;
+ }
+
+ jtmp = json_object_get(jin, "secrets");
+ if(jtmp == NULL)
+ goto jirr2;
+ binlen = _hex2bin(json_string_value(jtmp), blob, maxblob);
+ if(binlen > 1)
+ buffer_add(json, blob, binlen);
+ else {
+ strcpy(jerror.text, hexerr);
+ goto jirr2;
+ }
+
+ json_decref(jin);
+ ucfree(blob, maxblob);
+ return json;
+
+ jirr2:
+ ucfree(blob, maxblob);
+ json_decref(jin);
+
+ jirr1:
+ fatal(ptx, "JSON decoding error: %s", jerror.text);
+ return NULL;
+}
+
pcp_ks_bundle_t *pcp_import_pub_json(PCPCTX *ptx, byte *raw, size_t rawsize) {
pcp_ks_bundle_t *b = NULL;
pcp_keysig_t *s = NULL;
@@ -1137,7 +1189,6 @@ pcp_ks_bundle_t *pcp_import_pub_json(PCPCTX *ptx, byte *raw, size_t rawsize) {
jerr1:
fatal(ptx, "JSON decoding error: %s", jerror.text);
- fprintf(stderr, "JSON decoding error: %s\n", jerror.text);
return NULL;
}
#endif
diff --git a/tests/jsonunittests.cfg b/tests/jsonunittests.cfg
index f8251cf..cbac5e3 100644
--- a/tests/jsonunittests.cfg
+++ b/tests/jsonunittests.cfg
@@ -35,6 +35,14 @@ include keys.cfg
cmd = cat testkeyvjapub.json
expect = /"Alicia"/
+
+ cmd = $pcp -V vja -s -j -x a -O testkeyvjasec.json
+ expect-file testkeyvjasec.json
+
+
+ cmd = cat testkeyvjasec.json
+ expect = /"Alicia"/
+
@@ -43,6 +51,21 @@ include keys.cfg
cmd = $pcp -V vjb -K -I testkeyvjapub.json -j
expect /added/
+
+ cmd = $pcp -V vjb -l
+ expect = /Alicia/
+
+
+
+
+
+ cmd = $pcp -V vjc -K -I testkeyvjasec.json -x a -j
+ expect = /added/
+
+
+ cmd = $pcp -V vjc -l
+ expect = /Alicia/
+