"Fossies" - the Fresh Open Source Software Archive

Member "gpgme-1.15.1/lang/cpp/src/gpggencardkeyinteractor.cpp" (6 May 2019, 13107 Bytes) of package /linux/privat/gpgme-1.15.1.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "gpggencardkeyinteractor.cpp" see the Fossies "Dox" file reference documentation.

    1 /*
    2   gpggencardkeyinteractor.cpp - Edit Interactor to generate a key on a card
    3   Copyright (C) 2017 by Bundesamt für Sicherheit in der Informationstechnik
    4   Software engineering by Intevation GmbH
    5 
    6   This file is part of GPGME++.
    7 
    8   GPGME++ is free software; you can redistribute it and/or
    9   modify it under the terms of the GNU Library General Public
   10   License as published by the Free Software Foundation; either
   11   version 2 of the License, or (at your option) any later version.
   12 
   13   GPGME++ is distributed in the hope that it will be useful,
   14   but WITHOUT ANY WARRANTY; without even the implied warranty of
   15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16   GNU Library General Public License for more details.
   17 
   18   You should have received a copy of the GNU Library General Public License
   19   along with GPGME++; see the file COPYING.LIB.  If not, write to the
   20   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   21   Boston, MA 02110-1301, USA.
   22 */
   23 
   24 #ifdef HAVE_CONFIG_H
   25  #include "config.h"
   26 #endif
   27 
   28 #include "gpggencardkeyinteractor.h"
   29 
   30 #include "error.h"
   31 
   32 #include <gpgme.h>
   33 
   34 using namespace GpgME;
   35 
   36 class GpgGenCardKeyInteractor::Private
   37 {
   38 public:
   39     Private() : keysize("2048"), backup(false), algo(RSA)
   40     {
   41 
   42     }
   43     std::string name, email, backupFileName, expiry, serial, keysize;
   44     bool backup;
   45     Algo algo;
   46 };
   47 
   48 GpgGenCardKeyInteractor::~GpgGenCardKeyInteractor() {}
   49 
   50 GpgGenCardKeyInteractor::GpgGenCardKeyInteractor(const std::string &serial):
   51     d(new Private)
   52 {
   53     d->serial = serial;
   54 }
   55 
   56 void GpgGenCardKeyInteractor::setNameUtf8(const std::string &name)
   57 {
   58     d->name = name;
   59 }
   60 
   61 void GpgGenCardKeyInteractor::setEmailUtf8(const std::string &email)
   62 {
   63     d->email = email;
   64 }
   65 
   66 void GpgGenCardKeyInteractor::setDoBackup(bool value)
   67 {
   68     d->backup = value;
   69 }
   70 
   71 void GpgGenCardKeyInteractor::setKeySize(int value)
   72 {
   73     d->keysize = std::to_string(value);
   74 }
   75 
   76 void GpgGenCardKeyInteractor::setExpiry(const std::string &timeStr)
   77 {
   78     d->expiry = timeStr;
   79 }
   80 
   81 std::string GpgGenCardKeyInteractor::backupFileName() const
   82 {
   83     return d->backupFileName;
   84 }
   85 
   86 void GpgGenCardKeyInteractor::setAlgo(Algo algo)
   87 {
   88     d->algo = algo;
   89 }
   90 
   91 namespace GpgGenCardKeyInteractor_Private
   92 {
   93 enum {
   94     START = EditInteractor::StartState,
   95     DO_ADMIN,
   96     EXPIRE,
   97 
   98     GOT_SERIAL,
   99     COMMAND,
  100     NAME,
  101     EMAIL,
  102     COMMENT,
  103     BACKUP,
  104     REPLACE,
  105     SIZE,
  106     SIZE2,
  107     SIZE3,
  108     BACKUP_KEY_CREATED,
  109     KEY_CREATED,
  110     QUIT,
  111     SAVE,
  112 
  113     KEY_ATTR,
  114     KEY_ALGO1,
  115     KEY_ALGO2,
  116     KEY_ALGO3,
  117     KEY_CURVE1,
  118     KEY_CURVE2,
  119     KEY_CURVE3,
  120 
  121     ERROR = EditInteractor::ErrorState
  122 };
  123 }
  124 
  125 const char *GpgGenCardKeyInteractor::action(Error &err) const
  126 {
  127 
  128     using namespace GpgGenCardKeyInteractor_Private;
  129 
  130     switch (state()) {
  131     case DO_ADMIN:
  132         return "admin";
  133     case COMMAND:
  134         return "generate";
  135     case KEY_ATTR:
  136         return "key-attr";
  137     case KEY_ALGO1:
  138     case KEY_ALGO2:
  139     case KEY_ALGO3:
  140         return d->algo == RSA ? "1" : "2";
  141     case KEY_CURVE1:
  142     case KEY_CURVE2:
  143     case KEY_CURVE3:
  144         return "1"; // Only cv25519 supported.
  145     case NAME:
  146         return d->name.c_str();
  147     case EMAIL:
  148         return d->email.c_str();
  149     case EXPIRE:
  150         return d->expiry.c_str();
  151     case BACKUP:
  152         return d->backup ? "Y" : "N";
  153     case REPLACE:
  154         return "Y";
  155     case SIZE:
  156     case SIZE2:
  157     case SIZE3:
  158         return d->keysize.c_str();
  159     case COMMENT:
  160         return "";
  161     case SAVE:
  162         return "Y";
  163     case QUIT:
  164         return "quit";
  165     case KEY_CREATED:
  166     case START:
  167     case GOT_SERIAL:
  168     case BACKUP_KEY_CREATED:
  169     case ERROR:
  170         return nullptr;
  171     default:
  172         err = Error::fromCode(GPG_ERR_GENERAL);
  173         return nullptr;
  174     }
  175 }
  176 
  177 unsigned int GpgGenCardKeyInteractor::nextState(unsigned int status, const char *args, Error &err) const
  178 {
  179 
  180     static const Error GENERAL_ERROR     = Error::fromCode(GPG_ERR_GENERAL);
  181     static const Error INV_NAME_ERROR    = Error::fromCode(GPG_ERR_INV_NAME);
  182     static const Error INV_EMAIL_ERROR   = Error::fromCode(GPG_ERR_INV_USER_ID);
  183     static const Error INV_COMMENT_ERROR = Error::fromCode(GPG_ERR_INV_USER_ID);
  184 
  185     if (needsNoResponse(status)) {
  186         return state();
  187     }
  188 
  189     using namespace GpgGenCardKeyInteractor_Private;
  190 
  191     switch (state()) {
  192     case START:
  193         if (status == GPGME_STATUS_CARDCTRL &&
  194                 !d->serial.empty()) {
  195             const std::string sArgs = args;
  196             if (sArgs.find(d->serial) == std::string::npos) {
  197                 // Wrong smartcard
  198                 err = Error::fromCode(GPG_ERR_WRONG_CARD);
  199                 return ERROR;
  200             } else {
  201                 printf("EditInteractor: Confirmed S/N: %s %s\n",
  202                            d->serial.c_str(), sArgs.c_str());
  203             }
  204             return GOT_SERIAL;
  205         } else if (d->serial.empty()) {
  206             return GOT_SERIAL;
  207         }
  208         err = GENERAL_ERROR;
  209         return ERROR;
  210     case GOT_SERIAL:
  211         if (status == GPGME_STATUS_GET_LINE &&
  212                 strcmp(args, "cardedit.prompt") == 0) {
  213             return DO_ADMIN;
  214         }
  215         err = GENERAL_ERROR;
  216         return ERROR;
  217     case DO_ADMIN:
  218         if (status == GPGME_STATUS_GET_LINE &&
  219                 strcmp(args, "cardedit.prompt") == 0) {
  220             return KEY_ATTR;
  221         }
  222         err = GENERAL_ERROR;
  223         return ERROR;
  224     // Handling for key-attr subcommand
  225     case KEY_ATTR:
  226         if (status == GPGME_STATUS_GET_LINE &&
  227                 strcmp(args, "cardedit.prompt") == 0) {
  228             // Happens if key attr is not yet supported.
  229             return COMMAND;
  230         }
  231         if (status == GPGME_STATUS_GET_LINE &&
  232                 strcmp(args, "cardedit.genkeys.algo") == 0) {
  233             return KEY_ALGO1;
  234         }
  235         err = GENERAL_ERROR;
  236         return ERROR;
  237     case KEY_ALGO1:
  238         if (status == GPGME_STATUS_GET_LINE &&
  239                 strcmp(args, "cardedit.genkeys.size") == 0) {
  240             return SIZE;
  241         }
  242         if (status == GPGME_STATUS_GET_LINE &&
  243                 strcmp(args, "keygen.curve") == 0) {
  244             return KEY_CURVE1;
  245         }
  246         err = GENERAL_ERROR;
  247         return ERROR;
  248     case KEY_ALGO2:
  249         if (status == GPGME_STATUS_GET_LINE &&
  250                 strcmp(args, "cardedit.genkeys.size") == 0) {
  251             return SIZE2;
  252         }
  253         if (status == GPGME_STATUS_GET_LINE &&
  254                 strcmp(args, "keygen.curve") == 0) {
  255             return KEY_CURVE2;
  256         }
  257         err = GENERAL_ERROR;
  258         return ERROR;
  259     case KEY_ALGO3:
  260         if (status == GPGME_STATUS_GET_LINE &&
  261                 strcmp(args, "cardedit.genkeys.size") == 0) {
  262             return SIZE3;
  263         }
  264         if (status == GPGME_STATUS_GET_LINE &&
  265                 strcmp(args, "keygen.curve") == 0) {
  266             return KEY_CURVE3;
  267         }
  268         err = GENERAL_ERROR;
  269         return ERROR;
  270     case KEY_CURVE1:
  271         if (status == GPGME_STATUS_GET_LINE &&
  272                 strcmp(args, "cardedit.genkeys.algo") == 0) {
  273             return KEY_ALGO2;
  274         }
  275         if (status == GPGME_STATUS_GET_LINE &&
  276                 strcmp(args, "cardedit.prompt") == 0) {
  277             return COMMAND;
  278         }
  279         err = GENERAL_ERROR;
  280         return ERROR;
  281     case KEY_CURVE2:
  282         if (status == GPGME_STATUS_GET_LINE &&
  283                 strcmp(args, "cardedit.genkeys.algo") == 0) {
  284             return KEY_ALGO3;
  285         }
  286         if (status == GPGME_STATUS_GET_LINE &&
  287                 strcmp(args, "cardedit.prompt") == 0) {
  288             return COMMAND;
  289         }
  290         err = GENERAL_ERROR;
  291         return ERROR;
  292     case KEY_CURVE3:
  293         if (status == GPGME_STATUS_GET_LINE &&
  294                 strcmp(args, "cardedit.genkeys.algo") == 0) {
  295             return KEY_ALGO3;
  296         }
  297         if (status == GPGME_STATUS_GET_LINE &&
  298                 strcmp(args, "cardedit.prompt") == 0) {
  299             return COMMAND;
  300         }
  301         err = GENERAL_ERROR;
  302         return ERROR;
  303     // End key-attr handling
  304     case COMMAND:
  305         if (status == GPGME_STATUS_GET_LINE &&
  306                 strcmp(args, "cardedit.genkeys.backup_enc") == 0) {
  307             return BACKUP;
  308         }
  309         err = GENERAL_ERROR;
  310         return ERROR;
  311     case BACKUP:
  312         if (status == GPGME_STATUS_GET_BOOL &&
  313                 strcmp(args, "cardedit.genkeys.replace_keys") == 0) {
  314             return REPLACE;
  315         }
  316         if (status == GPGME_STATUS_GET_LINE &&
  317                 strcmp(args, "cardedit.genkeys.size") == 0) {
  318             return SIZE;
  319         }
  320         if (status == GPGME_STATUS_GET_LINE &&
  321                 strcmp(args, "keygen.valid") == 0) {
  322             return EXPIRE;
  323         }
  324         err = GENERAL_ERROR;
  325         return ERROR;
  326     case REPLACE:
  327         if (status == GPGME_STATUS_GET_LINE &&
  328                 strcmp(args, "cardedit.genkeys.size") == 0) {
  329             return SIZE;
  330         }
  331         if (status == GPGME_STATUS_GET_LINE &&
  332                 strcmp(args, "keygen.valid") == 0) {
  333             return EXPIRE;
  334         }
  335         err = GENERAL_ERROR;
  336         return ERROR;
  337     case SIZE:
  338         if (status == GPGME_STATUS_GET_LINE &&
  339                 strcmp(args, "cardedit.genkeys.size") == 0) {
  340             return SIZE2;
  341         }
  342         if (status == GPGME_STATUS_GET_LINE &&
  343                 strcmp(args, "keygen.valid") == 0) {
  344             return EXPIRE;
  345         }
  346         if (status == GPGME_STATUS_GET_LINE &&
  347                 strcmp(args, "cardedit.genkeys.algo") == 0) {
  348             return KEY_ALGO2;
  349         }
  350         if (status == GPGME_STATUS_GET_LINE &&
  351                 strcmp(args, "cardedit.prompt") == 0) {
  352             return COMMAND;
  353         }
  354         err = GENERAL_ERROR;
  355         return ERROR;
  356     case SIZE2:
  357         if (status == GPGME_STATUS_GET_LINE &&
  358                 strcmp(args, "cardedit.genkeys.size") == 0) {
  359             return SIZE3;
  360         }
  361         if (status == GPGME_STATUS_GET_LINE &&
  362                 strcmp(args, "keygen.valid") == 0) {
  363             return EXPIRE;
  364         }
  365         if (status == GPGME_STATUS_GET_LINE &&
  366                 strcmp(args, "cardedit.genkeys.algo") == 0) {
  367             return KEY_ALGO3;
  368         }
  369         if (status == GPGME_STATUS_GET_LINE &&
  370                 strcmp(args, "cardedit.prompt") == 0) {
  371             return COMMAND;
  372         }
  373         err = GENERAL_ERROR;
  374         return ERROR;
  375     case SIZE3:
  376         if (status == GPGME_STATUS_GET_LINE &&
  377                 strcmp(args, "keygen.valid") == 0) {
  378             return EXPIRE;
  379         }
  380         if (status == GPGME_STATUS_GET_LINE &&
  381                 strcmp(args, "cardedit.prompt") == 0) {
  382             return COMMAND;
  383         }
  384         err = GENERAL_ERROR;
  385         return ERROR;
  386     case EXPIRE:
  387         if (status == GPGME_STATUS_GET_LINE &&
  388                 strcmp(args, "keygen.name") == 0) {
  389             return NAME;
  390         }
  391         err = GENERAL_ERROR;
  392         return ERROR;
  393     case NAME:
  394         if (status == GPGME_STATUS_GET_LINE &&
  395                 strcmp(args, "keygen.email") == 0) {
  396             return EMAIL;
  397         }
  398         err = GENERAL_ERROR;
  399         if (status == GPGME_STATUS_GET_LINE &&
  400                 strcmp(args, "keygen.name") == 0) {
  401             err = INV_NAME_ERROR;
  402         }
  403         return ERROR;
  404     case EMAIL:
  405         if (status == GPGME_STATUS_GET_LINE &&
  406                 strcmp(args, "keygen.comment") == 0) {
  407             return COMMENT;
  408         }
  409         err = GENERAL_ERROR;
  410         if (status == GPGME_STATUS_GET_LINE &&
  411                 strcmp(args, "keygen.email") == 0) {
  412             err = INV_EMAIL_ERROR;
  413         }
  414         return ERROR;
  415     case COMMENT:
  416         if (status == GPGME_STATUS_BACKUP_KEY_CREATED) {
  417             std::string sArgs = args;
  418             const auto pos = sArgs.rfind(" ");
  419             if (pos != std::string::npos) {
  420                 d->backupFileName = sArgs.substr(pos + 1);
  421                 return BACKUP_KEY_CREATED;
  422             }
  423         }
  424         if (status == GPGME_STATUS_KEY_CREATED) {
  425             return KEY_CREATED;
  426         }
  427         if (status == GPGME_STATUS_GET_LINE &&
  428                 strcmp(args, "keyedit.prompt") == 0) {
  429             return QUIT;
  430         }
  431         err = GENERAL_ERROR;
  432         if (status == GPGME_STATUS_GET_LINE &&
  433                 strcmp(args, "keygen.comment") == 0) {
  434             err = INV_COMMENT_ERROR;
  435         }
  436         return ERROR;
  437     case BACKUP_KEY_CREATED:
  438         if (status == GPGME_STATUS_KEY_CREATED) {
  439             return KEY_CREATED;
  440         }
  441         err = GENERAL_ERROR;
  442         return ERROR;
  443     case KEY_CREATED:
  444         return QUIT;
  445     case QUIT:
  446         if (status == GPGME_STATUS_GET_LINE &&
  447                 strcmp(args, "cardedit.prompt") == 0) {
  448             return QUIT;
  449         }
  450         err = GENERAL_ERROR;
  451         return ERROR;
  452     case ERROR:
  453         if (status == GPGME_STATUS_GET_LINE &&
  454                 strcmp(args, "keyedit.prompt") == 0) {
  455             return QUIT;
  456         }
  457         err = lastError();
  458         return ERROR;
  459     default:
  460         err = GENERAL_ERROR;
  461         return ERROR;
  462     }
  463 }