From ffdb75217bc09561cf651dab15cd26e0024d89a7 Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Tue, 26 Mar 2019 12:02:28 +0100 Subject: [PATCH] cpp: Fix GenCardKeyInteractor and extend it * NEWS: Mention interface change. * lang/cpp/src/gpggencardkeyinteractor.cpp (GpgGenCardKeyInteractor::setAlgo): New. (GpgGenCardKeyInteractor::action), (GpgGenCardKeyInteractor::nextState: Handle new interface. -- Tested that this workes with the old interface of GnuPG 2.2.5 and the new interface since GnuPG 2.2.6 GnuPG-Bug-Id: T4428 --- NEWS | 1 + lang/cpp/src/gpggencardkeyinteractor.cpp | 135 ++++++++++++++++++++++- lang/cpp/src/gpggencardkeyinteractor.h | 6 + 3 files changed, 140 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 9c11df34..c4961522 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ Noteworthy changes in version 1.12.1 (unreleased) cpp: Subkey::isBad NEW. cpp: UserID::isBad NEW. cpp: UserID::Signature::isBad NEW. + cpp: GenCardKeyInteractor::setAlgo NEW. Noteworthy changes in version 1.12.0 (2018-10-08) diff --git a/lang/cpp/src/gpggencardkeyinteractor.cpp b/lang/cpp/src/gpggencardkeyinteractor.cpp index 831e4c4a..b1098665 100644 --- a/lang/cpp/src/gpggencardkeyinteractor.cpp +++ b/lang/cpp/src/gpggencardkeyinteractor.cpp @@ -36,11 +36,12 @@ using namespace GpgME; class GpgGenCardKeyInteractor::Private { public: - Private() : keysize("2048"), backup(false) + Private() : keysize("2048"), backup(false), algo(RSA) { } std::string name, email, backupFileName, expiry, serial, keysize; + Algo algo; bool backup; }; @@ -82,6 +83,11 @@ std::string GpgGenCardKeyInteractor::backupFileName() const return d->backupFileName; } +void GpgGenCardKeyInteractor::setAlgo(Algo algo) +{ + d->algo = algo; +} + namespace GpgGenCardKeyInteractor_Private { enum { @@ -104,6 +110,14 @@ enum { QUIT, SAVE, + KEY_ATTR, + KEY_ALGO1, + KEY_ALGO2, + KEY_ALGO3, + KEY_CURVE1, + KEY_CURVE2, + KEY_CURVE3, + ERROR = EditInteractor::ErrorState }; } @@ -118,6 +132,16 @@ const char *GpgGenCardKeyInteractor::action(Error &err) const return "admin"; case COMMAND: return "generate"; + case KEY_ATTR: + return "key-attr"; + case KEY_ALGO1: + case KEY_ALGO2: + case KEY_ALGO3: + return d->algo == RSA ? "1" : "2"; + case KEY_CURVE1: + case KEY_CURVE2: + case KEY_CURVE3: + return "1"; // Only cv25519 supported. case NAME: return d->name.c_str(); case EMAIL: @@ -191,12 +215,92 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char err = GENERAL_ERROR; return ERROR; case DO_ADMIN: + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.prompt") == 0) { + return KEY_ATTR; + } + err = GENERAL_ERROR; + return ERROR; + // Handling for key-attr subcommand + case KEY_ATTR: + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.prompt") == 0) { + // Happens if key attr is not yet supported. + return COMMAND; + } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.genkeys.algo") == 0) { + return KEY_ALGO1; + } + err = GENERAL_ERROR; + return ERROR; + case KEY_ALGO1: + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.genkeys.size") == 0) { + return SIZE; + } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "keygen.curve") == 0) { + return KEY_CURVE1; + } + err = GENERAL_ERROR; + return ERROR; + case KEY_ALGO2: + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.genkeys.size") == 0) { + return SIZE2; + } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "keygen.curve") == 0) { + return KEY_CURVE2; + } + err = GENERAL_ERROR; + return ERROR; + case KEY_ALGO3: + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.genkeys.size") == 0) { + return SIZE3; + } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "keygen.curve") == 0) { + return KEY_CURVE3; + } + err = GENERAL_ERROR; + return ERROR; + case KEY_CURVE1: + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.genkeys.algo") == 0) { + return KEY_ALGO2; + } if (status == GPGME_STATUS_GET_LINE && strcmp(args, "cardedit.prompt") == 0) { return COMMAND; } err = GENERAL_ERROR; return ERROR; + case KEY_CURVE2: + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.genkeys.algo") == 0) { + return KEY_ALGO3; + } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.prompt") == 0) { + return COMMAND; + } + err = GENERAL_ERROR; + return ERROR; + case KEY_CURVE3: + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.genkeys.algo") == 0) { + return KEY_ALGO3; + } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.prompt") == 0) { + return COMMAND; + } + err = GENERAL_ERROR; + return ERROR; + // End key-attr handling case COMMAND: if (status == GPGME_STATUS_GET_LINE && strcmp(args, "cardedit.genkeys.backup_enc") == 0) { @@ -213,14 +317,21 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char strcmp(args, "cardedit.genkeys.size") == 0) { return SIZE; } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "keygen.valid") == 0) { + return EXPIRE; + } err = GENERAL_ERROR; return ERROR; case REPLACE: if (status == GPGME_STATUS_GET_LINE && strcmp(args, "cardedit.genkeys.size") == 0) { - printf("Moving to SIZE\n"); return SIZE; } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "keygen.valid") == 0) { + return EXPIRE; + } err = GENERAL_ERROR; return ERROR; case SIZE: @@ -232,6 +343,14 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char strcmp(args, "keygen.valid") == 0) { return EXPIRE; } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.genkeys.algo") == 0) { + return KEY_ALGO2; + } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.prompt") == 0) { + return COMMAND; + } err = GENERAL_ERROR; return ERROR; case SIZE2: @@ -243,6 +362,14 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char strcmp(args, "keygen.valid") == 0) { return EXPIRE; } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.genkeys.algo") == 0) { + return KEY_ALGO3; + } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.prompt") == 0) { + return COMMAND; + } err = GENERAL_ERROR; return ERROR; case SIZE3: @@ -250,6 +377,10 @@ unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char strcmp(args, "keygen.valid") == 0) { return EXPIRE; } + if (status == GPGME_STATUS_GET_LINE && + strcmp(args, "cardedit.prompt") == 0) { + return COMMAND; + } err = GENERAL_ERROR; return ERROR; case EXPIRE: diff --git a/lang/cpp/src/gpggencardkeyinteractor.h b/lang/cpp/src/gpggencardkeyinteractor.h index d6a7b7b0..3d9c7136 100644 --- a/lang/cpp/src/gpggencardkeyinteractor.h +++ b/lang/cpp/src/gpggencardkeyinteractor.h @@ -56,6 +56,12 @@ public: void setDoBackup(bool value); void setExpiry(const std::string &timeString); + enum Algo { + RSA = 1, + ECC = 2 + }; + void setAlgo(Algo algo); + std::string backupFileName() const; private: