1.1 --- a/src/pgp_netpgp.c Tue May 12 17:30:20 2015 +0200
1.2 +++ b/src/pgp_netpgp.c Tue May 12 17:30:58 2015 +0200
1.3 @@ -17,8 +17,6 @@
1.4 #include <pthread.h>
1.5 #include <regex.h>
1.6
1.7 -#define PEP_NETPGP_DEBUG
1.8 -
1.9 static netpgp_t netpgp;
1.10 static pthread_mutex_t netpgp_mutex;
1.11
1.12 @@ -231,21 +229,11 @@
1.13 now = time(NULL);
1.14 if (now < vresult->birthtime) {
1.15 // signature is not valid yet
1.16 -#ifdef PEP_NETPGP_DEBUG
1.17 - (void) printf(
1.18 - "signature not valid until %.24s\n",
1.19 - ctime(&vresult->birthtime));
1.20 -#endif //PEP_NETPGP_DEBUG
1.21 return PEP_UNENCRYPTED;
1.22 }
1.23 if (vresult->duration != 0 && now > vresult->birthtime + vresult->duration) {
1.24 // signature has expired
1.25 t = vresult->duration + vresult->birthtime;
1.26 -#ifdef PEP_NETPGP_DEBUG
1.27 - (void) printf(
1.28 - "signature not valid after %.24s\n",
1.29 - ctime(&t));
1.30 -#endif //PEP_NETPGP_DEBUG
1.31 return PEP_UNENCRYPTED;
1.32 }
1.33 if (vresult->validc && vresult->valid_sigs &&
1.34 @@ -263,16 +251,6 @@
1.35 char id[MAX_ID_LENGTH + 1];
1.36 const uint8_t *userid = vresult->valid_sigs[n].signer_id;
1.37
1.38 -#ifdef PEP_NETPGP_DEBUG
1.39 - const pgp_key_t *key;
1.40 - pgp_pubkey_t *sigkey;
1.41 - unsigned from = 0;
1.42 - key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
1.43 - (const uint8_t *) vresult->valid_sigs[n].signer_id,
1.44 - &from, &sigkey);
1.45 - pgp_print_keydata(netpgp->io, netpgp->pubring, key, "valid signature ", &key->key.pubkey, 0);
1.46 -#endif //PEP_NETPGP_DEBUG
1.47 -
1.48 id_to_str(userid, id);
1.49
1.50 k = stringlist_add(k, id);
1.51 @@ -290,23 +268,6 @@
1.52
1.53 if (vresult->invalidc) {
1.54 // some invalid signatures
1.55 -
1.56 -#ifdef PEP_NETPGP_DEBUG
1.57 - unsigned n;
1.58 - for (n = 0; n < vresult->invalidc; ++n) {
1.59 - const pgp_key_t *key;
1.60 - pgp_pubkey_t *sigkey;
1.61 - unsigned from = 0;
1.62 - key = pgp_getkeybyid(netpgp->io, netpgp->pubring,
1.63 - (const uint8_t *) vresult->invalid_sigs[n].signer_id,
1.64 - &from, &sigkey);
1.65 - pgp_print_keydata(netpgp->io, netpgp->pubring, key, "invalid signature ", &key->key.pubkey, 0);
1.66 - if (sigkey->duration != 0 && now > sigkey->birthtime + sigkey->duration) {
1.67 - printf("EXPIRED !\n");
1.68 - }
1.69 - }
1.70 -#endif //PEP_NETPGP_DEBUG
1.71 -
1.72 return PEP_DECRYPT_SIGNATURE_DOES_NOT_MATCH;
1.73 }
1.74
1.75 @@ -364,11 +325,12 @@
1.76
1.77 _psize = pgp_mem_len(mem);
1.78 if (_psize){
1.79 - if ((_ptext = calloc(1, _psize)) == NULL) {
1.80 + if ((_ptext = malloc(_psize + 1)) == NULL) {
1.81 result = PEP_OUT_OF_MEMORY;
1.82 goto free_pgp;
1.83 }
1.84 memcpy(_ptext, pgp_mem_data(mem), _psize);
1.85 + _ptext[_psize] = '\0'; // safeguard for naive users
1.86 result = PEP_DECRYPTED;
1.87 }else{
1.88 result = PEP_DECRYPT_NO_KEY;
1.89 @@ -577,10 +539,6 @@
1.90 result = PEP_KEY_NOT_FOUND;
1.91 goto free_rcpts;
1.92 }
1.93 -#ifdef PEP_NETPGP_DEBUG
1.94 - pgp_print_keydata(netpgp.io, netpgp.pubring, key,
1.95 - "recipient pubkey ", &key->key.pubkey, 0);
1.96 -#endif //PEP_NETPGP_DEBUG
1.97
1.98 // add key to recipients/signers
1.99 pgp_keyring_add(rcpts, key);
1.100 @@ -688,6 +646,9 @@
1.101 unsigned public;
1.102 PEP_STATUS result;
1.103
1.104 + /* XXX TODO : check key is valid */
1.105 + /* XXX TODO : replace/update key if already in ring */
1.106 +
1.107 if ((public = (newkey->type == PGP_PTAG_CT_PUBLIC_KEY))){
1.108 pubkey = *newkey;
1.109 } else {
1.110 @@ -858,8 +819,9 @@
1.111
1.112 pgp_memory_t *mem;
1.113 pgp_keyring_t tmpring;
1.114 + unsigned i = 0;
1.115
1.116 - PEP_STATUS result;
1.117 + PEP_STATUS result = PEP_STATUS_OK;
1.118
1.119 assert(session);
1.120 assert(key_data);
1.121 @@ -886,12 +848,8 @@
1.122 result = PEP_ILLEGAL_VALUE;
1.123 }else if (tmpring.keyc == 0){
1.124 result = PEP_UNKNOWN_ERROR;
1.125 - }else if (tmpring.keyc > 1){
1.126 - /* too many keys given */
1.127 - /* XXX TODO accept many */
1.128 - result = PEP_ILLEGAL_VALUE;
1.129 - }else{
1.130 - result = import_key_or_keypair(&netpgp, &tmpring.keys[0]);
1.131 + }else while(result == PEP_STATUS_OK && i < tmpring.keyc){
1.132 + result = import_key_or_keypair(&netpgp, &tmpring.keys[i++]);
1.133 }
1.134
1.135 pgp_memory_free(mem);
1.136 @@ -984,27 +942,104 @@
1.137 return result;
1.138 }
1.139
1.140 -// "keyserver"
1.141 -// "hkp://keys.gnupg.net"
1.142 +struct HKP_answer {
1.143 + char *memory;
1.144 + size_t size;
1.145 +};
1.146 +
1.147 +static size_t
1.148 +HKPAnswerWriter(void *contents, size_t size, size_t nmemb, void *userp)
1.149 +{
1.150 + size_t realsize = size * nmemb;
1.151 + struct HKP_answer *mem = (struct HKP_answer *)userp;
1.152 +
1.153 + mem->memory = realloc(mem->memory, mem->size + realsize + 1);
1.154 + if(mem->memory == NULL) {
1.155 + mem->size = 0;
1.156 + return 0;
1.157 + }
1.158 +
1.159 + memcpy(&(mem->memory[mem->size]), contents, realsize);
1.160 + mem->size += realsize;
1.161 + mem->memory[mem->size] = 0;
1.162 +
1.163 + return realsize;
1.164 +}
1.165 +
1.166 PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern)
1.167 {
1.168 + static const char *ks_cmd = "http://keys.gnupg.net:11371/pks/lookup?"
1.169 + "op=get&options=mr&exact=on&"
1.170 + "search=";
1.171 + char *encoded_pattern;
1.172 + char *request = NULL;
1.173 + struct HKP_answer answer;
1.174 + CURLcode curlres;
1.175 +
1.176 + PEP_STATUS result;
1.177 +
1.178 + CURL *curl;
1.179 +
1.180 assert(session);
1.181 assert(pattern);
1.182
1.183 - CURL *curl;
1.184 + if (!session || !pattern )
1.185 + return PEP_UNKNOWN_ERROR;
1.186 +
1.187 + if(pthread_mutex_lock(&session->ctx.curl_mutex)){
1.188 + return PEP_UNKNOWN_ERROR;
1.189 + }
1.190 +
1.191 curl = session->ctx.curl;
1.192
1.193 - /* TODO ask for key */
1.194 - return PEP_UNKNOWN_ERROR;
1.195 - return PEP_GET_KEY_FAILED;
1.196 + encoded_pattern = curl_easy_escape(curl, (char*)pattern, 0);
1.197 + if(!encoded_pattern){
1.198 + result = PEP_OUT_OF_MEMORY;
1.199 + goto unlock_curl;
1.200 + }
1.201 +
1.202 + if((request = malloc(strlen(ks_cmd) + strlen(encoded_pattern) + 1))==NULL){
1.203 + result = PEP_OUT_OF_MEMORY;
1.204 + goto free_encoded_pattern;
1.205 + }
1.206
1.207 - do {
1.208 + //(*stpcpy(stpcpy(request, ks_cmd), encoded_pattern)) = '\0';
1.209 + stpcpy(stpcpy(request, ks_cmd), encoded_pattern);
1.210 +
1.211 + curl_easy_setopt(curl, CURLOPT_URL,request);
1.212 +
1.213 + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HKPAnswerWriter);
1.214 +
1.215 + answer.memory = NULL;
1.216 + answer.size = 0;
1.217 + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&answer);
1.218
1.219 - /* For each key */
1.220 - /* import key */
1.221 - } while (0);
1.222 + curlres = curl_easy_perform(curl);
1.223 + if(curlres != CURLE_OK) {
1.224 + result = PEP_GET_KEY_FAILED;
1.225 + goto free_request;
1.226 + }
1.227 +
1.228 + if(!answer.memory || !answer.size) {
1.229 + result = PEP_OUT_OF_MEMORY;
1.230 + goto free_request;
1.231 + }
1.232
1.233 - return PEP_STATUS_OK;
1.234 + printf("request :\n %s\n\nanswer :\n%s\n", request, answer);
1.235 + result = pgp_import_keydata(session,
1.236 + answer.memory,
1.237 + answer.size);
1.238 +
1.239 +free_answer:
1.240 + free(answer.memory);
1.241 +free_request:
1.242 + free(request);
1.243 +free_encoded_pattern:
1.244 + curl_free(encoded_pattern);
1.245 +unlock_curl:
1.246 + pthread_mutex_unlock(&session->ctx.curl_mutex);
1.247 +
1.248 + return result;
1.249 }
1.250
1.251 PEP_STATUS add_key_fpr_to_stringlist(stringlist_t **keylist, pgp_key_t *key)
2.1 --- a/test/pEpEngineTest.cc Tue May 12 17:30:20 2015 +0200
2.2 +++ b/test/pEpEngineTest.cc Tue May 12 17:30:58 2015 +0200
2.3 @@ -233,6 +233,7 @@
2.4
2.5 cout << "searching for vb@ulm.ccc.de on keyserver\n";
2.6 PEP_STATUS recv_key_status = recv_key(session, "vb@ulm.ccc.de");
2.7 + cout << "recv_key() exits with " << recv_key_status << "\n";
2.8 assert(recv_key_status == PEP_STATUS_OK);
2.9
2.10 cout << "sending vb@ulm.ccc.de to keyserver\n";