Merge with default outlook_mime_support
authorMarkus Schaber <markus@pep-security.net>
Thu, 01 Sep 2016 19:09:20 +0200
branchoutlook_mime_support
changeset 111507072f55445a
parent 1042 bb7d2fe42d66
parent 1096 396214c5cd9b
child 1130 a501981ae686
Merge with default
     1.1 --- a/src/cryptotech.c	Sun Aug 21 01:57:49 2016 +0200
     1.2 +++ b/src/cryptotech.c	Thu Sep 01 19:09:20 2016 +0200
     1.3 @@ -7,7 +7,7 @@
     1.4  #include "pgp_netpgp.h"
     1.5  #endif
     1.6  #endif
     1.7 -
     1.8 +// 
     1.9  
    1.10  #include <stdlib.h>
    1.11  #include <memory.h>
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/openpgp_compat.c	Thu Sep 01 19:09:20 2016 +0200
     2.3 @@ -0,0 +1,23 @@
     2.4 +#include "pEp_internal.h"
     2.5 +#include "dynamic_api.h"
     2.6 +#include "openpgp_compat.h"
     2.7 +
     2.8 +DYNAMIC_API PEP_STATUS OpenPGP_list_keyinfo (
     2.9 +        PEP_SESSION session, const char* search_pattern, stringpair_list_t** keyinfo_list
    2.10 +    )
    2.11 +{
    2.12 +    assert(session);
    2.13 +    assert(keyinfo_list);
    2.14 +
    2.15 +    if (!(session && keyinfo_list))
    2.16 +        return PEP_ILLEGAL_VALUE;
    2.17 +
    2.18 +    stringpair_list_t* _keyinfo_list = NULL;
    2.19 +    
    2.20 +    PEP_STATUS retval = pgp_list_keyinfo(session, search_pattern, &_keyinfo_list);
    2.21 +        
    2.22 +    if (retval == PEP_STATUS_OK)
    2.23 +        *keyinfo_list = _keyinfo_list;
    2.24 +    
    2.25 +    return retval;
    2.26 +}
    2.27 \ No newline at end of file
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/openpgp_compat.h	Thu Sep 01 19:09:20 2016 +0200
     3.3 @@ -0,0 +1,44 @@
     3.4 +// openpgp_compat.h
     3.5 +//
     3.6 +// These functions are the exposure of non-generic PGP-specific functionality (largely related to PGP
     3.7 +// keyrings) to adapters that need them without polluting the engine interface.
     3.8 +//
     3.9 +#pragma once
    3.10 +
    3.11 +#ifdef __cplusplus
    3.12 +extern "C" {
    3.13 +#endif
    3.14 +
    3.15 +#include <stddef.h>
    3.16 +#include <stdint.h>
    3.17 +#include <stdbool.h>
    3.18 +    
    3.19 +#include "dynamic_api.h"
    3.20 +#include "stringpair.h"    
    3.21 +
    3.22 +#ifdef USE_GPG
    3.23 +#include "pgp_gpg.h"
    3.24 +#else
    3.25 +#ifdef USE_NETPGP
    3.26 +#include "pgp_netpgp.h"
    3.27 +#endif
    3.28 +#endif    
    3.29 +    
    3.30 +//  OpenPGP_list_keyinfo() - get a key/UID list for pattern matches in keyring (NULL or ""
    3.31 +//                           to return entire keyring), filtering out revoked keys in the results
    3.32 +//
    3.33 +//  parameters:
    3.34 +//      session (in)          session handle
    3.35 +//      search_pattern (in)   search pattern - either an fpr, or something within the UID, or NULL / "" for
    3.36 +//                            all keys
    3.37 +//      keyinfo_list (out)    a key/value pair list for each key / UID combination
    3.38 +//
    3.39 +//  caveat:
    3.40 +//      keyinfo_list must be freed by the caller.
    3.41 +DYNAMIC_API PEP_STATUS OpenPGP_list_keyinfo (
    3.42 +        PEP_SESSION session, const char* search_pattern, stringpair_list_t** keyinfo_list
    3.43 +    );
    3.44 +    
    3.45 +#ifdef __cplusplus
    3.46 +}
    3.47 +#endif
    3.48 \ No newline at end of file
     4.1 --- a/src/pEpEngine.c	Sun Aug 21 01:57:49 2016 +0200
     4.2 +++ b/src/pEpEngine.c	Thu Sep 01 19:09:20 2016 +0200
     4.3 @@ -1234,6 +1234,7 @@
     4.4      return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern, keylist);
     4.5  }
     4.6  
     4.7 +
     4.8  DYNAMIC_API PEP_STATUS generate_keypair(
     4.9          PEP_SESSION session, pEp_identity *identity
    4.10      )
     5.1 --- a/src/pEpEngine.h	Sun Aug 21 01:57:49 2016 +0200
     5.2 +++ b/src/pEpEngine.h	Thu Sep 01 19:09:20 2016 +0200
     5.3 @@ -10,6 +10,7 @@
     5.4  
     5.5  #include "dynamic_api.h"
     5.6  #include "stringlist.h"
     5.7 +#include "stringpair.h"    
     5.8  #include "timestamp.h"
     5.9  
    5.10  #define PEP_VERSION "1.0" // protocol version
    5.11 @@ -644,7 +645,6 @@
    5.12          PEP_SESSION session, const char *pattern, stringlist_t **keylist
    5.13      );
    5.14  
    5.15 -
    5.16  // send_key() - send key(s) to keyserver
    5.17  //
    5.18  //  parameters:
     6.1 --- a/src/pgp_gpg.c	Sun Aug 21 01:57:49 2016 +0200
     6.2 +++ b/src/pgp_gpg.c	Thu Sep 01 19:09:20 2016 +0200
     6.3 @@ -1225,6 +1225,101 @@
     6.4      return PEP_STATUS_OK;
     6.5  }
     6.6  
     6.7 +PEP_STATUS pgp_list_keyinfo(PEP_SESSION session, const char* pattern, 
     6.8 +                            stringpair_list_t** keyinfo_list)
     6.9 +{    
    6.10 +    gpgme_error_t gpgme_error;
    6.11 +    assert(session);
    6.12 +    assert(keyinfo_list);
    6.13 +    
    6.14 +    if (!session || !keyinfo_list)
    6.15 +        return PEP_ILLEGAL_VALUE;
    6.16 +    
    6.17 +    *keyinfo_list = NULL;
    6.18 +    
    6.19 +    gpgme_error = gpg.gpgme_op_keylist_start(session->ctx, pattern, 0);
    6.20 +    gpgme_error = _GPGERR(gpgme_error);
    6.21 +    
    6.22 +    switch(gpgme_error) {
    6.23 +        case GPG_ERR_NO_ERROR:
    6.24 +            break;
    6.25 +        case GPG_ERR_INV_VALUE:
    6.26 +            assert(0);
    6.27 +            return PEP_UNKNOWN_ERROR;
    6.28 +        default:
    6.29 +            gpg.gpgme_op_keylist_end(session->ctx);
    6.30 +            return PEP_GET_KEY_FAILED;        
    6.31 +    };
    6.32 +    
    6.33 +    gpgme_key_t key;
    6.34 +    stringpair_list_t* _keyinfo_list = new_stringpair_list(NULL);
    6.35 +    stringpair_list_t* list_curr = _keyinfo_list;
    6.36 +    stringpair_t* pair = NULL;
    6.37 +        
    6.38 +    do {
    6.39 +        gpgme_error = gpg.gpgme_op_keylist_next(session->ctx, &key);
    6.40 +        gpgme_error = _GPGERR(gpgme_error);
    6.41 +      
    6.42 +        switch(gpgme_error) {
    6.43 +            case GPG_ERR_EOF:
    6.44 +                break;
    6.45 +            case GPG_ERR_NO_ERROR:
    6.46 +                assert(key);
    6.47 +                assert(key->subkeys);
    6.48 +                if (!key || !key->subkeys)
    6.49 +                    return PEP_GET_KEY_FAILED;
    6.50 +
    6.51 +                // first subkey is primary key
    6.52 +                char* fpr = key->subkeys->fpr;
    6.53 +                char* uid = key->uids->uid;
    6.54 +                
    6.55 +                assert(fpr);
    6.56 +                assert(uid); // ??
    6.57 +                if (!fpr)
    6.58 +                    return PEP_GET_KEY_FAILED;
    6.59 +                
    6.60 +                PEP_STATUS key_status = PEP_GET_KEY_FAILED;
    6.61 +                
    6.62 +                bool key_revoked = false;
    6.63 +                                
    6.64 +                if (key->subkeys->revoked)
    6.65 +                    continue;
    6.66 +                
    6.67 +                pair = new_stringpair(fpr, uid);
    6.68 +
    6.69 +                assert(pair);
    6.70 +                
    6.71 +                if (pair) {
    6.72 +                    list_curr = stringpair_list_add(list_curr, pair);
    6.73 +                    pair = NULL;
    6.74 +                    
    6.75 +                    assert(list_curr);
    6.76 +                    if (list_curr != NULL)
    6.77 +                        break;
    6.78 +                    else
    6.79 +                        free_stringpair(pair);
    6.80 +                }
    6.81 +                // else fallthrough (list_curr or pair wasn't allocateable)
    6.82 +            case GPG_ERR_ENOMEM:
    6.83 +                free_stringpair_list(_keyinfo_list);
    6.84 +                gpg.gpgme_op_keylist_end(session->ctx);
    6.85 +                return PEP_OUT_OF_MEMORY;
    6.86 +            default:
    6.87 +                gpg.gpgme_op_keylist_end(session->ctx);
    6.88 +                return PEP_UNKNOWN_ERROR;
    6.89 +        }
    6.90 +    } while (gpgme_error != GPG_ERR_EOF);
    6.91 +    
    6.92 +    if (_keyinfo_list->value == NULL) {
    6.93 +        free_stringpair_list(_keyinfo_list);
    6.94 +        _keyinfo_list = NULL;
    6.95 +    }
    6.96 +    
    6.97 +    *keyinfo_list = _keyinfo_list;
    6.98 +    
    6.99 +    return PEP_STATUS_OK;
   6.100 +}
   6.101 +
   6.102  static void _switch_mode(pEpSession *session, gpgme_keylist_mode_t remove_mode,
   6.103      gpgme_keylist_mode_t add_mode)
   6.104  {
     7.1 --- a/src/pgp_gpg.h	Sun Aug 21 01:57:49 2016 +0200
     7.2 +++ b/src/pgp_gpg.h	Thu Sep 01 19:09:20 2016 +0200
     7.3 @@ -30,6 +30,10 @@
     7.4          PEP_SESSION session, const char *pattern, stringlist_t **keylist
     7.5      );
     7.6  
     7.7 +PEP_STATUS pgp_list_keyinfo(
     7.8 +    PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list
     7.9 +    );
    7.10 +
    7.11  PEP_STATUS pgp_generate_keypair(
    7.12          PEP_SESSION session, pEp_identity *identity
    7.13      );
     8.1 --- a/src/pgp_netpgp.c	Sun Aug 21 01:57:49 2016 +0200
     8.2 +++ b/src/pgp_netpgp.c	Thu Sep 01 19:09:20 2016 +0200
     8.3 @@ -1169,7 +1169,7 @@
     8.4          return PEP_OUT_OF_MEMORY;
     8.5      } else { 
     8.6  
     8.7 -        *keylist = stringlist_add(*keylist, newfprstr);
     8.8 +        stringlist_add(*keylist, newfprstr);
     8.9          free(newfprstr);
    8.10          if (*keylist == NULL) {
    8.11              return PEP_OUT_OF_MEMORY;
    8.12 @@ -1178,6 +1178,34 @@
    8.13      return PEP_STATUS_OK;
    8.14  }
    8.15  
    8.16 +static PEP_STATUS add_keyinfo_to_stringpair_list(void* arg, pgp_key_t *key) {
    8.17 +    stringpair_list_t** keyinfo_list = (stringpair_list_t**)arg;
    8.18 +    stringpair_t* pair = NULL;
    8.19 +    char* id_fpr = NULL;
    8.20 +    char* primary_userid = (char*)pgp_key_get_primary_userid(key);
    8.21 +
    8.22 +    bool key_revoked = false;
    8.23 +                
    8.24 +//    PEP_STATUS key_status = pgp_key_revoked(session, id_fpr, &key_revoked);
    8.25 +                
    8.26 +//    if (key_revoked || key_status == PEP_GET_KEY_FAILED)
    8.27 +//        return PEP_STATUS_OK; // we just move on
    8.28 +        
    8.29 +    fpr_to_str(&id_fpr, key->pubkeyfpr.fingerprint,
    8.30 +                key->pubkeyfpr.length);
    8.31 +
    8.32 +    pair = new_stringpair(id_fpr, primary_userid);
    8.33 +    
    8.34 +    if (pair == NULL)
    8.35 +        return PEP_OUT_OF_MEMORY;
    8.36 +    
    8.37 +    *keyinfo_list = stringpair_list_add(*keyinfo_list, pair);
    8.38 +    free(id_fpr);
    8.39 +    if (*keyinfo_list == NULL)
    8.40 +        return PEP_OUT_OF_MEMORY;
    8.41 +    return PEP_STATUS_OK;
    8.42 +}
    8.43 +
    8.44  PEP_STATUS pgp_find_keys(
    8.45      PEP_SESSION session, const char *pattern, stringlist_t **keylist
    8.46      )
    8.47 @@ -1644,3 +1672,33 @@
    8.48      
    8.49      return PEP_STATUS_OK;
    8.50  }
    8.51 +
    8.52 +
    8.53 +PEP_STATUS pgp_list_keyinfo(
    8.54 +        PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list)
    8.55 +{
    8.56 +    
    8.57 +    if (!session || !keyinfo_list)
    8.58 +        return PEP_UNKNOWN_ERROR;
    8.59 +    
    8.60 +    if (pthread_mutex_lock(&netpgp_mutex))
    8.61 +    {
    8.62 +        return PEP_UNKNOWN_ERROR;
    8.63 +    }
    8.64 +    
    8.65 +    pgp_key_t *key;
    8.66 +
    8.67 +    PEP_STATUS result;
    8.68 +    
    8.69 +    result = find_keys_do(pattern, &add_keyinfo_to_stringpair_list, (void*)keyinfo_list);
    8.70 +    
    8.71 +    if (!keyinfo_list)
    8.72 +        result = PEP_KEY_NOT_FOUND;
    8.73 +    
    8.74 +unlock_netpgp:
    8.75 +    pthread_mutex_unlock(&netpgp_mutex);
    8.76 +    
    8.77 +    return result;
    8.78 +}
    8.79 +
    8.80 +
     9.1 --- a/src/pgp_netpgp.h	Sun Aug 21 01:57:49 2016 +0200
     9.2 +++ b/src/pgp_netpgp.h	Thu Sep 01 19:09:20 2016 +0200
     9.3 @@ -30,6 +30,10 @@
     9.4          PEP_SESSION session, const char *pattern, stringlist_t **keylist
     9.5      );
     9.6  
     9.7 +PEP_STATUS pgp_list_keyinfo(
     9.8 +    PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list
     9.9 +    );
    9.10 +
    9.11  PEP_STATUS pgp_generate_keypair(
    9.12          PEP_SESSION session, pEp_identity *identity
    9.13      );
    10.1 --- a/src/platform_unix.c	Sun Aug 21 01:57:49 2016 +0200
    10.2 +++ b/src/platform_unix.c	Thu Sep 01 19:09:20 2016 +0200
    10.3 @@ -6,6 +6,7 @@
    10.4  #include <sys/stat.h>
    10.5  #include <sys/types.h>
    10.6  #include <fcntl.h>
    10.7 +#include <regex.h>
    10.8  
    10.9  #include "platform_unix.h"
   10.10  
   10.11 @@ -123,6 +124,14 @@
   10.12      return retval;
   10.13  }
   10.14  
   10.15 +#ifdef USE_NETPGP
   10.16 +// FIXME: This may cause problems - this is a quick compatibility fix for netpgp code
   10.17 +int regnexec(const regex_t* preg, const char* string,
   10.18 +             size_t len, size_t nmatch, regmatch_t pmatch[], int eflags) {
   10.19 +    return regexec(preg, string, nmatch, pmatch, eflags);
   10.20 +}
   10.21 +#endif
   10.22 +
   10.23  #endif
   10.24  
   10.25  const char *unix_local_db(void)
    11.1 --- a/src/platform_unix.h	Sun Aug 21 01:57:49 2016 +0200
    11.2 +++ b/src/platform_unix.h	Thu Sep 01 19:09:20 2016 +0200
    11.3 @@ -5,6 +5,7 @@
    11.4  #include <unistd.h>
    11.5  #include <strings.h>
    11.6  #include <sys/select.h>
    11.7 +#include <regex.h>
    11.8  
    11.9  #ifdef __cplusplus
   11.10  extern "C" {
   11.11 @@ -43,6 +44,15 @@
   11.12  #if !defined(BSD) && !defined(__APPLE__)
   11.13  size_t strlcpy(char* dst, const	char* src, size_t size);
   11.14  size_t strlcat(char* dst, const	char* src, size_t size);
   11.15 +
   11.16 +// N.B. This is ifdef'd out because NDK users sometimes have trouble finding regex functions in
   11.17 +//      the library in spite of the inclusion of regex.h - this is a FIXME, but since iOS is
   11.18 +//      *currently* the only netpgp user, we will ifdef this so that we don't block Android.
   11.19 +#ifdef USE_NETPGP
   11.20 +int regnexec(const regex_t* preg, const char* string,
   11.21 +             size_t len, size_t nmatch, regmatch_t pmatch[], int eflags);
   11.22 +#endif
   11.23 +
   11.24  #endif
   11.25  
   11.26  #ifdef __cplusplus
    12.1 --- a/test/encrypt_for_identity_test.cc	Sun Aug 21 01:57:49 2016 +0200
    12.2 +++ b/test/encrypt_for_identity_test.cc	Thu Sep 01 19:09:20 2016 +0200
    12.3 @@ -90,7 +90,7 @@
    12.4      for (stringlist_t* kl4 = keylist_used; kl4 && kl4->value; kl4 = kl4->next)
    12.5      {
    12.6          cout << "\t " << kl4->value << endl;
    12.7 -        assert(strcmp("4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", kl4->value) == 0);
    12.8 +        assert(strcasecmp("4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", kl4->value) == 0);
    12.9          cout << "Encrypted for Alice! Yay! It worked!" << endl;
   12.10      }
   12.11      cout << "Encrypted ONLY for Alice! Test passed. Move along. These are not the bugs you are looking for." << endl;
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/pgp_list_keys_test.cc	Thu Sep 01 19:09:20 2016 +0200
    13.3 @@ -0,0 +1,71 @@
    13.4 +#include <iostream>
    13.5 +#include <string>
    13.6 +#include <assert.h>
    13.7 +#include "pEpEngine.h"
    13.8 +#include "stringpair.h"
    13.9 +#include "openpgp_compat.h"
   13.10 +
   13.11 +using namespace std;
   13.12 +
   13.13 +void print_stringpair_list(stringpair_list_t* spl) {
   13.14 +    for ( ; spl != NULL; spl = spl->next) {
   13.15 +        if (spl->value) {
   13.16 +            cout << "Key:" << endl;
   13.17 +            if (spl->value->key)
   13.18 +                cout << "\tFPR: " << spl->value->key << endl;
   13.19 +            if (spl->value->value)
   13.20 +                cout << "\tUID: " << spl->value->value << endl;
   13.21 +        }
   13.22 +    }
   13.23 +}
   13.24 +
   13.25 +int main() {
   13.26 +    cout << "\n*** openpgp_compat test ***\n\n";
   13.27 +
   13.28 +    PEP_SESSION session;
   13.29 +    
   13.30 +    cout << "calling init()\n";
   13.31 +    PEP_STATUS status1 = init(&session);   
   13.32 +    assert(status1 == PEP_STATUS_OK);
   13.33 +    assert(session);
   13.34 +    cout << "init() completed.\n";
   13.35 +
   13.36 +    cout << "Listing all the keys:" << endl;
   13.37 +    stringpair_list_t* all_the_ids = NULL;
   13.38 +    OpenPGP_list_keyinfo(session, "", &all_the_ids);
   13.39 +    print_stringpair_list(all_the_ids);
   13.40 +    free_stringpair_list(all_the_ids);
   13.41 +    
   13.42 +    cout << "**********************" << endl << endl << "Checking on Alice, Bob and John" << endl;
   13.43 +    all_the_ids = NULL;
   13.44 +    OpenPGP_list_keyinfo(session, "pEp Test", &all_the_ids);
   13.45 +    print_stringpair_list(all_the_ids);
   13.46 +    free_stringpair_list(all_the_ids);
   13.47 +
   13.48 +    cout << "**********************" << endl << endl << "Compare to find_keys for Alice, Bob and John" << endl;
   13.49 +    stringlist_t* all_the_keys;
   13.50 +    find_keys(session, "pEp Test", &all_the_keys);
   13.51 +    stringlist_t* i;
   13.52 +    for (i = all_the_keys; i; i = i->next) {
   13.53 +        cout << i->value << endl;
   13.54 +    }
   13.55 +    free_stringlist(all_the_keys);
   13.56 +
   13.57 +    
   13.58 +    cout << "**********************" << endl << endl << "Checking FPR" << endl;
   13.59 +    all_the_ids = NULL;
   13.60 +    OpenPGP_list_keyinfo(session, "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39", &all_the_ids);
   13.61 +    print_stringpair_list(all_the_ids);
   13.62 +    free_stringpair_list(all_the_ids);
   13.63 +
   13.64 +    cout << "**********************" << endl << endl << "Checking on nothing" << endl;
   13.65 +    all_the_ids = NULL;
   13.66 +    OpenPGP_list_keyinfo(session, "ekhwr89234uh4rknfjsklejfnlskjflselkflkserjs", &all_the_ids);
   13.67 +    print_stringpair_list(all_the_ids);
   13.68 +    free_stringpair_list(all_the_ids);
   13.69 +
   13.70 +    cout << "calling release()\n";
   13.71 +    release(session);
   13.72 +    return 0;
   13.73 +}
   13.74 +