merged with default krista_local_windows
authorkrista
Wed, 31 Aug 2016 17:26:59 +0200
branchkrista_local_windows
changeset 112589e75396c69a
parent 1124 e50b654b3e14
child 1126 129b561095a6
merged with default
.hgtags
asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj
db/create_system_db.sql
pEpEngine.vcxproj
src/Makefile
src/cryptotech.c
src/keymanagement.c
src/message_api.c
src/message_api.h
src/mime.c
src/pEpEngine.c
src/pEpEngine.h
src/pgp_gpg.c
src/pgp_gpg.h
src/pgp_netpgp.c
src/pgp_netpgp.h
src/platform_unix.c
src/platform_unix.h
src/platform_windows.h
test/pEpEngineTest.cc
     1.1 --- a/.hgtags	Tue Aug 02 12:55:50 2016 +0200
     1.2 +++ b/.hgtags	Wed Aug 31 17:26:59 2016 +0200
     1.3 @@ -1,3 +1,4 @@
     1.4  c51c34a97ba7345f4fe9cd1313335f41e0da17b1 list
     1.5  b5d0f1e3b9c7f727c427562a0e9ff1a027250820 0.7
     1.6  2b4d6c760ad771d9917cd6f0f96c4ab379d75d1d 0.7.0
     1.7 +a1ba15c1ac041c780e52e759db6b77d116f29c72 0.8.0
     2.1 --- a/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Tue Aug 02 12:55:50 2016 +0200
     2.2 +++ b/asn.1/pEpEngineASN1/pEpEngineASN1.vcxproj	Wed Aug 31 17:26:59 2016 +0200
     2.3 @@ -54,7 +54,7 @@
     2.4        <WarningLevel>Level3</WarningLevel>
     2.5        <Optimization>Disabled</Optimization>
     2.6        <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     2.7 -      <CompileAs>Default</CompileAs>
     2.8 +	  <CompileAs>Default</CompileAs>
     2.9      </ClCompile>
    2.10      <Link>
    2.11        <SubSystem>Windows</SubSystem>
     3.1 --- a/db/create_system_db.sql	Tue Aug 02 12:55:50 2016 +0200
     3.2 +++ b/db/create_system_db.sql	Wed Aug 31 17:26:59 2016 +0200
     3.3 @@ -42,6 +42,6 @@
     3.4  INSERT INTO i18n_token VALUES ('ca', 1000, 'Vull mostrar les trustwords en català');
     3.5  
     3.6  INSERT INTO i18n_language VALUES ('tr', 'Türkçe');
     3.7 -INSERT INTO i18n_token VALUES ('tr', 1000, 'Güvenlik kelimelerini Türk dilinde görüntülemek istiyorum');
     3.8 +INSERT INTO i18n_token VALUES ('tr', 1000, 'Güvenlik kelimelerini Türkçe görüntülemek istiyorum');
     3.9  -- add more languages here
    3.10  
     4.1 --- a/pEpEngine.vcxproj	Tue Aug 02 12:55:50 2016 +0200
     4.2 +++ b/pEpEngine.vcxproj	Wed Aug 31 17:26:59 2016 +0200
     4.3 @@ -14,11 +14,11 @@
     4.4      <ProjectGuid>{146E69F8-E1DA-456A-B048-6DD29D9ACF6B}</ProjectGuid>
     4.5      <Keyword>Win32Proj</Keyword>
     4.6      <RootNamespace>pEpEngine</RootNamespace>
     4.7 -    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
     4.8 +	<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
     4.9    </PropertyGroup>
    4.10    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
    4.11    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
    4.12 -    <ConfigurationType>StaticLibrary</ConfigurationType>
    4.13 +    <ConfigurationType>DynamicLibrary</ConfigurationType>
    4.14      <UseDebugLibraries>true</UseDebugLibraries>
    4.15      <PlatformToolset>v140</PlatformToolset>
    4.16      <CharacterSet>Unicode</CharacterSet>
    4.17 @@ -48,7 +48,8 @@
    4.18    </PropertyGroup>
    4.19    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
    4.20      <LinkIncremental>false</LinkIncremental>
    4.21 -    <IncludePath>C:\Users\vb\Documents\Visual Studio 2013\Projects\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath)</IncludePath>
    4.22 +    <IncludePath>$(ProjectDir)\..\libetpan\build-windows\include;C:\Program Files %28x86%29\GNU\GnuPG\include;$(IncludePath)</IncludePath>
    4.23 +    <LibraryPath>$(ProjectDir)\..\libetpan\build-windows\Release;$(LibraryPath)</LibraryPath>
    4.24    </PropertyGroup>
    4.25    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
    4.26      <ClCompile>
    4.27 @@ -59,7 +60,7 @@
    4.28        <SDLCheck>true</SDLCheck>
    4.29        <EnablePREfast>false</EnablePREfast>
    4.30        <AdditionalIncludeDirectories>C:\Users\vb\share\asn1c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    4.31 -      <CompileAs>Default</CompileAs>
    4.32 +	  <CompileAs>Default</CompileAs>
    4.33      </ClCompile>
    4.34      <Link>
    4.35        <SubSystem>Windows</SubSystem>
    4.36 @@ -82,6 +83,7 @@
    4.37        <SDLCheck>false</SDLCheck>
    4.38        <TreatWarningAsError>false</TreatWarningAsError>
    4.39        <AdditionalIncludeDirectories>C:\Users\vb\share\asn1c;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    4.40 +	  <CompileAs>Default</CompileAs>
    4.41      </ClCompile>
    4.42      <Link>
    4.43        <SubSystem>Windows</SubSystem>
     5.1 --- a/src/Makefile	Tue Aug 02 12:55:50 2016 +0200
     5.2 +++ b/src/Makefile	Wed Aug 31 17:26:59 2016 +0200
     5.3 @@ -88,7 +88,7 @@
     5.4  install: $(TARGET)
     5.5  	cp $< $(PREFIX)/lib/
     5.6  	mkdir -p $(PREFIX)/include/pEp
     5.7 -	cp pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h cryptotech.h $(PREFIX)/include/pEp/
     5.8 +	cp pEpEngine.h keymanagement.h message_api.h dynamic_api.h stringlist.h timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h cryptotech.h sync.h $(PREFIX)/include/pEp/
     5.9  
    5.10  uninstall:
    5.11  	rm -f $(PREFIX)/lib/$(TARGET)
     6.1 --- a/src/cryptotech.c	Tue Aug 02 12:55:50 2016 +0200
     6.2 +++ b/src/cryptotech.c	Wed Aug 31 17:26:59 2016 +0200
     6.3 @@ -7,7 +7,7 @@
     6.4  #include "pgp_netpgp.h"
     6.5  #endif
     6.6  #endif
     6.7 -
     6.8 +// 
     6.9  
    6.10  #include <stdlib.h>
    6.11  #include <memory.h>
     7.1 --- a/src/keymanagement.c	Tue Aug 02 12:55:50 2016 +0200
     7.2 +++ b/src/keymanagement.c	Wed Aug 31 17:26:59 2016 +0200
     7.3 @@ -131,7 +131,7 @@
     7.4          {
     7.5              return PEP_OUT_OF_MEMORY;
     7.6          }
     7.7 -        snprintf(identity->user_id, strlen(identity->address) + 5,
     7.8 +        snprintf(identity->user_id, strlen(identity->address) + 6,
     7.9                   "TOFU_%s", identity->address);
    7.10      }
    7.11   
     8.1 --- a/src/message_api.c	Tue Aug 02 12:55:50 2016 +0200
     8.2 +++ b/src/message_api.c	Wed Aug 31 17:26:59 2016 +0200
     8.3 @@ -532,12 +532,13 @@
     8.4  
     8.5                      if (_s->filename) {
     8.6                          size_t len = strlen(_s->filename);
     8.7 -                        filename = calloc(1, len + 5);
     8.8 +                        size_t bufsize = len + 5; // length of .pgp extension + NUL
     8.9 +                        filename = calloc(1, bufsize);
    8.10                          if (filename == NULL)
    8.11                              goto enomem;
    8.12  
    8.13 -                        strlcpy(filename, _s->filename, len);
    8.14 -                        strlcpy(filename + len, ".pgp", 5);
    8.15 +                        strlcpy(filename, _s->filename, bufsize);
    8.16 +                        strlcat(filename, ".pgp", bufsize);
    8.17                      }
    8.18                      else {
    8.19                          filename = calloc(1, 20);
    8.20 @@ -1209,6 +1210,103 @@
    8.21      return status;
    8.22  }
    8.23  
    8.24 +DYNAMIC_API PEP_STATUS encrypt_message_for_self(
    8.25 +        PEP_SESSION session,
    8.26 +        pEp_identity* target_id,
    8.27 +        message *src,
    8.28 +        message **dst,
    8.29 +        PEP_enc_format enc_format
    8.30 +    )
    8.31 +{
    8.32 +    PEP_STATUS status = PEP_STATUS_OK;
    8.33 +    message * msg = NULL;
    8.34 +    stringlist_t * keys = NULL;
    8.35 +
    8.36 +    assert(session);
    8.37 +    assert(src);
    8.38 +    assert(dst);
    8.39 +    assert(enc_format != PEP_enc_none);
    8.40 +
    8.41 +    if (!(session && src && dst && enc_format != PEP_enc_none))
    8.42 +        return PEP_ILLEGAL_VALUE;
    8.43 +
    8.44 +    if (src->dir == PEP_dir_incoming)
    8.45 +        return PEP_ILLEGAL_VALUE;
    8.46 +    
    8.47 +    determine_encryption_format(src);
    8.48 +    if (src->enc_format != PEP_enc_none)
    8.49 +        return PEP_ILLEGAL_VALUE;
    8.50 +
    8.51 +    status = myself(session, target_id);
    8.52 +    if (status != PEP_STATUS_OK)
    8.53 +        goto pep_error;
    8.54 +
    8.55 +    *dst = NULL;
    8.56 +
    8.57 +    
    8.58 +    PEP_STATUS _status = update_identity(session, target_id);
    8.59 +    if (_status != PEP_STATUS_OK) {
    8.60 +        status = _status;
    8.61 +        goto pep_error;
    8.62 +    }
    8.63 +
    8.64 +    char* target_fpr = target_id->fpr;
    8.65 +    if (!target_fpr)
    8.66 +        return PEP_KEY_NOT_FOUND; // FIXME: Error condition
    8.67 +        
    8.68 +    keys = new_stringlist(target_fpr);
    8.69 +
    8.70 +    
    8.71 +    msg = clone_to_empty_message(src);
    8.72 +    if (msg == NULL)
    8.73 +        goto enomem;
    8.74 +
    8.75 +    switch (enc_format) {
    8.76 +        case PEP_enc_PGP_MIME:
    8.77 +        case PEP_enc_PEP: // BUG: should be implemented extra
    8.78 +            status = encrypt_PGP_MIME(session, src, keys, msg);
    8.79 +            break;
    8.80 +
    8.81 +        case PEP_enc_pieces:
    8.82 +            status = encrypt_PGP_in_pieces(session, src, keys, msg);
    8.83 +            break;
    8.84 +
    8.85 +        /* case PEP_enc_PEP:
    8.86 +            // TODO: implement
    8.87 +            NOT_IMPLEMENTED */
    8.88 +
    8.89 +        default:
    8.90 +            assert(0);
    8.91 +            status = PEP_ILLEGAL_VALUE;
    8.92 +            goto pep_error;
    8.93 +    }
    8.94 +        
    8.95 +    if (status == PEP_OUT_OF_MEMORY)
    8.96 +        goto enomem;
    8.97 +    
    8.98 +    if (status != PEP_STATUS_OK)
    8.99 +        goto pep_error;
   8.100 +
   8.101 +     if (msg && msg->shortmsg == NULL) {
   8.102 +         msg->shortmsg = strdup("pEp");
   8.103 +         assert(msg->shortmsg);
   8.104 +         if (msg->shortmsg == NULL)
   8.105 +             goto enomem;
   8.106 +     }
   8.107 +
   8.108 +    *dst = msg;
   8.109 +    return status;
   8.110 +
   8.111 +enomem:
   8.112 +    status = PEP_OUT_OF_MEMORY;
   8.113 +
   8.114 +pep_error:
   8.115 +    free_stringlist(keys);
   8.116 +    free_message(msg);
   8.117 +
   8.118 +    return status;
   8.119 +}
   8.120 +
   8.121  static bool is_a_pEpmessage(const message *msg)
   8.122  {
   8.123      for (stringpair_list_t *i = msg->opt_fields; i && i->value ; i=i->next) {
     9.1 --- a/src/message_api.h	Tue Aug 02 12:55:50 2016 +0200
     9.2 +++ b/src/message_api.h	Wed Aug 31 17:26:59 2016 +0200
     9.3 @@ -47,6 +47,38 @@
     9.4          PEP_enc_format enc_format
     9.5      );
     9.6  
     9.7 +// encrypt_message_for_self() - encrypt message in memory for user's identity only,
     9.8 +//                              ignoring recipients and other identities from
     9.9 +//                              the message
    9.10 +//  parameters:
    9.11 +//      session (in)        session handle
    9.12 +//      target_id (in)      self identity this message should be encrypted for
    9.13 +//      src (in)            message to encrypt
    9.14 +//      dst (out)           pointer to new encrypted message or NULL on failure
    9.15 +//      enc_format (in)     encrypted format
    9.16 +//
    9.17 +//  return value:       (FIXME: This may not be correct or complete)
    9.18 +//      PEP_STATUS_OK                   on success
    9.19 +//		PEP_KEY_NOT_FOUND	            at least one of the receipient keys
    9.20 +//		                                could not be found
    9.21 +//		PEP_KEY_HAS_AMBIG_NAME          at least one of the receipient keys has
    9.22 +//		                                an ambiguous name
    9.23 +//		PEP_GET_KEY_FAILED		        cannot retrieve key
    9.24 +//
    9.25 +//	caveat:
    9.26 +//	    the ownership of src remains with the caller
    9.27 +//      the ownership of target_id remains w/ caller            
    9.28 +//	    the ownership of dst goes to the caller
    9.29 +//      message is NOT encrypted for identities other than the target_id (and then,
    9.30 +//          only if the target_id refers to self!)
    9.31 +
    9.32 +DYNAMIC_API PEP_STATUS encrypt_message_for_self(
    9.33 +        PEP_SESSION session,
    9.34 +        pEp_identity* target_id,
    9.35 +        message *src,
    9.36 +        message **dst,
    9.37 +        PEP_enc_format enc_format
    9.38 +    );
    9.39  
    9.40  typedef enum _PEP_color {
    9.41      PEP_rating_undefined = 0,
    10.1 --- a/src/mime.c	Tue Aug 02 12:55:50 2016 +0200
    10.2 +++ b/src/mime.c	Wed Aug 31 17:26:59 2016 +0200
    10.3 @@ -1280,6 +1280,8 @@
    10.4                  }
    10.5                  free(_longmsg);
    10.6                  _longmsg = _text;
    10.7 +                // FIXME: KG - This is where we have the text we want to deal with.
    10.8 +                // Now we need to strip sigs and process them.
    10.9              }
   10.10          }
   10.11      }
    11.1 --- a/src/pEpEngine.c	Tue Aug 02 12:55:50 2016 +0200
    11.2 +++ b/src/pEpEngine.c	Wed Aug 31 17:26:59 2016 +0200
    11.3 @@ -1234,6 +1234,7 @@
    11.4      return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern, keylist);
    11.5  }
    11.6  
    11.7 +
    11.8  DYNAMIC_API PEP_STATUS generate_keypair(
    11.9          PEP_SESSION session, pEp_identity *identity
   11.10      )
   11.11 @@ -1745,6 +1746,11 @@
   11.12      return status;
   11.13  }
   11.14  
   11.15 +DYNAMIC_API const char* get_engine_version() {
   11.16 +    return PEP_ENGINE_VERSION;
   11.17 +}
   11.18 +
   11.19 +
   11.20  DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
   11.21  {
   11.22      assert(session);
    12.1 --- a/src/pEpEngine.h	Tue Aug 02 12:55:50 2016 +0200
    12.2 +++ b/src/pEpEngine.h	Wed Aug 31 17:26:59 2016 +0200
    12.3 @@ -10,6 +10,7 @@
    12.4  
    12.5  #include "dynamic_api.h"
    12.6  #include "stringlist.h"
    12.7 +#include "stringpair.h"    
    12.8  #include "timestamp.h"
    12.9  
   12.10  #define PEP_VERSION "1.0" // protocol version
   12.11 @@ -644,7 +645,6 @@
   12.12          PEP_SESSION session, const char *pattern, stringlist_t **keylist
   12.13      );
   12.14  
   12.15 -
   12.16  // send_key() - send key(s) to keyserver
   12.17  //
   12.18  //  parameters:
   12.19 @@ -884,6 +884,15 @@
   12.20      );
   12.21  
   12.22  
   12.23 +// get_engine_version() - returns the current version of pEpEngine (this is different
   12.24 +//                        from the pEp protocol version!)
   12.25 +//
   12.26 +//  parameters: none
   12.27 +//
   12.28 +//  return_value: const char* to the engine version string constant
   12.29 +//
   12.30 +DYNAMIC_API const char* get_engine_version();
   12.31 +
   12.32  DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session);
   12.33  
   12.34  #ifdef __cplusplus
    13.1 --- a/src/pgp_gpg.c	Tue Aug 02 12:55:50 2016 +0200
    13.2 +++ b/src/pgp_gpg.c	Wed Aug 31 17:26:59 2016 +0200
    13.3 @@ -25,7 +25,6 @@
    13.4      if (f == NULL && errno == ENOMEM)
    13.5          return false;
    13.6  
    13.7 -    /* FIXME: extract as internal function */
    13.8      if (f != NULL) {
    13.9          int length = stringlist_length(keys);
   13.10          unsigned int n = (1 << length) - 1;
   13.11 @@ -1226,6 +1225,101 @@
   13.12      return PEP_STATUS_OK;
   13.13  }
   13.14  
   13.15 +PEP_STATUS pgp_list_keyinfo(PEP_SESSION session, const char* pattern, 
   13.16 +                            stringpair_list_t** keyinfo_list)
   13.17 +{    
   13.18 +    gpgme_error_t gpgme_error;
   13.19 +    assert(session);
   13.20 +    assert(keyinfo_list);
   13.21 +    
   13.22 +    if (!session || !keyinfo_list)
   13.23 +        return PEP_ILLEGAL_VALUE;
   13.24 +    
   13.25 +    *keyinfo_list = NULL;
   13.26 +    
   13.27 +    gpgme_error = gpg.gpgme_op_keylist_start(session->ctx, pattern, 0);
   13.28 +    gpgme_error = _GPGERR(gpgme_error);
   13.29 +    
   13.30 +    switch(gpgme_error) {
   13.31 +        case GPG_ERR_NO_ERROR:
   13.32 +            break;
   13.33 +        case GPG_ERR_INV_VALUE:
   13.34 +            assert(0);
   13.35 +            return PEP_UNKNOWN_ERROR;
   13.36 +        default:
   13.37 +            gpg.gpgme_op_keylist_end(session->ctx);
   13.38 +            return PEP_GET_KEY_FAILED;        
   13.39 +    };
   13.40 +    
   13.41 +    gpgme_key_t key;
   13.42 +    stringpair_list_t* _keyinfo_list = new_stringpair_list(NULL);
   13.43 +    stringpair_list_t* list_curr = _keyinfo_list;
   13.44 +    stringpair_t* pair = NULL;
   13.45 +        
   13.46 +    do {
   13.47 +        gpgme_error = gpg.gpgme_op_keylist_next(session->ctx, &key);
   13.48 +        gpgme_error = _GPGERR(gpgme_error);
   13.49 +      
   13.50 +        switch(gpgme_error) {
   13.51 +            case GPG_ERR_EOF:
   13.52 +                break;
   13.53 +            case GPG_ERR_NO_ERROR:
   13.54 +                assert(key);
   13.55 +                assert(key->subkeys);
   13.56 +                if (!key || !key->subkeys)
   13.57 +                    return PEP_GET_KEY_FAILED;
   13.58 +
   13.59 +                // first subkey is primary key
   13.60 +                char* fpr = key->subkeys->fpr;
   13.61 +                char* uid = key->uids->uid;
   13.62 +                
   13.63 +                assert(fpr);
   13.64 +                assert(uid); // ??
   13.65 +                if (!fpr)
   13.66 +                    return PEP_GET_KEY_FAILED;
   13.67 +                
   13.68 +                PEP_STATUS key_status = PEP_GET_KEY_FAILED;
   13.69 +                
   13.70 +                bool key_revoked = false;
   13.71 +                                
   13.72 +                if (key->subkeys->revoked)
   13.73 +                    continue;
   13.74 +                
   13.75 +                pair = new_stringpair(fpr, uid);
   13.76 +
   13.77 +                assert(pair);
   13.78 +                
   13.79 +                if (pair) {
   13.80 +                    list_curr = stringpair_list_add(list_curr, pair);
   13.81 +                    pair = NULL;
   13.82 +                    
   13.83 +                    assert(list_curr);
   13.84 +                    if (list_curr != NULL)
   13.85 +                        break;
   13.86 +                    else
   13.87 +                        free_stringpair(pair);
   13.88 +                }
   13.89 +                // else fallthrough (list_curr or pair wasn't allocateable)
   13.90 +            case GPG_ERR_ENOMEM:
   13.91 +                free_stringpair_list(_keyinfo_list);
   13.92 +                gpg.gpgme_op_keylist_end(session->ctx);
   13.93 +                return PEP_OUT_OF_MEMORY;
   13.94 +            default:
   13.95 +                gpg.gpgme_op_keylist_end(session->ctx);
   13.96 +                return PEP_UNKNOWN_ERROR;
   13.97 +        }
   13.98 +    } while (gpgme_error != GPG_ERR_EOF);
   13.99 +    
  13.100 +    if (_keyinfo_list->value == NULL) {
  13.101 +        free_stringpair_list(_keyinfo_list);
  13.102 +        _keyinfo_list = NULL;
  13.103 +    }
  13.104 +    
  13.105 +    *keyinfo_list = _keyinfo_list;
  13.106 +    
  13.107 +    return PEP_STATUS_OK;
  13.108 +}
  13.109 +
  13.110  static void _switch_mode(pEpSession *session, gpgme_keylist_mode_t remove_mode,
  13.111      gpgme_keylist_mode_t add_mode)
  13.112  {
    14.1 --- a/src/pgp_gpg.h	Tue Aug 02 12:55:50 2016 +0200
    14.2 +++ b/src/pgp_gpg.h	Wed Aug 31 17:26:59 2016 +0200
    14.3 @@ -30,6 +30,10 @@
    14.4          PEP_SESSION session, const char *pattern, stringlist_t **keylist
    14.5      );
    14.6  
    14.7 +PEP_STATUS pgp_list_keyinfo(
    14.8 +    PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list
    14.9 +    );
   14.10 +
   14.11  PEP_STATUS pgp_generate_keypair(
   14.12          PEP_SESSION session, pEp_identity *identity
   14.13      );
    15.1 --- a/src/pgp_netpgp.c	Tue Aug 02 12:55:50 2016 +0200
    15.2 +++ b/src/pgp_netpgp.c	Wed Aug 31 17:26:59 2016 +0200
    15.3 @@ -1169,7 +1169,7 @@
    15.4          return PEP_OUT_OF_MEMORY;
    15.5      } else { 
    15.6  
    15.7 -        *keylist = stringlist_add(*keylist, newfprstr);
    15.8 +        stringlist_add(*keylist, newfprstr);
    15.9          free(newfprstr);
   15.10          if (*keylist == NULL) {
   15.11              return PEP_OUT_OF_MEMORY;
   15.12 @@ -1178,6 +1178,34 @@
   15.13      return PEP_STATUS_OK;
   15.14  }
   15.15  
   15.16 +static PEP_STATUS add_keyinfo_to_stringpair_list(void* arg, pgp_key_t *key) {
   15.17 +    stringpair_list_t** keyinfo_list = (stringpair_list_t**)arg;
   15.18 +    stringpair_t* pair = NULL;
   15.19 +    char* id_fpr = NULL;
   15.20 +    char* primary_userid = (char*)pgp_key_get_primary_userid(key);
   15.21 +
   15.22 +    bool key_revoked = false;
   15.23 +                
   15.24 +//    PEP_STATUS key_status = pgp_key_revoked(session, id_fpr, &key_revoked);
   15.25 +                
   15.26 +//    if (key_revoked || key_status == PEP_GET_KEY_FAILED)
   15.27 +//        return PEP_STATUS_OK; // we just move on
   15.28 +        
   15.29 +    fpr_to_str(&id_fpr, key->pubkeyfpr.fingerprint,
   15.30 +                key->pubkeyfpr.length);
   15.31 +
   15.32 +    pair = new_stringpair(id_fpr, primary_userid);
   15.33 +    
   15.34 +    if (pair == NULL)
   15.35 +        return PEP_OUT_OF_MEMORY;
   15.36 +    
   15.37 +    *keyinfo_list = stringpair_list_add(*keyinfo_list, pair);
   15.38 +    free(id_fpr);
   15.39 +    if (*keyinfo_list == NULL)
   15.40 +        return PEP_OUT_OF_MEMORY;
   15.41 +    return PEP_STATUS_OK;
   15.42 +}
   15.43 +
   15.44  PEP_STATUS pgp_find_keys(
   15.45      PEP_SESSION session, const char *pattern, stringlist_t **keylist
   15.46      )
   15.47 @@ -1644,3 +1672,33 @@
   15.48      
   15.49      return PEP_STATUS_OK;
   15.50  }
   15.51 +
   15.52 +
   15.53 +PEP_STATUS pgp_list_keyinfo(
   15.54 +        PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list)
   15.55 +{
   15.56 +    
   15.57 +    if (!session || !keyinfo_list)
   15.58 +        return PEP_UNKNOWN_ERROR;
   15.59 +    
   15.60 +    if (pthread_mutex_lock(&netpgp_mutex))
   15.61 +    {
   15.62 +        return PEP_UNKNOWN_ERROR;
   15.63 +    }
   15.64 +    
   15.65 +    pgp_key_t *key;
   15.66 +
   15.67 +    PEP_STATUS result;
   15.68 +    
   15.69 +    result = find_keys_do(pattern, &add_keyinfo_to_stringpair_list, (void*)keyinfo_list);
   15.70 +    
   15.71 +    if (!keyinfo_list)
   15.72 +        result = PEP_KEY_NOT_FOUND;
   15.73 +    
   15.74 +unlock_netpgp:
   15.75 +    pthread_mutex_unlock(&netpgp_mutex);
   15.76 +    
   15.77 +    return result;
   15.78 +}
   15.79 +
   15.80 +
    16.1 --- a/src/pgp_netpgp.h	Tue Aug 02 12:55:50 2016 +0200
    16.2 +++ b/src/pgp_netpgp.h	Wed Aug 31 17:26:59 2016 +0200
    16.3 @@ -30,6 +30,10 @@
    16.4          PEP_SESSION session, const char *pattern, stringlist_t **keylist
    16.5      );
    16.6  
    16.7 +PEP_STATUS pgp_list_keyinfo(
    16.8 +    PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list
    16.9 +    );
   16.10 +
   16.11  PEP_STATUS pgp_generate_keypair(
   16.12          PEP_SESSION session, pEp_identity *identity
   16.13      );
    17.1 --- a/src/platform_unix.c	Tue Aug 02 12:55:50 2016 +0200
    17.2 +++ b/src/platform_unix.c	Wed Aug 31 17:26:59 2016 +0200
    17.3 @@ -6,6 +6,7 @@
    17.4  #include <sys/stat.h>
    17.5  #include <sys/types.h>
    17.6  #include <fcntl.h>
    17.7 +#include <regex.h>
    17.8  
    17.9  #include "platform_unix.h"
   17.10  
   17.11 @@ -123,6 +124,14 @@
   17.12      return retval;
   17.13  }
   17.14  
   17.15 +#ifdef USE_NETPGP
   17.16 +// FIXME: This may cause problems - this is a quick compatibility fix for netpgp code
   17.17 +int regnexec(const regex_t* preg, const char* string,
   17.18 +             size_t len, size_t nmatch, regmatch_t pmatch[], int eflags) {
   17.19 +    return regexec(preg, string, nmatch, pmatch, eflags);
   17.20 +}
   17.21 +#endif
   17.22 +
   17.23  #endif
   17.24  
   17.25  const char *unix_local_db(void)
    18.1 --- a/src/platform_unix.h	Tue Aug 02 12:55:50 2016 +0200
    18.2 +++ b/src/platform_unix.h	Wed Aug 31 17:26:59 2016 +0200
    18.3 @@ -5,6 +5,7 @@
    18.4  #include <unistd.h>
    18.5  #include <strings.h>
    18.6  #include <sys/select.h>
    18.7 +#include <regex.h>
    18.8  
    18.9  #ifdef __cplusplus
   18.10  extern "C" {
   18.11 @@ -43,6 +44,15 @@
   18.12  #if !defined(BSD) && !defined(__APPLE__)
   18.13  size_t strlcpy(char* dst, const	char* src, size_t size);
   18.14  size_t strlcat(char* dst, const	char* src, size_t size);
   18.15 +
   18.16 +// N.B. This is ifdef'd out because NDK users sometimes have trouble finding regex functions in
   18.17 +//      the library in spite of the inclusion of regex.h - this is a FIXME, but since iOS is
   18.18 +//      *currently* the only netpgp user, we will ifdef this so that we don't block Android.
   18.19 +#ifdef USE_NETPGP
   18.20 +int regnexec(const regex_t* preg, const char* string,
   18.21 +             size_t len, size_t nmatch, regmatch_t pmatch[], int eflags);
   18.22 +#endif
   18.23 +
   18.24  #endif
   18.25  
   18.26  #ifdef __cplusplus
    19.1 --- a/src/platform_windows.h	Tue Aug 02 12:55:50 2016 +0200
    19.2 +++ b/src/platform_windows.h	Wed Aug 31 17:26:59 2016 +0200
    19.3 @@ -25,9 +25,9 @@
    19.4  #define strdup(A) _strdup((A))
    19.5  #endif
    19.6  #ifndef snprintf
    19.7 -	#if _MSC_VER<1900 // Includes undefined case. This is a check for VS 2015, which throws an error.
    19.8 -	#define snprintf(...) _snprintf(__VA_ARGS__)
    19.9 -	#endif
   19.10 +#if _MSC_VER<1900 // Includes undefined case. This is a check for VS 2015, which throws an error.
   19.11 +#define snprintf(...) _snprintf(__VA_ARGS__)
   19.12 +#endif
   19.13  #endif
   19.14  #ifndef strtok_r
   19.15  #define strtok_r(A, B, C) strtok_s((A), (B), (C))
    20.1 --- a/test/pEpEngineTest.cc	Tue Aug 02 12:55:50 2016 +0200
    20.2 +++ b/test/pEpEngineTest.cc	Wed Aug 31 17:26:59 2016 +0200
    20.3 @@ -285,6 +285,8 @@
    20.4      assert(tcomm_type == PEP_ct_OpenPGP_unconfirmed);
    20.5      
    20.6      cout << "\ncalling release()\n";
    20.7 +    cout << endl << "End of pEpEngineTest for engine version " << get_engine_version() << endl;
    20.8 +
    20.9      release(session);
   20.10      return 0;
   20.11  }