netpgp : pEp session->ctx not anymore of type netpgp_t. netpgp_t instance is now static, protected by a single pthread_mutex. pEp session->ctx is now a struct containing per session resources such as curl handle.
authorEdouard Tisserant
Wed, 06 May 2015 12:05:48 +0200
changeset 252d0aa4a732456
parent 245 43b4cf6fe548
child 253 162d1a585cf8
netpgp : pEp session->ctx not anymore of type netpgp_t. netpgp_t instance is now static, protected by a single pthread_mutex. pEp session->ctx is now a struct containing per session resources such as curl handle.
src/pEp_internal.h
src/pgp_netpgp.c
src/pgp_netpgp_internal.h
     1.1 --- a/src/pEp_internal.h	Tue May 05 17:27:57 2015 +0200
     1.2 +++ b/src/pEp_internal.h	Wed May 06 12:05:48 2015 +0200
     1.3 @@ -67,7 +67,7 @@
     1.4  #ifdef USE_GPG
     1.5      gpgme_ctx_t ctx;
     1.6  #elif defined(USE_NETPGP)
     1.7 -    netpgp_t ctx;
     1.8 +    pEpNetPGPSession ctx;
     1.9  #endif
    1.10  
    1.11      PEP_cryptotech_t *cryptotech;
     2.1 --- a/src/pgp_netpgp.c	Tue May 05 17:27:57 2015 +0200
     2.2 +++ b/src/pgp_netpgp.c	Wed May 06 12:05:48 2015 +0200
     2.3 @@ -13,72 +13,99 @@
     2.4  #include <netpgp/validate.h>
     2.5  #include <netpgp/readerwriter.h>
     2.6  
     2.7 +#include <curl/curl.h>
     2.8 +#include <pthread.h>
     2.9  #include <regex.h>
    2.10  
    2.11  #define PEP_NETPGP_DEBUG
    2.12  
    2.13 +static netpgp_t netpgp;
    2.14 +static pthread_mutex_t netpgp_mutex = PTHREAD_MUTEX_INITIALIZER;
    2.15 +static pthread_mutex_t curl_mutex = PTHREAD_MUTEX_INITIALIZER;
    2.16 +
    2.17 +
    2.18 +
    2.19 +PEP_STATUS enter_curl(PEP_SESSION session, CURL **curl){
    2.20 +}
    2.21 +
    2.22  PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
    2.23  {
    2.24 -    netpgp_t *netpgp;
    2.25      PEP_STATUS status = PEP_STATUS_OK;
    2.26      const char *home = NULL;
    2.27  
    2.28      assert(session);
    2.29      if(!session) return PEP_UNKNOWN_ERROR;
    2.30  
    2.31 -    netpgp = &session->ctx;
    2.32 +    if(pthread_mutex_init(&netpgp_mutex, NULL)){
    2.33 +        return PEP_OUT_OF_MEMORY;
    2.34 +    }
    2.35 +
    2.36 +    if(pthread_mutex_lock(&netpgp_mutex)){;
    2.37 +        return PEP_UNKNOWN_ERROR;
    2.38 +    }
    2.39     
    2.40      if (in_first) {
    2.41          if (strcmp(setlocale(LC_ALL, NULL), "C") == 0)
    2.42              setlocale(LC_ALL, "");
    2.43 -    }
    2.44  
    2.45 -    memset(netpgp, 0x0, sizeof(session->ctx));
    2.46 +        memset(&netpgp, 0x0, sizeof(netpgp_t));
    2.47 +
    2.48  
    2.49 -    // netpgp_setvar(netpgp, "max mem alloc", "4194304");
    2.50 -    netpgp_setvar(netpgp, "need seckey", "1");
    2.51 -    netpgp_setvar(netpgp, "need userid", "1");
    2.52 +        // netpgp_setvar(&netpgp, "max mem alloc", "4194304");
    2.53 +        netpgp_setvar(&netpgp, "need seckey", "1");
    2.54 +        netpgp_setvar(&netpgp, "need userid", "1");
    2.55  
    2.56 -    // NetPGP shares home with GPG
    2.57 -    home = gpg_home();
    2.58 -    if(home){
    2.59 -        netpgp_set_homedir(netpgp,(char*)home, NULL, 0);
    2.60 -    }else{
    2.61 -        status = PEP_INIT_NO_GPG_HOME;
    2.62 -        goto pep_error;
    2.63 +        // NetPGP shares home with GPG
    2.64 +        home = gpg_home();
    2.65 +        if(home){
    2.66 +            netpgp_set_homedir(&netpgp,(char*)home, NULL, 0);
    2.67 +        }else{
    2.68 +            status = PEP_INIT_NO_GPG_HOME;
    2.69 +            goto unlock_netpgp;
    2.70 +        }
    2.71 +
    2.72 +        // pair with gpg's cert-digest-algo
    2.73 +        netpgp_setvar(&netpgp, "hash", "SHA256");
    2.74 +
    2.75 +        // subset of gpg's personal-cipher-preferences
    2.76 +        // here only one cipher can be selected
    2.77 +        netpgp_setvar(&netpgp, "cipher", "CAST5");
    2.78 +
    2.79 +        if (!netpgp_init(&netpgp)) {
    2.80 +            status = PEP_INIT_NETPGP_INIT_FAILED;
    2.81 +            goto unlock_netpgp;
    2.82 +        }
    2.83      }
    2.84  
    2.85 -    // pair with gpg's cert-digest-algo
    2.86 -    netpgp_setvar(netpgp, "hash", "SHA256");
    2.87 +    status = PEP_STATUS_OK;
    2.88  
    2.89 -    // subset of gpg's personal-cipher-preferences
    2.90 -    // here only one cipher can be selected
    2.91 -    netpgp_setvar(netpgp, "cipher", "CAST5");
    2.92 +unlock_netpgp:
    2.93 +    pthread_mutex_unlock(&netpgp_mutex);
    2.94  
    2.95 -    if (!netpgp_init(netpgp)) {
    2.96 -        status = PEP_INIT_NETPGP_INIT_FAILED;
    2.97 -        goto pep_error;
    2.98 +    if(status != PEP_STATUS_OK){
    2.99 +        pgp_release(session, in_first);
   2.100      }
   2.101  
   2.102 -    return PEP_STATUS_OK;
   2.103 -
   2.104 -pep_error:
   2.105 -    pgp_release(session, in_first);
   2.106      return status;
   2.107  }
   2.108  
   2.109  void pgp_release(PEP_SESSION session, bool out_last)
   2.110  {
   2.111 -    netpgp_t *netpgp;
   2.112 -
   2.113      assert(session);
   2.114      if(!session) return;
   2.115  
   2.116 -    netpgp = &session->ctx;
   2.117 +    if(pthread_mutex_lock(&netpgp_mutex)){;
   2.118 +        return;
   2.119 +    }
   2.120  
   2.121 -    netpgp_end(netpgp);
   2.122 -    memset(netpgp, 0x0, sizeof(session->ctx));
   2.123 +    if (out_last){
   2.124 +        netpgp_end(&netpgp);
   2.125 +        memset(&netpgp, 0x0, sizeof(netpgp_t));
   2.126 +        pthread_mutex_destroy(&netpgp_mutex);
   2.127 +        return;
   2.128 +    }
   2.129  
   2.130 +    pthread_mutex_unlock(&netpgp_mutex);
   2.131      // out_last unused here
   2.132  }
   2.133  
   2.134 @@ -214,7 +241,6 @@
   2.135      char **ptext, size_t *psize, stringlist_t **keylist
   2.136      )
   2.137  {
   2.138 -    netpgp_t *netpgp;
   2.139      pgp_memory_t *mem;
   2.140      pgp_memory_t *cat;
   2.141      pgp_validation_t *vresult;
   2.142 @@ -236,7 +262,9 @@
   2.143      if(!session || !ctext || !csize || !ptext || !psize || !keylist) 
   2.144          return PEP_UNKNOWN_ERROR;
   2.145  
   2.146 -    netpgp = &session->ctx;
   2.147 +    if(pthread_mutex_lock(&netpgp_mutex)){;
   2.148 +        return PEP_UNKNOWN_ERROR;
   2.149 +    }
   2.150  
   2.151      *ptext = NULL;
   2.152      *psize = 0;
   2.153 @@ -245,13 +273,14 @@
   2.154      vresult = malloc(sizeof(pgp_validation_t));
   2.155      memset(vresult, 0x0, sizeof(pgp_validation_t));
   2.156  
   2.157 -    mem = pgp_decrypt_and_validate_buf(netpgp->io, vresult, ctext, csize,
   2.158 -                netpgp->secring, netpgp->pubring,
   2.159 +    mem = pgp_decrypt_and_validate_buf(netpgp.io, vresult, ctext, csize,
   2.160 +                netpgp.secring, netpgp.pubring,
   2.161                  _armoured(ctext, csize, ARMOR_HEAD),
   2.162                  0 /* sshkeys */,
   2.163                  NULL, -1, NULL  /* pass fp,attempts,cb */);
   2.164      if (mem == NULL) {
   2.165 -        return PEP_OUT_OF_MEMORY;
   2.166 +        result = PEP_OUT_OF_MEMORY;
   2.167 +        goto unlock_netpgp;
   2.168      }
   2.169  
   2.170      _psize = pgp_mem_len(mem);
   2.171 @@ -268,7 +297,7 @@
   2.172      }
   2.173  
   2.174      if (result == PEP_DECRYPTED) {
   2.175 -        result = _validation_results(netpgp, vresult, &_keylist);
   2.176 +        result = _validation_results(&netpgp, vresult, &_keylist);
   2.177          if (result != PEP_STATUS_OK) {
   2.178              goto free_ptext;
   2.179          }
   2.180 @@ -298,6 +327,9 @@
   2.181      pgp_memory_free(mem);
   2.182      pgp_validate_result_free(vresult);
   2.183  
   2.184 +unlock_netpgp:
   2.185 +    pthread_mutex_unlock(&netpgp_mutex);
   2.186 +
   2.187      return result;
   2.188  }
   2.189  
   2.190 @@ -307,7 +339,6 @@
   2.191      const char *signature, size_t sig_size, stringlist_t **keylist
   2.192      )
   2.193  {
   2.194 -    netpgp_t *netpgp;
   2.195      pgp_memory_t *signedmem;
   2.196      pgp_memory_t *sig;
   2.197      pgp_validation_t *vresult;
   2.198 @@ -325,7 +356,9 @@
   2.199      if(!session || !text || !size || !signature || !sig_size || !keylist) 
   2.200          return PEP_UNKNOWN_ERROR;
   2.201  
   2.202 -    netpgp = &session->ctx;
   2.203 +    if(pthread_mutex_lock(&netpgp_mutex)){;
   2.204 +        return PEP_UNKNOWN_ERROR;
   2.205 +    }
   2.206  
   2.207      *keylist = NULL;
   2.208  
   2.209 @@ -334,24 +367,26 @@
   2.210  
   2.211      signedmem = pgp_memory_new();
   2.212      if (signedmem == NULL) {
   2.213 -        return PEP_OUT_OF_MEMORY;
   2.214 +        result = PEP_OUT_OF_MEMORY;
   2.215 +        goto unlock_netpgp;
   2.216      }
   2.217      pgp_memory_add(signedmem, (const uint8_t*)text, size);
   2.218  
   2.219      sig = pgp_memory_new();
   2.220      if (sig == NULL) {
   2.221          pgp_memory_free(signedmem);
   2.222 -        return PEP_OUT_OF_MEMORY;
   2.223 +        result = PEP_OUT_OF_MEMORY;
   2.224 +        goto unlock_netpgp;
   2.225      }
   2.226      pgp_memory_add(sig, (const uint8_t*)signature, sig_size);
   2.227  
   2.228 -    pgp_validate_mem_detached(netpgp->io, vresult, sig,
   2.229 +    pgp_validate_mem_detached(netpgp.io, vresult, sig,
   2.230                  NULL,/* output */
   2.231                  _armoured(signature, sig_size, ARMOR_SIG_HEAD),
   2.232 -                netpgp->pubring,
   2.233 +                netpgp.pubring,
   2.234                  signedmem);
   2.235  
   2.236 -    result = _validation_results(netpgp, vresult, &_keylist);
   2.237 +    result = _validation_results(&netpgp, vresult, &_keylist);
   2.238      if (result != PEP_STATUS_OK) {
   2.239          goto free_pgp;
   2.240      }else{
   2.241 @@ -379,6 +414,9 @@
   2.242      // pgp_memory_free(signedmem);
   2.243      pgp_validate_result_free(vresult);
   2.244  
   2.245 +unlock_netpgp:
   2.246 +    pthread_mutex_unlock(&netpgp_mutex);
   2.247 +
   2.248      return result;
   2.249  }
   2.250  
   2.251 @@ -387,7 +425,6 @@
   2.252      size_t psize, char **ctext, size_t *csize
   2.253      )
   2.254  {
   2.255 -    netpgp_t *netpgp;
   2.256      const pgp_key_t *keypair;
   2.257      pgp_seckey_t *seckey;
   2.258      pgp_memory_t *signedmem;
   2.259 @@ -409,26 +446,28 @@
   2.260      if(!session || !ptext || !psize || !ctext || !csize || !keylist) 
   2.261          return PEP_UNKNOWN_ERROR;
   2.262  
   2.263 -    netpgp = &session->ctx;
   2.264 +    if(pthread_mutex_lock(&netpgp_mutex)){;
   2.265 +        return PEP_UNKNOWN_ERROR;
   2.266 +    }
   2.267  
   2.268      *ctext = NULL;
   2.269      *csize = 0;
   2.270  
   2.271      // Get signing details from netpgp
   2.272 -    if ((userid = netpgp_getvar(netpgp, "userid")) == NULL || 
   2.273 -        (keypair = pgp_getkeybyname(netpgp->io, netpgp->secring, userid)) == NULL ||
   2.274 +    if ((userid = netpgp_getvar(&netpgp, "userid")) == NULL || 
   2.275 +        (keypair = pgp_getkeybyname(netpgp.io, netpgp.secring, userid)) == NULL ||
   2.276          (seckey = pgp_decrypt_seckey(keypair, NULL /*passfp*/)) == NULL) {
   2.277          return PEP_UNKNOWN_ERROR;
   2.278      }
   2.279  
   2.280 -    hashalg = netpgp_getvar(netpgp, "hash");
   2.281 +    hashalg = netpgp_getvar(&netpgp, "hash");
   2.282      // netpgp (l)imitation - XXX why ? 
   2.283      if (seckey->pubkey.alg == PGP_PKA_DSA) {
   2.284          hashalg = "sha1";
   2.285      }
   2.286  
   2.287      // Sign data
   2.288 -    signedmem = pgp_sign_buf(netpgp->io, ptext, psize, seckey,
   2.289 +    signedmem = pgp_sign_buf(netpgp.io, ptext, psize, seckey,
   2.290                  time(NULL), /* birthtime */
   2.291                  0 /* duration */,
   2.292                  hashalg, 
   2.293 @@ -438,7 +477,8 @@
   2.294      pgp_forget(seckey, (unsigned)sizeof(*seckey));
   2.295  
   2.296      if (!signedmem) {
   2.297 -        return PEP_UNENCRYPTED;
   2.298 +        result = PEP_UNENCRYPTED;
   2.299 +        goto unlock_netpgp;
   2.300      }
   2.301  
   2.302      // Encrypt signed data
   2.303 @@ -450,8 +490,8 @@
   2.304          assert(_keylist->value);
   2.305          // get key from netpgp's pubring
   2.306          const pgp_key_t *key;
   2.307 -        key = pgp_getkeybyname(netpgp->io,
   2.308 -                               netpgp->pubring,
   2.309 +        key = pgp_getkeybyname(netpgp.io,
   2.310 +                               netpgp.pubring,
   2.311                                 _keylist->value);
   2.312  
   2.313          if(key == NULL){
   2.314 @@ -459,7 +499,7 @@
   2.315              goto free_rcpts;
   2.316          }
   2.317  #ifdef PEP_NETPGP_DEBUG
   2.318 -        pgp_print_keydata(netpgp->io, netpgp->pubring, key,
   2.319 +        pgp_print_keydata(netpgp.io, netpgp.pubring, key,
   2.320                            "recipient pubkey ", &key->key.pubkey, 0);
   2.321  #endif //PEP_NETPGP_DEBUG
   2.322  
   2.323 @@ -471,9 +511,9 @@
   2.324          }
   2.325      }
   2.326  
   2.327 -    cmem = pgp_encrypt_buf(netpgp->io, pgp_mem_data(signedmem),
   2.328 +    cmem = pgp_encrypt_buf(netpgp.io, pgp_mem_data(signedmem),
   2.329              pgp_mem_len(signedmem), rcpts, 1 /* armored */,
   2.330 -            netpgp_getvar(netpgp, "cipher"), 
   2.331 +            netpgp_getvar(&netpgp, "cipher"), 
   2.332              1 /* takes raw OpenPGP message */);
   2.333  
   2.334      if (cmem == NULL) {
   2.335 @@ -506,6 +546,8 @@
   2.336      pgp_keyring_free(rcpts);
   2.337  free_signedmem :
   2.338      pgp_memory_free(signedmem);
   2.339 +unlock_netpgp:
   2.340 +    pthread_mutex_unlock(&netpgp_mutex);
   2.341  
   2.342      return result;
   2.343  }
   2.344 @@ -567,7 +609,6 @@
   2.345      unsigned public;
   2.346      PEP_STATUS result;
   2.347      
   2.348 -
   2.349      if ((public = (newkey->type == PGP_PTAG_CT_PUBLIC_KEY))){
   2.350          pubkey = *newkey;
   2.351      } else {
   2.352 @@ -578,7 +619,7 @@
   2.353          }
   2.354      }
   2.355  
   2.356 -    // Append generated key to netpgp's rings (key ownership transfered)
   2.357 +    // Append key to netpgp's rings (key ownership transfered)
   2.358      if (!public && !pgp_keyring_add(netpgp->secring, newkey)){
   2.359          result = PEP_OUT_OF_MEMORY;
   2.360          goto free_pubkey;
   2.361 @@ -614,7 +655,6 @@
   2.362      PEP_SESSION session, pEp_identity *identity
   2.363      )
   2.364  {
   2.365 -    netpgp_t *netpgp;
   2.366      pgp_key_t	newkey;
   2.367  
   2.368      PEP_STATUS result;
   2.369 @@ -633,15 +673,18 @@
   2.370         !identity->address || identity->fpr || !identity->username)
   2.371          return PEP_UNKNOWN_ERROR;
   2.372  
   2.373 -    netpgp = &session->ctx;
   2.374 +    if(pthread_mutex_lock(&netpgp_mutex)){;
   2.375 +        return PEP_UNKNOWN_ERROR;
   2.376 +    }
   2.377  
   2.378      if(snprintf(newid, sizeof(newid),
   2.379          "%s <%s>", identity->username, identity->address) >= sizeof(newid)){
   2.380 -        return PEP_BUFFER_TOO_SMALL;
   2.381 +        result =  PEP_BUFFER_TOO_SMALL;
   2.382 +        goto unlock_netpgp;
   2.383      }
   2.384      
   2.385 -    hashalg = netpgp_getvar(netpgp, "hash");
   2.386 -    cipher = netpgp_getvar(netpgp, "cipher");
   2.387 +    hashalg = netpgp_getvar(&netpgp, "hash");
   2.388 +    cipher = netpgp_getvar(&netpgp, "cipher");
   2.389  
   2.390      bzero(&newkey, sizeof(newkey));
   2.391  
   2.392 @@ -663,25 +706,27 @@
   2.393          goto free_newkey;
   2.394      } 
   2.395  
   2.396 -    result = import_key_or_keypair(netpgp, &newkey);
   2.397 +    result = import_key_or_keypair(&netpgp, &newkey);
   2.398  
   2.399      if (result == PEP_STATUS_OK) {
   2.400          identity->fpr = fprstr;
   2.401          /* free nothing, everything transfered */
   2.402 -        return PEP_STATUS_OK;
   2.403 +        result = PEP_STATUS_OK;
   2.404 +        goto unlock_netpgp;
   2.405      }
   2.406  
   2.407  free_fprstr:
   2.408      free(fprstr);
   2.409  free_newkey:
   2.410      pgp_key_free(&newkey);
   2.411 +unlock_netpgp:
   2.412 +    pthread_mutex_unlock(&netpgp_mutex);
   2.413  
   2.414      return result;
   2.415  }
   2.416  
   2.417  PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fprstr)
   2.418  {
   2.419 -    netpgp_t *netpgp;
   2.420      uint8_t fpr[PGP_FINGERPRINT_SIZE];
   2.421      size_t length;
   2.422      unsigned res;
   2.423 @@ -694,33 +739,40 @@
   2.424      if (!session || !fpr)
   2.425          return PEP_UNKNOWN_ERROR;
   2.426  
   2.427 -    netpgp = &session->ctx;
   2.428 +    if(pthread_mutex_lock(&netpgp_mutex)){;
   2.429 +        return PEP_UNKNOWN_ERROR;
   2.430 +    }
   2.431      
   2.432      if (str_to_fpr(fprstr, fpr, &length)) {
   2.433 -        unsigned insec = pgp_deletekeybyfpr(netpgp->io,
   2.434 -                                (pgp_keyring_t *)netpgp->secring, 
   2.435 +        unsigned insec = pgp_deletekeybyfpr(netpgp.io,
   2.436 +                                (pgp_keyring_t *)netpgp.secring, 
   2.437                                  (const uint8_t *)fpr, length);
   2.438 -        unsigned inpub = pgp_deletekeybyfpr(netpgp->io,
   2.439 -                                (pgp_keyring_t *)netpgp->pubring, 
   2.440 +        unsigned inpub = pgp_deletekeybyfpr(netpgp.io,
   2.441 +                                (pgp_keyring_t *)netpgp.pubring, 
   2.442                                  (const uint8_t *)fpr, length);
   2.443          if(!insec && !inpub){
   2.444              result = PEP_KEY_NOT_FOUND;
   2.445 +            goto unlock_netpgp;
   2.446          } else {
   2.447              result = PEP_STATUS_OK;
   2.448          }
   2.449      }else{
   2.450 -        return PEP_OUT_OF_MEMORY;
   2.451 +        result = PEP_OUT_OF_MEMORY;
   2.452 +        goto unlock_netpgp;
   2.453      }
   2.454  
   2.455      // save rings (key ownership transfered)
   2.456 -    if (netpgp_save_pubring(netpgp) && 
   2.457 -        netpgp_save_secring(netpgp))
   2.458 +    if (netpgp_save_pubring(&netpgp) && 
   2.459 +        netpgp_save_secring(&netpgp))
   2.460      {
   2.461          result = PEP_STATUS_OK;
   2.462      }else{
   2.463          result = PEP_UNKNOWN_ERROR;
   2.464      }
   2.465  
   2.466 +unlock_netpgp:
   2.467 +    pthread_mutex_unlock(&netpgp_mutex);
   2.468 +
   2.469      return result;
   2.470  }
   2.471  
   2.472 @@ -728,7 +780,6 @@
   2.473  PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data, size_t size)
   2.474  {
   2.475  
   2.476 -    netpgp_t *netpgp;
   2.477      pgp_memory_t *mem;
   2.478      pgp_keyring_t tmpring;
   2.479  
   2.480 @@ -740,17 +791,20 @@
   2.481      if(!session || !key_data) 
   2.482          return PEP_UNKNOWN_ERROR;
   2.483  
   2.484 -    netpgp = &session->ctx;
   2.485 +    if(pthread_mutex_lock(&netpgp_mutex)){;
   2.486 +        return PEP_UNKNOWN_ERROR;
   2.487 +    }
   2.488  
   2.489      mem = pgp_memory_new();
   2.490      if (mem == NULL) {
   2.491 -        return PEP_OUT_OF_MEMORY;
   2.492 +        result = PEP_OUT_OF_MEMORY;
   2.493 +        goto unlock_netpgp;
   2.494      }
   2.495      pgp_memory_add(mem, (const uint8_t*)key_data, size);
   2.496  
   2.497      bzero(&tmpring, sizeof(tmpring));
   2.498  
   2.499 -    if (pgp_keyring_read_from_mem(netpgp->io, &tmpring, 
   2.500 +    if (pgp_keyring_read_from_mem(netpgp.io, &tmpring, 
   2.501                                    _armoured(key_data, size, ARMOR_KEY_HEAD),
   2.502                                    mem) == 0){
   2.503          result = PEP_ILLEGAL_VALUE;
   2.504 @@ -758,9 +812,10 @@
   2.505          result = PEP_UNKNOWN_ERROR;
   2.506      }else if (tmpring.keyc > 1){
   2.507          /* too many keys given */
   2.508 +        /* XXX TODO accept many */
   2.509          result = PEP_ILLEGAL_VALUE;
   2.510      }else{
   2.511 -        result = import_key_or_keypair(netpgp, &tmpring.keys[0]);
   2.512 +        result = import_key_or_keypair(&netpgp, &tmpring.keys[0]);
   2.513      }
   2.514      
   2.515      pgp_memory_free(mem);
   2.516 @@ -771,6 +826,9 @@
   2.517          pgp_keyring_purge(&tmpring);
   2.518      }
   2.519  
   2.520 +unlock_netpgp:
   2.521 +    pthread_mutex_unlock(&netpgp_mutex);
   2.522 +
   2.523      return result;
   2.524  }
   2.525  
   2.526 @@ -778,7 +836,6 @@
   2.527      PEP_SESSION session, const char *fprstr, char **key_data, size_t *size
   2.528      )
   2.529  {
   2.530 -    netpgp_t *netpgp;
   2.531      pgp_key_t *key;
   2.532  	pgp_output_t *output;
   2.533      pgp_memory_t *mem;
   2.534 @@ -794,26 +851,31 @@
   2.535      assert(key_data);
   2.536      assert(size);
   2.537  
   2.538 -    netpgp = &session->ctx;
   2.539 -
   2.540      if (!session || !fprstr || !key_data || !size)
   2.541          return PEP_UNKNOWN_ERROR;
   2.542  
   2.543 +    if(pthread_mutex_lock(&netpgp_mutex)){;
   2.544 +        return PEP_UNKNOWN_ERROR;
   2.545 +    }
   2.546 +
   2.547      if (str_to_fpr(fprstr, fpr, &fprlen)) {
   2.548          unsigned from = 0;
   2.549 -        if ((key = (pgp_key_t *)pgp_getkeybyfpr(netpgp->io, netpgp->pubring, 
   2.550 +        if ((key = (pgp_key_t *)pgp_getkeybyfpr(netpgp.io, netpgp.pubring, 
   2.551                                                  fpr, fprlen,
   2.552                                                  &from, NULL)) == NULL) {
   2.553 -            return PEP_KEY_NOT_FOUND;
   2.554 +            result = PEP_KEY_NOT_FOUND;
   2.555 +            goto unlock_netpgp;
   2.556          }
   2.557      }else{
   2.558 -        return PEP_OUT_OF_MEMORY;
   2.559 +        result = PEP_OUT_OF_MEMORY;
   2.560 +        goto unlock_netpgp;
   2.561      }
   2.562      
   2.563  	pgp_setup_memory_write(&output, &mem, 128);
   2.564  
   2.565      if (mem == NULL || output == NULL) {
   2.566 -        return PEP_OUT_OF_MEMORY;
   2.567 +        result = PEP_OUT_OF_MEMORY;
   2.568 +        goto unlock_netpgp;
   2.569      }
   2.570  
   2.571      if (!pgp_write_xfer_pubkey(output, key, 1)) {
   2.572 @@ -841,6 +903,8 @@
   2.573  
   2.574  free_mem :
   2.575  	pgp_teardown_memory_write(output, mem);
   2.576 +unlock_netpgp:
   2.577 +    pthread_mutex_unlock(&netpgp_mutex);
   2.578  
   2.579      return result;
   2.580  }
   2.581 @@ -852,6 +916,9 @@
   2.582      assert(session);
   2.583      assert(pattern);
   2.584  
   2.585 +    CURL *curl;
   2.586 +    curl = session->ctx.curl;
   2.587 +
   2.588      /* TODO ask for key */
   2.589          return PEP_UNKNOWN_ERROR;
   2.590          return PEP_GET_KEY_FAILED;
     3.1 --- a/src/pgp_netpgp_internal.h	Tue May 05 17:27:57 2015 +0200
     3.2 +++ b/src/pgp_netpgp_internal.h	Wed May 06 12:05:48 2015 +0200
     3.3 @@ -1,3 +1,7 @@
     3.4  #pragma once
     3.5  
     3.6 -#include <netpgp.h>
     3.7 +#include <curl/curl.h>
     3.8 +
     3.9 +typedef struct _pEpNetPGPSession {
    3.10 +    CURL *curl;
    3.11 +} pEpNetPGPSession;