From b38441115629e765ec5c4d82b0ca5c9ad7738c88 Mon Sep 17 00:00:00 2001 From: saturneric Date: Sun, 28 Jul 2024 17:01:41 +0200 Subject: [PATCH] feat: paper key module is now useable --- src/m_paper_key/PaperKeyModule.cpp | 97 ++++++++++++++++++++---------- src/m_paper_key/extract.cpp | 5 +- src/m_paper_key/extract.h | 3 +- src/m_paper_key/output.cpp | 46 +++++++++++++- src/m_paper_key/output.h | 2 + src/m_paper_key/restore.cpp | 5 +- src/m_paper_key/restore.h | 2 +- 7 files changed, 117 insertions(+), 43 deletions(-) diff --git a/src/m_paper_key/PaperKeyModule.cpp b/src/m_paper_key/PaperKeyModule.cpp index c118bd9..695e149 100644 --- a/src/m_paper_key/PaperKeyModule.cpp +++ b/src/m_paper_key/PaperKeyModule.cpp @@ -28,10 +28,13 @@ #include "PaperKeyModule.h" +#include + #include #include "GFModuleDefine.h" #include "extract.h" +#include "restore.h" GF_MODULE_API_DEFINE("com.bktus.gpgfrontend.module.paper_key", "PaperKey", "1.0.0", "Integrated PaperKey Functions.", "Saturneric") @@ -52,70 +55,98 @@ EXECUTE_MODULE() { FLOG_DEBUG("paper key module executing, event id: %1", event["event_id"]); if (event["event_id"] == "REQUEST_TRANS_KEY_2_PAPER_KEY") { - if (event["secret_key"].isEmpty() || event["output_path"].isEmpty()) { - CB_ERR(event, -1, "secret key or output path is empty"); - } + if (event["secret_key"].isEmpty()) CB_ERR(event, -1, "secret key is empty"); - QByteArray secret_key_data = - QByteArray::fromBase64(event["secret_key"].toUtf8()); + QByteArray secret_key_rdata = + QByteArray::fromBase64(event["secret_key"].toLatin1()); QTemporaryFile secret_key_t_file; - if (!secret_key_t_file.open()) { + if (!secret_key_t_file.open()) CB_ERR(event, -1, "unable to open temporary file"); - } - secret_key_t_file.write(secret_key_data); + secret_key_t_file.write(secret_key_rdata); secret_key_t_file.flush(); - secret_key_t_file.seek(0); + secret_key_t_file.reset(); - FILE *file = fdopen(secret_key_t_file.handle(), "rb"); - if (file == nullptr) { + FILE *secret_key_file = fdopen(secret_key_t_file.handle(), "rb"); + if (secret_key_file == nullptr) CB_ERR(event, -1, "unable to convert QTemporaryFile to FILE*"); - } - extract(file, event["output_path"].toUtf8(), AUTO); + QTemporaryFile paper_key_t_file; + if (!paper_key_t_file.open()) + CB_ERR(event, -1, "unable to open temporary file"); - fclose(file); - } else if (event["event_id"] == "REQUEST_TRANS_PAPER_KEY_2_KEY") { - if (event["public_key"].isEmpty() || event["paper_key_secrets"].isEmpty()) { + FILE *paper_key_fp = fdopen(dup(paper_key_t_file.handle()), "w"); + if (paper_key_fp == nullptr) + CB_ERR(event, -1, "unable to convert QTemporaryFile to FILE*"); + + auto ret = extract(secret_key_file, paper_key_fp, BASE16); + paper_key_t_file.flush(); + paper_key_t_file.reset(); + + CB(event, GFGetModuleID(), + { + {"ret", QString::number(ret)}, + {"paper_key", QString::fromLatin1(paper_key_t_file.readAll())}, + }); + return ret; + } + + if (event["event_id"] == "REQUEST_TRANS_PAPER_KEY_2_KEY") { + if (event["public_key"].isEmpty() || event["paper_key_secrets"].isEmpty()) CB_ERR(event, -1, "public key or paper key secrets is empty"); - } QByteArray public_key_data = - QByteArray::fromBase64(event["public_key"].toUtf8()); + QByteArray::fromBase64(event["public_key"].toLatin1()); QTemporaryFile public_key_t_file; - if (!public_key_t_file.open()) { + if (!public_key_t_file.open()) CB_ERR(event, -1, "unable to open temporary file"); - } public_key_t_file.write(public_key_data); public_key_t_file.flush(); public_key_t_file.seek(0); FILE *pubring = fdopen(public_key_t_file.handle(), "rb"); - if (pubring == nullptr) { + if (pubring == nullptr) CB_ERR(event, -1, "unable to convert QTemporaryFile to FILE*"); - } QByteArray secrets_data = - QByteArray::fromBase64(event["paper_key_secrets"].toUtf8()); + QByteArray::fromBase64(event["paper_key_secrets"].toLatin1()); - QTemporaryFile secrets_data_file; - if (!secrets_data_file.open()) { + QTemporaryFile secrets_data_t_file; + if (!secrets_data_t_file.open()) CB_ERR(event, -1, "unable to open temporary file"); - } - secrets_data_file.write(public_key_data); - secrets_data_file.flush(); - secrets_data_file.seek(0); + secrets_data_t_file.write(secrets_data); + secrets_data_t_file.flush(); + secrets_data_t_file.reset(); - FILE *secrets = fdopen(secrets_data_file.handle(), "rb"); - if (secrets == nullptr) { + FILE *secrets_fp = fdopen(secrets_data_t_file.handle(), "r"); + if (secrets_fp == nullptr) CB_ERR(event, -1, "unable to convert QTemporaryFile to FILE*"); - } - restore(pubring, secrets, AUTO, ) + QTemporaryFile secret_key_t_file; + if (!secret_key_t_file.open()) + CB_ERR(event, -1, "unable to open temporary file"); + + FILE *secret_key_fp = fdopen(dup(secret_key_t_file.handle()), "wb"); + if (secret_key_fp == nullptr) + CB_ERR(event, -1, "unable to convert QTemporaryFile to FILE*"); + + auto ret = restore(pubring, secrets_fp, AUTO, secret_key_fp); + secret_key_t_file.reset(); + FLOG_DEBUG("secret key temp file size: %1, ret: %2", + secret_key_t_file.size(), ret); + + CB(event, GFGetModuleID(), + { + {"ret", QString::number(ret)}, + {"secret_key", + QString::fromLocal8Bit(secret_key_t_file.readAll().toBase64())}, + }); + + return ret; } CB_SUCC(event); diff --git a/src/m_paper_key/extract.cpp b/src/m_paper_key/extract.cpp index 388a6c7..1f0994a 100644 --- a/src/m_paper_key/extract.cpp +++ b/src/m_paper_key/extract.cpp @@ -26,7 +26,7 @@ extern int verbose; -int extract(FILE *input, const char *outname, enum data_type output_type) { +int extract(FILE *input, FILE *output, enum data_type output_type) { struct packet *packet; int offset; unsigned char fingerprint[20]; @@ -51,7 +51,7 @@ int extract(FILE *input, const char *outname, enum data_type output_type) { fprintf(stderr, "\n"); } - output_start(outname, output_type, fingerprint); + output_start(output, output_type, fingerprint); output_bytes(&version, 1); output_bytes(packet->buf, 1); output_bytes(fingerprint, 20); @@ -83,6 +83,7 @@ int extract(FILE *input, const char *outname, enum data_type output_type) { } output_finish(); + output_end(); if (input == stdin) { /* Consume everything else on input */ diff --git a/src/m_paper_key/extract.h b/src/m_paper_key/extract.h index 51cf603..f0a528d 100644 --- a/src/m_paper_key/extract.h +++ b/src/m_paper_key/extract.h @@ -22,5 +22,4 @@ #include "output.h" -auto extract(FILE *input, const char *outname, - enum data_type output_type) -> int; +auto extract(FILE *input, FILE *output, enum data_type output_type) -> int; diff --git a/src/m_paper_key/output.cpp b/src/m_paper_key/output.cpp index 8c6291b..0888402 100644 --- a/src/m_paper_key/output.cpp +++ b/src/m_paper_key/output.cpp @@ -147,6 +147,42 @@ void output_file_format(FILE *stream, const char *prefix) { fprintf(stream, "%smay simply be copied from the public key.\n", prefix); } +int output_start(FILE *fp, enum data_type type, unsigned char fingerprint[20]) { + output = fp; + if (!output) return -1; + + output_type = type; + + switch (type) { + case RAW: + break; + + case AUTO: + case BASE16: { + time_t now = time(NULL); + + line_items = (output_width - 5 - 6) / 3; + fprintf(output, "# Secret portions of key "); + print_bytes(output, fingerprint, 20); + fprintf(output, "\n"); + fprintf(output, "# Base16 data extracted %.24s\n", ctime(&now)); + fprintf(output, + "# Created with " + "Paper Key Module of GpgFrontend" + " by Saturneric\n#\n"); + output_file_format(output, "# "); + fprintf(output, + "#\n# Each base16 line ends with a CRC-24 of that line.\n"); + fprintf(output, + "# The entire block of data ends with a CRC-24 of the entire " + "block of data.\n\n"); + // if (comment != nullptr) fprintf(output, "# %s\n\n", comment); + } break; + } + + return 0; +} + int output_start(const char *name, enum data_type type, unsigned char fingerprint[20]) { if (name) { @@ -286,9 +322,13 @@ ssize_t output_openpgp_header(unsigned char tag, size_t length) { return output_bytes(encoded, bytes); } -void output_finish(void) { - output_bytes(nullptr, 0); - if (output != nullptr && output != stdout) fclose(output); +void output_finish(void) { output_bytes(nullptr, 0); } + +void output_end() { + if (output != nullptr) { + fflush(output); + fclose(output); + } } void set_binary_mode(FILE *stream) { diff --git a/src/m_paper_key/output.h b/src/m_paper_key/output.h index 21f36d3..a8bc38a 100644 --- a/src/m_paper_key/output.h +++ b/src/m_paper_key/output.h @@ -29,9 +29,11 @@ void print_bytes(FILE *stream, const unsigned char *buf, size_t length); void output_file_format(FILE *stream, const char *prefix); int output_start(const char *name, enum data_type type, unsigned char fingerprint[20]); +int output_start(FILE *fp, enum data_type type, unsigned char fingerprint[20]); ssize_t output_bytes(const unsigned char *buf, size_t length); #define output_packet(_packet) output_bytes((_packet)->buf, (_packet)->len) ssize_t output_length16(size_t length); ssize_t output_openpgp_header(unsigned char tag, size_t length); void output_finish(void); void set_binary_mode(FILE *stream); +void output_end(); diff --git a/src/m_paper_key/restore.cpp b/src/m_paper_key/restore.cpp index e1c8146..d2991c9 100644 --- a/src/m_paper_key/restore.cpp +++ b/src/m_paper_key/restore.cpp @@ -98,7 +98,7 @@ static void free_keys(struct key *key) { } auto restore(FILE *pubring, FILE *secrets, enum data_type input_type, - const char *outname) -> int { + FILE *output) -> int { struct packet *secret; if (input_type == AUTO) { @@ -128,7 +128,7 @@ auto restore(FILE *pubring, FILE *secrets, enum data_type input_type, keys = extract_keys(secret); if (keys) { - output_start(outname, RAW, NULL); + output_start(output, RAW, NULL); while ((pubkey = parse(pubring, 0, 0))) { unsigned char ptag; @@ -168,6 +168,7 @@ auto restore(FILE *pubring, FILE *secrets, enum data_type input_type, } free_keys(keys); + output_end(); } else { fprintf(stderr, "Unable to parse secret data\n"); return 1; diff --git a/src/m_paper_key/restore.h b/src/m_paper_key/restore.h index 7b908ef..fb65600 100644 --- a/src/m_paper_key/restore.h +++ b/src/m_paper_key/restore.h @@ -22,6 +22,6 @@ #include "output.h" auto restore(FILE *pubring, FILE *secrets, enum data_type input_type, - const char *outname) -> int; + FILE *output) -> int; #endif /* !_RESTORE_H_ */