gpg and internal API changes for ENGINE-172 implemented and tested (no-sign); no-key not in yet ENGINE-172
authorKrista Grothoff <krista@pep-project.org>
Fri, 10 Mar 2017 15:23:31 +0100
branchENGINE-172
changeset 1639be84d676f3ef
parent 1638 6474eeaee8e0
child 1640 52e90165ad0f
gpg and internal API changes for ENGINE-172 implemented and tested (no-sign); no-key not in yet
src/cryptotech.c
src/cryptotech.h
src/keymanagement.c
src/message_api.c
src/message_api.h
src/pEpEngine.c
src/pEp_internal.h
src/pgp_gpg.c
src/pgp_gpg.h
src/pgp_gpg_internal.h
test/encrypt_for_identity_test.cc
     1.1 --- a/src/cryptotech.c	Fri Mar 10 14:17:43 2017 +0100
     1.2 +++ b/src/cryptotech.c	Fri Mar 10 15:23:31 2017 +0100
     1.3 @@ -36,6 +36,7 @@
     1.4          cryptotech[PEP_crypt_OpenPGP].confirmed_comm_type = PEP_ct_OpenPGP;
     1.5          cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify = pgp_decrypt_and_verify;
     1.6          cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign = pgp_encrypt_and_sign;
     1.7 +        cryptotech[PEP_crypt_OpenPGP].encrypt_only = pgp_encrypt_only;
     1.8          cryptotech[PEP_crypt_OpenPGP].verify_text = pgp_verify_text;
     1.9          cryptotech[PEP_crypt_OpenPGP].delete_keypair = pgp_delete_keypair;
    1.10          cryptotech[PEP_crypt_OpenPGP].export_key = pgp_export_keydata;
     2.1 --- a/src/cryptotech.h	Fri Mar 10 14:17:43 2017 +0100
     2.2 +++ b/src/cryptotech.h	Fri Mar 10 15:23:31 2017 +0100
     2.3 @@ -32,6 +32,11 @@
     2.4          size_t psize, char **ctext, size_t *csize
     2.5      );
     2.6  
     2.7 +typedef PEP_STATUS (*encrypt_only_t)(
     2.8 +        PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
     2.9 +        size_t psize, char **ctext, size_t *csize
    2.10 +    );
    2.11 +
    2.12  typedef PEP_STATUS (*delete_keypair_t)(PEP_SESSION session, const char *fpr);
    2.13  
    2.14  typedef PEP_STATUS (*export_key_t)(
    2.15 @@ -92,6 +97,7 @@
    2.16      decrypt_and_verify_t decrypt_and_verify;
    2.17      verify_text_t verify_text;
    2.18      encrypt_and_sign_t encrypt_and_sign;
    2.19 +    encrypt_only_t encrypt_only;
    2.20      delete_keypair_t delete_keypair;
    2.21      export_key_t export_key;
    2.22      find_keys_t find_keys;
     3.1 --- a/src/keymanagement.c	Fri Mar 10 14:17:43 2017 +0100
     3.2 +++ b/src/keymanagement.c	Fri Mar 10 15:23:31 2017 +0100
     3.3 @@ -779,10 +779,10 @@
     3.4      assert(!EMPTYSTR(ident->address));
     3.5      assert(!EMPTYSTR(ident->user_id));
     3.6      assert(!EMPTYSTR(ident->fpr));
     3.7 -    assert(!ident->me);
     3.8 +//    assert(!ident->me);
     3.9  
    3.10      if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
    3.11 -            EMPTYSTR(ident->fpr) || ident->me)
    3.12 +            EMPTYSTR(ident->fpr)) // || ident->me)
    3.13          return PEP_ILLEGAL_VALUE;
    3.14  
    3.15      status = update_identity(session, ident);
     4.1 --- a/src/message_api.c	Fri Mar 10 14:17:43 2017 +0100
     4.2 +++ b/src/message_api.c	Fri Mar 10 15:23:31 2017 +0100
     4.3 @@ -340,7 +340,8 @@
     4.4      PEP_SESSION session,
     4.5      const message *src,
     4.6      stringlist_t *keys,
     4.7 -    message *dst
     4.8 +    message *dst,
     4.9 +    PEP_encrypt_flags_t flags
    4.10      )
    4.11  {
    4.12      PEP_STATUS status = PEP_STATUS_OK;
    4.13 @@ -396,8 +397,12 @@
    4.14      if (mimetext == NULL)
    4.15          goto pep_error;
    4.16  
    4.17 -    status = encrypt_and_sign(session, keys, mimetext, strlen(mimetext),
    4.18 -        &ctext, &csize);
    4.19 +    if (flags & PEP_encrypt_flag_force_unsigned)
    4.20 +        status = encrypt_only(session, keys, mimetext, strlen(mimetext),
    4.21 +            &ctext, &csize);
    4.22 +    else
    4.23 +        status = encrypt_and_sign(session, keys, mimetext, strlen(mimetext),
    4.24 +            &ctext, &csize);
    4.25      free(mimetext);
    4.26      if (ctext == NULL)
    4.27          goto pep_error;
    4.28 @@ -439,7 +444,8 @@
    4.29      PEP_SESSION session,
    4.30      const message *src,
    4.31      stringlist_t *keys,
    4.32 -    message *dst
    4.33 +    message *dst,
    4.34 +    PEP_encrypt_flags_t flags
    4.35      )
    4.36  {
    4.37      PEP_STATUS status = PEP_STATUS_OK;
    4.38 @@ -453,6 +459,8 @@
    4.39  
    4.40      dst->enc_format = PEP_enc_pieces;
    4.41  
    4.42 +    bool nosign = (flags & PEP_encrypt_flag_force_unsigned);
    4.43 +
    4.44      if (src->shortmsg && src->shortmsg[0] && strcmp(src->shortmsg, "pEp") != 0) {
    4.45          if (session->unencrypted_subject) {
    4.46              dst->shortmsg = strdup(src->shortmsg);
    4.47 @@ -468,8 +476,12 @@
    4.48              free_ptext = true;
    4.49          }
    4.50  
    4.51 -        status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
    4.52 -            &csize);
    4.53 +        if (nosign)
    4.54 +            status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
    4.55 +                &csize);
    4.56 +        else 
    4.57 +            status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
    4.58 +                &csize);
    4.59          if (free_ptext)
    4.60              free(ptext);
    4.61          free_ptext = false;
    4.62 @@ -482,8 +494,12 @@
    4.63      }
    4.64      else if (src->longmsg && src->longmsg[0]) {
    4.65          ptext = src->longmsg;
    4.66 -        status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
    4.67 -            &csize);
    4.68 +        if (nosign)
    4.69 +            status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
    4.70 +                &csize);
    4.71 +        else 
    4.72 +            status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
    4.73 +                &csize);
    4.74          if (ctext) {
    4.75              dst->longmsg = ctext;
    4.76          }
    4.77 @@ -500,8 +516,12 @@
    4.78  
    4.79      if (src->longmsg_formatted && src->longmsg_formatted[0]) {
    4.80          ptext = src->longmsg_formatted;
    4.81 -        status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
    4.82 -            &csize);
    4.83 +        if (nosign)
    4.84 +            status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
    4.85 +                &csize);
    4.86 +        else 
    4.87 +            status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
    4.88 +                &csize);
    4.89          if (ctext) {
    4.90  
    4.91              bloblist_t *_a = bloblist_add(dst->attachments, ctext, csize,
    4.92 @@ -535,8 +555,12 @@
    4.93              else {
    4.94                  size_t psize = _s->size;
    4.95                  ptext = _s->value;
    4.96 -                status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
    4.97 -                    &csize);
    4.98 +                if (nosign)
    4.99 +                    status = encrypt_only(session, keys, ptext, psize, &ctext,
   4.100 +                        &csize);
   4.101 +                else 
   4.102 +                    status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
   4.103 +                        &csize);
   4.104                  if (ctext) {
   4.105                      char *filename = NULL;
   4.106  
   4.107 @@ -1187,11 +1211,11 @@
   4.108          switch (enc_format) {
   4.109          case PEP_enc_PGP_MIME:
   4.110          case PEP_enc_PEP: // BUG: should be implemented extra
   4.111 -            status = encrypt_PGP_MIME(session, src, keys, msg);
   4.112 +            status = encrypt_PGP_MIME(session, src, keys, msg, flags);
   4.113              break;
   4.114  
   4.115          case PEP_enc_pieces:
   4.116 -            status = encrypt_PGP_in_pieces(session, src, keys, msg);
   4.117 +            status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
   4.118              break;
   4.119  
   4.120          /* case PEP_enc_PEP:
   4.121 @@ -1298,11 +1322,11 @@
   4.122      switch (enc_format) {
   4.123          case PEP_enc_PGP_MIME:
   4.124          case PEP_enc_PEP: // BUG: should be implemented extra
   4.125 -            status = encrypt_PGP_MIME(session, src, keys, msg);
   4.126 +            status = encrypt_PGP_MIME(session, src, keys, msg, flags);
   4.127              break;
   4.128  
   4.129          case PEP_enc_pieces:
   4.130 -            status = encrypt_PGP_in_pieces(session, src, keys, msg);
   4.131 +            status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
   4.132              break;
   4.133  
   4.134          /* case PEP_enc_PEP:
     5.1 --- a/src/message_api.h	Fri Mar 10 14:17:43 2017 +0100
     5.2 +++ b/src/message_api.h	Fri Mar 10 15:23:31 2017 +0100
     5.3 @@ -23,6 +23,8 @@
     5.4  void add_opt_field(message *msg, const char *name, const char *value);
     5.5  
     5.6  typedef enum _PEP_encrypt_flags {
     5.7 +    // "default" means whatever the default behaviour for the function is.
     5.8 +    PEP_encrypt_flag_default = 0x0,
     5.9      PEP_encrypt_flag_force_encryption = 0x1,
    5.10  
    5.11      // This flag is for special use cases and should not be used
    5.12 @@ -383,4 +385,3 @@
    5.13  #ifdef __cplusplus
    5.14  }
    5.15  #endif
    5.16 -
     6.1 --- a/src/pEpEngine.c	Fri Mar 10 14:17:43 2017 +0100
     6.2 +++ b/src/pEpEngine.c	Fri Mar 10 15:23:31 2017 +0100
     6.3 @@ -1477,6 +1477,26 @@
     6.4              keylist, ptext, psize, ctext, csize);
     6.5  }
     6.6  
     6.7 +PEP_STATUS encrypt_only(
     6.8 +    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
     6.9 +    size_t psize, char **ctext, size_t *csize
    6.10 +    )
    6.11 +{
    6.12 +    assert(session);
    6.13 +    assert(keylist);
    6.14 +    assert(ptext);
    6.15 +    assert(psize);
    6.16 +    assert(ctext);
    6.17 +    assert(csize);
    6.18 +
    6.19 +    if (!(session && keylist && ptext && psize && ctext && csize))
    6.20 +        return PEP_ILLEGAL_VALUE;
    6.21 +
    6.22 +    return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
    6.23 +            keylist, ptext, psize, ctext, csize);
    6.24 +}
    6.25 +
    6.26 +
    6.27  DYNAMIC_API PEP_STATUS verify_text(
    6.28      PEP_SESSION session, const char *text, size_t size,
    6.29      const char *signature, size_t sig_size, stringlist_t **keylist
     7.1 --- a/src/pEp_internal.h	Fri Mar 10 14:17:43 2017 +0100
     7.2 +++ b/src/pEp_internal.h	Fri Mar 10 15:23:31 2017 +0100
     7.3 @@ -167,6 +167,12 @@
     7.4  PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first);
     7.5  void release_transport_system(PEP_SESSION session, bool out_last);
     7.6  
     7.7 +/* NOT to be exposed to the outside!!! */
     7.8 +PEP_STATUS encrypt_only(
     7.9 +        PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
    7.10 +        size_t psize, char **ctext, size_t *csize
    7.11 +);
    7.12 +
    7.13  #ifdef NDEBUG
    7.14  #define DEBUG_LOG(TITLE, ENTITY, DESC)
    7.15  #define  LOGD(...)
     8.1 --- a/src/pgp_gpg.c	Fri Mar 10 14:17:43 2017 +0100
     8.2 +++ b/src/pgp_gpg.c	Fri Mar 10 15:23:31 2017 +0100
     8.3 @@ -250,6 +250,11 @@
     8.4              "gpgme_op_encrypt_sign");
     8.5          assert(gpg.gpgme_op_encrypt_sign);
     8.6  
     8.7 +        gpg.gpgme_op_encrypt
     8.8 +            = (gpgme_op_encrypt_t) (intptr_t) dlsym(gpgme,
     8.9 +            "gpgme_op_encrypt");
    8.10 +        assert(gpg.gpgme_op_encrypt);
    8.11 +
    8.12          gpg.gpgme_op_verify_result
    8.13              = (gpgme_op_verify_result_t) (intptr_t) dlsym(gpgme,
    8.14              "gpgme_op_verify_result");
    8.15 @@ -873,11 +878,12 @@
    8.16      return result;
    8.17  }
    8.18  
    8.19 -PEP_STATUS pgp_encrypt_and_sign(
    8.20 +
    8.21 +static PEP_STATUS pgp_encrypt_sign_optional(    
    8.22      PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
    8.23 -    size_t psize, char **ctext, size_t *csize
    8.24 -    )
    8.25 -{
    8.26 +    size_t psize, char **ctext, size_t *csize, bool sign
    8.27 +)
    8.28 +{    
    8.29      PEP_STATUS result;
    8.30      gpgme_error_t gpgme_error;
    8.31      gpgme_data_t plain, cipher;
    8.32 @@ -943,7 +949,7 @@
    8.33              gpg.gpgme_data_release(cipher);
    8.34              return PEP_OUT_OF_MEMORY;
    8.35          case GPG_ERR_NO_ERROR:
    8.36 -            if (i == 0) {
    8.37 +            if (i == 0 && sign) {
    8.38                  gpgme_error_t _gpgme_error = gpg.gpgme_signers_add(session->ctx, rcpt[0]);
    8.39                  _gpgme_error = _GPGERR(_gpgme_error);
    8.40                  assert(_gpgme_error == GPG_ERR_NO_ERROR);
    8.41 @@ -976,9 +982,16 @@
    8.42  
    8.43      // TODO: remove that and replace with proper key management
    8.44      flags = GPGME_ENCRYPT_ALWAYS_TRUST;
    8.45 -
    8.46 -    gpgme_error = gpg.gpgme_op_encrypt_sign(session->ctx, rcpt, flags,
    8.47 -        plain, cipher);
    8.48 +    
    8.49 +    if (sign) {
    8.50 +        gpgme_error = gpg.gpgme_op_encrypt_sign(session->ctx, rcpt, flags,
    8.51 +            plain, cipher);
    8.52 +    }
    8.53 +    else {
    8.54 +        gpgme_error = gpg.gpgme_op_encrypt(session->ctx, rcpt, flags,
    8.55 +            plain, cipher);
    8.56 +    }
    8.57 +    
    8.58      gpgme_error = _GPGERR(gpgme_error);
    8.59      switch (gpgme_error) {
    8.60      case GPG_ERR_NO_ERROR:
    8.61 @@ -1024,6 +1037,24 @@
    8.62      return result;
    8.63  }
    8.64  
    8.65 +PEP_STATUS pgp_encrypt_only(
    8.66 +    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
    8.67 +    size_t psize, char **ctext, size_t *csize
    8.68 +    )
    8.69 +{
    8.70 +    return pgp_encrypt_sign_optional(session, keylist, ptext,
    8.71 +        psize, ctext, csize, false);
    8.72 +}
    8.73 +
    8.74 +PEP_STATUS pgp_encrypt_and_sign(
    8.75 +    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
    8.76 +    size_t psize, char **ctext, size_t *csize
    8.77 +    )
    8.78 +{
    8.79 +    return pgp_encrypt_sign_optional(session, keylist, ptext,
    8.80 +        psize, ctext, csize, true);
    8.81 +}
    8.82 +
    8.83  PEP_STATUS pgp_generate_keypair(
    8.84      PEP_SESSION session, pEp_identity *identity
    8.85      )
     9.1 --- a/src/pgp_gpg.h	Fri Mar 10 14:17:43 2017 +0100
     9.2 +++ b/src/pgp_gpg.h	Fri Mar 10 15:23:31 2017 +0100
     9.3 @@ -19,6 +19,12 @@
     9.4          size_t psize, char **ctext, size_t *csize
     9.5      );
     9.6  
     9.7 +PEP_STATUS pgp_encrypt_only(
     9.8 +        PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
     9.9 +        size_t psize, char **ctext, size_t *csize
    9.10 +    );
    9.11 +
    9.12 +
    9.13  PEP_STATUS pgp_verify_text(
    9.14          PEP_SESSION session, const char *text, size_t size,
    9.15          const char *signature, size_t sig_size, stringlist_t **keylist
    9.16 @@ -100,4 +106,3 @@
    9.17  
    9.18  PEP_STATUS pgp_binary(const char **path);
    9.19  #define PGP_BINARY_PATH pgp_binary
    9.20 -
    10.1 --- a/src/pgp_gpg_internal.h	Fri Mar 10 14:17:43 2017 +0100
    10.2 +++ b/src/pgp_gpg_internal.h	Fri Mar 10 15:23:31 2017 +0100
    10.3 @@ -43,6 +43,9 @@
    10.4  typedef gpgme_error_t(*gpgme_op_encrypt_sign_t)(gpgme_ctx_t CTX,
    10.5      gpgme_key_t RECP[], gpgme_encrypt_flags_t FLAGS, gpgme_data_t PLAIN,
    10.6      gpgme_data_t CIPHER);
    10.7 +typedef gpgme_error_t(*gpgme_op_encrypt_t)(gpgme_ctx_t CTX,
    10.8 +        gpgme_key_t RECP[], gpgme_encrypt_flags_t FLAGS, gpgme_data_t PLAIN,
    10.9 +        gpgme_data_t CIPHER);
   10.10  typedef gpgme_verify_result_t(*gpgme_op_verify_result_t)(gpgme_ctx_t CTX);
   10.11  typedef void(*gpgme_signers_clear_t)(gpgme_ctx_t CTX);
   10.12  typedef gpgme_error_t(*gpgme_signers_add_t)(gpgme_ctx_t CTX, const gpgme_key_t KEY);
   10.13 @@ -102,6 +105,7 @@
   10.14      gpgme_op_decrypt_verify_t gpgme_op_decrypt_verify;
   10.15      gpgme_op_decrypt_result_t gpgme_op_decrypt_result;
   10.16      gpgme_op_encrypt_sign_t gpgme_op_encrypt_sign;
   10.17 +    gpgme_op_encrypt_t gpgme_op_encrypt;
   10.18      gpgme_op_verify_result_t gpgme_op_verify_result;
   10.19      gpgme_signers_clear_t gpgme_signers_clear;
   10.20      gpgme_signers_add_t gpgme_signers_add;
   10.21 @@ -125,4 +129,3 @@
   10.22      gpgme_op_edit_t gpgme_op_edit;
   10.23      gpgme_io_write_t gpgme_io_write;
   10.24  };
   10.25 -
    11.1 --- a/test/encrypt_for_identity_test.cc	Fri Mar 10 14:17:43 2017 +0100
    11.2 +++ b/test/encrypt_for_identity_test.cc	Fri Mar 10 15:23:31 2017 +0100
    11.3 @@ -51,7 +51,7 @@
    11.4      cout << "encrypting message as MIME multipart…\n";
    11.5      message* encrypted_msg = nullptr;
    11.6      cout << "calling encrypt_message_for_identity()\n";
    11.7 -    status = encrypt_message_for_self(session, alice, outgoing_message, &encrypted_msg, PEP_enc_PGP_MIME);
    11.8 +    status = encrypt_message_for_self(session, alice, outgoing_message, &encrypted_msg, PEP_enc_PGP_MIME, PEP_encrypt_flag_default);
    11.9      cout << "encrypt_message() returns " << std::hex << status << '.' << endl;
   11.10      assert(status == PEP_STATUS_OK);
   11.11      assert(encrypted_msg);