ENGINE-73 added openpgp compat files for listing keyinfo #comment Redesign: function is now OpenPGP_list_keyinfo() in openpgp_compat.c/.h, returns full pgp key fingerprint + primary gpg uid string (Real Name <email@address.blah>) ENGINE-73
authorKrista Grothoff <krista@pep-project.org>
Thu, 18 Aug 2016 13:23:15 +0200
branchENGINE-73
changeset 10304354451338cd
parent 1029 5b6af5b14d3a
child 1031 ed718acfd6fe
ENGINE-73 added openpgp compat files for listing keyinfo #comment Redesign: function is now OpenPGP_list_keyinfo() in openpgp_compat.c/.h, returns full pgp key fingerprint + primary gpg uid string (Real Name <email@address.blah>)
src/cryptotech.c
src/cryptotech.h
src/openpgp_compat.c
src/openpgp_compat.h
src/pEpEngine.c
src/pEpEngine.h
src/pgp_gpg.h
src/pgp_netpgp.c
src/pgp_netpgp.h
     1.1 --- a/src/cryptotech.c	Wed Aug 17 12:27:44 2016 +0200
     1.2 +++ b/src/cryptotech.c	Thu Aug 18 13:23:15 2016 +0200
     1.3 @@ -46,7 +46,6 @@
     1.4          cryptotech[PEP_crypt_OpenPGP].revoke_key = pgp_revoke_key;
     1.5          cryptotech[PEP_crypt_OpenPGP].key_expired = pgp_key_expired;
     1.6          cryptotech[PEP_crypt_OpenPGP].key_revoked = pgp_key_revoked;
     1.7 -        cryptotech[PEP_crypt_OpenPGP].list_keys = pgp_list_keys;
     1.8  #ifdef PGP_BINARY_PATH
     1.9          cryptotech[PEP_crypt_OpenPGP].binary_path = PGP_BINARY_PATH;
    1.10  #endif
     2.1 --- a/src/cryptotech.h	Wed Aug 17 12:27:44 2016 +0200
     2.2 +++ b/src/cryptotech.h	Thu Aug 18 13:23:15 2016 +0200
     2.3 @@ -68,9 +68,6 @@
     2.4  
     2.5  typedef PEP_STATUS (*binary_path_t)(const char **path);
     2.6  
     2.7 -typedef PEP_STATUS (*list_keys_t)(PEP_SESSION session, 
     2.8 -                                             identity_list** id_list);
     2.9 -
    2.10  typedef struct _PEP_cryptotech_t {
    2.11      uint8_t id;
    2.12      // the following are default values; comm_type may vary with key length or b0rken crypto
    2.13 @@ -92,7 +89,6 @@
    2.14      key_expired_t key_expired;
    2.15      key_revoked_t key_revoked;
    2.16      binary_path_t binary_path;
    2.17 -    list_keys_t list_keys;
    2.18  } PEP_cryptotech_t;
    2.19  
    2.20  extern PEP_cryptotech_t cryptotech[PEP_crypt__count];
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/openpgp_compat.c	Thu Aug 18 13:23:15 2016 +0200
     3.3 @@ -0,0 +1,23 @@
     3.4 +#include "pEp_internal.h"
     3.5 +#include "dynamic_api.h"
     3.6 +#include "openpgp_compat.h"
     3.7 +
     3.8 +DYNAMIC_API PEP_STATUS OpenPGP_list_keyinfo (
     3.9 +        PEP_SESSION session, stringpair_list_t** keyinfo_list, char* search_pattern
    3.10 +    );
    3.11 +{
    3.12 +    assert(session);
    3.13 +    assert(keyinfo_list);
    3.14 +
    3.15 +    if (!(session && keyinfo_list))
    3.16 +        return PEP_ILLEGAL_VALUE;
    3.17 +
    3.18 +    stringpair_list_t* _keyinfo_list = NULL;
    3.19 +    
    3.20 +    PEP_STATUS retval = pgp_list_keyinfo(session, _keyinfo_list, search_pattern);
    3.21 +        
    3.22 +    if (retval == PEP_STATUS_OK)
    3.23 +        *keyinfo_list = _keyinfo_list;
    3.24 +    
    3.25 +    return retval;
    3.26 +}
    3.27 \ No newline at end of file
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/openpgp_compat.h	Thu Aug 18 13:23:15 2016 +0200
     4.3 @@ -0,0 +1,47 @@
     4.4 +// openpgp_compat.h
     4.5 +//
     4.6 +// These functions are the exposure of non-generic PGP-specific functionality (largely related to PGP
     4.7 +// keyrings) to adapters that need them without polluting the engine interface.
     4.8 +//
     4.9 +#pragma once
    4.10 +
    4.11 +#ifdef __cplusplus
    4.12 +extern "C" {
    4.13 +#endif
    4.14 +
    4.15 +#include <stddef.h>
    4.16 +#include <stdint.h>
    4.17 +#include <stdbool.h>
    4.18 +    
    4.19 +#include "dynamic_api.h"
    4.20 +#include "stringpair.h"    
    4.21 +
    4.22 +#ifdef USE_GPG
    4.23 +#include "pgp_gpg.h"
    4.24 +#else
    4.25 +#ifdef USE_NETPGP
    4.26 +#include "pgp_netpgp.h"
    4.27 +#endif
    4.28 +#endif    
    4.29 +    
    4.30 +//  OpenPGP_list_keyinfo() - get a key/UID list for pattern matches in keyring (NULL
    4.31 +//                           to return entire keyring)
    4.32 +//
    4.33 +//  parameters:
    4.34 +//      session (in)          session handle
    4.35 +//      show_revoked (in)     true if identities with revoked primary keys should also
    4.36 +//                            be listed; false if only valid keys should be shown
    4.37 +//      keyinfo_list (out)    list of identities for each available key 
    4.38 +//
    4.39 +//  caveat: FIXME
    4.40 +//        the ownership of the identity list goes to the caller
    4.41 +//        the caller must use free_identity_list() to free it
    4.42 +//        identity objects derived from the keyring only have the available information
    4.43 +//           from the keyring; some fields may be NULL
    4.44 +DYNAMIC_API PEP_STATUS OpenPGP_list_keyinfo (
    4.45 +        PEP_SESSION session, stringpair_list_t** keyinfo_list, char* search_pattern
    4.46 +    );
    4.47 +    
    4.48 +#ifdef __cplusplus
    4.49 +}
    4.50 +#endif
    4.51 \ No newline at end of file
     5.1 --- a/src/pEpEngine.c	Wed Aug 17 12:27:44 2016 +0200
     5.2 +++ b/src/pEpEngine.c	Thu Aug 18 13:23:15 2016 +0200
     5.3 @@ -56,6 +56,9 @@
     5.4      static const char *sql_set_revoked;
     5.5      static const char *sql_get_revoked;
     5.6      
     5.7 +    // Get full list of keys in database
     5.8 +    static const char *sql_get_keylist;
     5.9 +    
    5.10      bool in_first = false;
    5.11  
    5.12      assert(sqlite3_threadsafe());
    5.13 @@ -363,6 +366,8 @@
    5.14          
    5.15          sql_get_revoked =     "select revoked_fpr, revocation_date from revoked_keys"
    5.16                                "    where replacement_fpr = upper(replace(?1,' ','')) ;";
    5.17 +        
    5.18 +        sql_get_keylist =     "
    5.19      }
    5.20  
    5.21      int_result = sqlite3_prepare_v2(_session->db, sql_log, (int)strlen(sql_log),
    5.22 @@ -1234,35 +1239,6 @@
    5.23      return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern, keylist);
    5.24  }
    5.25  
    5.26 -DYNAMIC_API PEP_STATUS list_keys(
    5.27 -        PEP_SESSION session, identity_list** id_list, bool db_only, bool show_revoked
    5.28 -    )
    5.29 -{
    5.30 -    assert(session);
    5.31 -    assert(id_list);
    5.32 -
    5.33 -    if (!(session && id_list))
    5.34 -        return PEP_ILLEGAL_VALUE;
    5.35 -
    5.36 -    identity_list* _id_list = new_identity_list(NULL);
    5.37 -    
    5.38 -    PEP_STATUS retval = PEP_KEY_NOT_FOUND;
    5.39 -    
    5.40 -    // FIXME: do management DB stuff here
    5.41 -    
    5.42 -    identity_list* _keyring_ids = NULL;
    5.43 -    if (!db_only) {
    5.44 -        PEP_STATUS extra_status = session->cryptotech[PEP_crypt_OpenPGP].list_keys(session, _keyring_ids);
    5.45 -    }
    5.46 -        
    5.47 -    // FIXME: Combine lists here
    5.48 -    if (_keyring_ids) {
    5.49 -    }
    5.50 -    
    5.51 -    if (retval == PEP_STATUS_OK)
    5.52 -        *id_list = _id_list;
    5.53 -    return retval;
    5.54 -}
    5.55  
    5.56  DYNAMIC_API PEP_STATUS generate_keypair(
    5.57          PEP_SESSION session, pEp_identity *identity
     6.1 --- a/src/pEpEngine.h	Wed Aug 17 12:27:44 2016 +0200
     6.2 +++ b/src/pEpEngine.h	Thu Aug 18 13:23:15 2016 +0200
     6.3 @@ -645,27 +645,6 @@
     6.4          PEP_SESSION session, const char *pattern, stringlist_t **keylist
     6.5      );
     6.6  
     6.7 -
     6.8 -// list_keys() - return identities for all keys in the database (and, optionally, keyring)
     6.9 -//
    6.10 -//  parameters:
    6.11 -//      session (in)          session handle
    6.12 -//      db_only (in)          true if only identities for the pEp management database
    6.13 -//                            should be listed; false if identities should also be
    6.14 -//                            shown from the keyring
    6.15 -//      show_revoked (in)     true if identities with revoked primary keys should also
    6.16 -//                            be listed; false if only valid keys should be shown
    6.17 -//      id_list (out)         list of identities for each available key 
    6.18 -//
    6.19 -//  caveat: FIXME
    6.20 -//        the ownership of the identity list goes to the caller
    6.21 -//        the caller must use free_identity_list() to free it
    6.22 -//        identity objects derived from the keyring only have the available information
    6.23 -//           from the keyring; some fields may be NULL
    6.24 -DYNAMIC_API PEP_STATUS list_keys(
    6.25 -        PEP_SESSION session, identity_list** id_list, bool db_only, bool show_revoked
    6.26 -    );
    6.27 -
    6.28  // send_key() - send key(s) to keyserver
    6.29  //
    6.30  //  parameters:
     7.1 --- a/src/pgp_gpg.h	Wed Aug 17 12:27:44 2016 +0200
     7.2 +++ b/src/pgp_gpg.h	Thu Aug 18 13:23:15 2016 +0200
     7.3 @@ -26,14 +26,14 @@
     7.4          PEP_SESSION session, const char *fpr, char **key_data, size_t *size
     7.5      );
     7.6  
     7.7 -PEP_STATUS pgp_list_keys(
     7.8 -    PEP_SESSION session, identity_list** id_list
     7.9 -    );
    7.10 -    
    7.11  PEP_STATUS pgp_find_keys(
    7.12          PEP_SESSION session, const char *pattern, stringlist_t **keylist
    7.13      );
    7.14  
    7.15 +PEP_STATUS pgp_list_keyinfo(
    7.16 +    PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list
    7.17 +    );
    7.18 +
    7.19  PEP_STATUS pgp_generate_keypair(
    7.20          PEP_SESSION session, pEp_identity *identity
    7.21      );
     8.1 --- a/src/pgp_netpgp.c	Wed Aug 17 12:27:44 2016 +0200
     8.2 +++ b/src/pgp_netpgp.c	Thu Aug 18 13:23:15 2016 +0200
     8.3 @@ -1651,81 +1651,87 @@
     8.4  // 
     8.5  // Our best guess is that this is structured as "REALNAME <blah@blah.blah>"
     8.6  //
     8.7 -static void parse_netpgp_uid_str(char* src, char** name, char** email) {
     8.8 -    *name = NULL;
     8.9 -    *email = NULL;
    8.10 -        
    8.11 -    if (!src)
    8.12 -        return;
    8.13 - 
    8.14 -    size_t source_len = strlen(src);
    8.15 -    char* last_char = src + source_len;
    8.16 +// static void parse_netpgp_uid_str(char* src, char** name, char** email) {
    8.17 +//     *name = NULL;
    8.18 +//     *email = NULL;
    8.19 +//         
    8.20 +//     if (!src)
    8.21 +//         return;
    8.22 +//  
    8.23 +//     size_t source_len = strlen(src);
    8.24 +//     char* last_char = src + source_len;
    8.25 +//     
    8.26 +//     char* at = NULL;
    8.27 +// 
    8.28 +//     char* begin = src;
    8.29 +//     char* end = last_char; // one past the end;
    8.30 +//     size_t copy_len = 0;
    8.31 +//     
    8.32 +//     // Primitive email extraction
    8.33 +//     at = strrchr(src,'@');
    8.34 +//     
    8.35 +//     char* name_str = NULL;
    8.36 +//     char* email_str = NULL;
    8.37 +//     
    8.38 +//     if (at) {
    8.39 +//         // Go back until we hit a space, a '<', or the start of the string
    8.40 +//         for (begin = at; begin >= src && *begin != ' ' && *begin != '<'; begin--) {
    8.41 +//             continue;
    8.42 +//         }
    8.43 +//         if (begin != at)
    8.44 +//             begin++; // Ugly
    8.45 +//         else {
    8.46 +//             for (end = at; end < last_char && *end != ' ' && *end != '>'; end++) {
    8.47 +//                 continue;
    8.48 +//             }
    8.49 +//             // Points one char past.
    8.50 +//         }
    8.51 +//         if (begin < at && end > at) {
    8.52 +//             // yay, it's an email address!
    8.53 +//             copy_len = end - begin - 1;
    8.54 +//             email_str = (char*)malloc(sizeof(char) * (copy_len + 1));
    8.55 +//             strncpy(email_str, begin, copy_len);
    8.56 +//             email_str[copy_len] = '\0';
    8.57 +//             begin--; // put the beginning back where it was.
    8.58 +//             end = (*begin == '<' ? begin : begin + 1); // if this precedes src, it is checked below
    8.59 +//             begin = src;
    8.60 +//         }
    8.61 +//         else {
    8.62 +//             // bail
    8.63 +//             begin = src;
    8.64 +//             end = last_char;
    8.65 +//         }
    8.66 +//     }
    8.67 +//     if (begin < end) {
    8.68 +//         copy_len = end - begin;
    8.69 +//         name_str = (char*)malloc(sizeof(char) * (copy_len + 1));
    8.70 +//         strncpy(name_str, begin, copy_len);
    8.71 +//         name_str[copy_len] = '\0';
    8.72 +//     }
    8.73 +//     *email = email_str;
    8.74 +//     *name = name_str;
    8.75 +// }
    8.76 +
    8.77 +PEP_STATUS pgp_list_keyinfo(
    8.78 +        PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list)
    8.79 +{
    8.80      
    8.81 -    char* at = NULL;
    8.82 -
    8.83 -    char* begin = src;
    8.84 -    char* end = last_char; // one past the end;
    8.85 -    size_t copy_len = 0;
    8.86 +    if (!session || !keyinfo_list)
    8.87 +        return PEP_UNKNOWN_ERROR;
    8.88      
    8.89 -    // Primitive email extraction
    8.90 -    at = strrchr(src,'@');
    8.91 -    
    8.92 -    char* name_str = NULL;
    8.93 -    char* email_str = NULL;
    8.94 -    
    8.95 -    if (at) {
    8.96 -        // Go back until we hit a space, a '<', or the start of the string
    8.97 -        for (begin = at; begin >= src && *begin != ' ' && *begin != '<'; begin--) {
    8.98 -            continue;
    8.99 -        }
   8.100 -        if (begin != at)
   8.101 -            begin++; // Ugly
   8.102 -        else {
   8.103 -            for (end = at; end < last_char && *end != ' ' && *end != '>'; end++) {
   8.104 -                continue;
   8.105 -            }
   8.106 -            // Points one char past.
   8.107 -        }
   8.108 -        if (begin < at && end > at) {
   8.109 -            // yay, it's an email address!
   8.110 -            copy_len = end - begin - 1;
   8.111 -            email_str = (char*)malloc(sizeof(char) * (copy_len + 1));
   8.112 -            strncpy(email_str, begin, copy_len);
   8.113 -            email_str[copy_len] = '\0';
   8.114 -            begin--; // put the beginning back where it was.
   8.115 -            end = (*begin == '<' ? begin : begin + 1); // if this precedes src, it is checked below
   8.116 -            begin = src;
   8.117 -        }
   8.118 -        else {
   8.119 -            // bail
   8.120 -            begin = src;
   8.121 -            end = last_char;
   8.122 -        }
   8.123 +    if (pthread_mutex_lock(&netpgp_mutex))
   8.124 +    {
   8.125 +        return PEP_UNKNOWN_ERROR;
   8.126      }
   8.127 -    if (begin < end) {
   8.128 -        copy_len = end - begin;
   8.129 -        name_str = (char*)malloc(sizeof(char) * (copy_len + 1));
   8.130 -        strncpy(name_str, begin, copy_len);
   8.131 -        name_str[copy_len] = '\0';
   8.132 -    }
   8.133 -    *email = email_str;
   8.134 -    *name = name_str;
   8.135 -}
   8.136 -
   8.137 -PEP_STATUS pgp_list_keys(
   8.138 -        PEP_SESSION session, 
   8.139 -        identity_list** id_list)
   8.140 -{
   8.141      
   8.142      pgp_key_t *key;
   8.143  
   8.144      PEP_STATUS result;
   8.145  
   8.146 -    unsigned from = 0;
   8.147      result = PEP_KEY_NOT_FOUND;
   8.148      
   8.149      // get all available keys
   8.150 -    unsigned n = 0; // type from netpgp...
   8.151 +    unsigned n = 0;
   8.152      
   8.153      pgp_keyring_t* pubkeys = (pgp_keyring_t *)netpgp.pubring; 
   8.154      int keyring_end = pubkeys->keyc;
   8.155 @@ -1733,31 +1739,29 @@
   8.156      if (keyring_end < 1)
   8.157          return result;
   8.158      
   8.159 -    identity_list* _retval = new_identity_list(NULL);
   8.160 +    stringpair_list_t* _retval = new_stringpair_list(NULL);
   8.161      
   8.162      for (key = pubkeys->keys; n < keyring_end; ++n, ++key) {
   8.163          assert(key);
   8.164          if (!key)
   8.165              continue;
   8.166          char* primary_userid = (char*)pgp_key_get_primary_userid(key);
   8.167 -        // FIXME: For now, we just presume it's name + email address. Let's see what it really is.
   8.168 -        char* username = NULL;
   8.169 -        char* usermail = NULL;
   8.170 -        parse_netpgp_uid_str(primary_userid, &username, &usermail);
   8.171 +//        parse_netpgp_uid_str(primary_userid, &username, &usermail);
   8.172       
   8.173          char* id_fpr = NULL;
   8.174          
   8.175          fpr_to_str(&id_fpr, key->pubkeyfpr.fingerprint,
   8.176                     key->pubkeyfpr.length);
   8.177  
   8.178 -        identity_list_add(_retval, new_identity(usermail, id_fpr, primary_userid,
   8.179 -                                                username));
   8.180 -        free(username);
   8.181 -        free(usermail);
   8.182 +        stringlist_add(_retval, new_stringpair(id_fpr, primary_userid));
   8.183          free(id_fpr);
   8.184          result = PEP_STATUS_OK;
   8.185      }
   8.186      *id_list = _retval;
   8.187 +    
   8.188 +unlock_netpgp:
   8.189 +    pthread_mutex_unlock(&netpgp_mutex);
   8.190 +    
   8.191      return result;
   8.192  }
   8.193  
     9.1 --- a/src/pgp_netpgp.h	Wed Aug 17 12:27:44 2016 +0200
     9.2 +++ b/src/pgp_netpgp.h	Thu Aug 18 13:23:15 2016 +0200
     9.3 @@ -30,8 +30,8 @@
     9.4          PEP_SESSION session, const char *pattern, stringlist_t **keylist
     9.5      );
     9.6  
     9.7 -PEP_STATUS pgp_list_keys(
     9.8 -    PEP_SESSION session, identity_list** id_list
     9.9 +PEP_STATUS pgp_list_keyinfo(
    9.10 +    PEP_SESSION session, const char* pattern, stringpair_list_t** keyinfo_list,
    9.11      );
    9.12  
    9.13  PEP_STATUS pgp_generate_keypair(