1.1 --- a/src/pgp_netpgp.c Tue Apr 28 01:52:09 2015 +0200
1.2 +++ b/src/pgp_netpgp.c Wed Apr 29 01:00:59 2015 +0200
1.3 @@ -11,6 +11,7 @@
1.4 #include <netpgp/crypto.h>
1.5 #include <netpgp/netpgpsdk.h>
1.6 #include <netpgp/validate.h>
1.7 +#include <netpgp/readerwriter.h>
1.8
1.9 #include <regex.h>
1.10
1.11 @@ -482,7 +483,6 @@
1.12
1.13 char *_buffer = NULL;
1.14 size_t length = pgp_mem_len(cmem);
1.15 - assert(length != -1);
1.16
1.17 // Allocate transferable buffer
1.18 _buffer = malloc(length + 1);
1.19 @@ -514,8 +514,8 @@
1.20 static unsigned
1.21 fpr_to_str (char **str, const uint8_t *fpr, size_t length)
1.22 {
1.23 - unsigned i;
1.24 - int n;
1.25 + unsigned i;
1.26 + int n;
1.27
1.28 /* 5 char per byte (hexes + space) tuple -1 space at the end + null */
1.29 *str = malloc((length / 2) * 5 - 1 + 1);
1.30 @@ -523,12 +523,12 @@
1.31 if(*str == NULL)
1.32 return 0;
1.33
1.34 - for (n = 0, i = 0 ; i < length - 1; i += 2) {
1.35 - n += snprintf(&((*str)[n]), 6, "%02x%02x ", *fpr++, *fpr++);
1.36 - }
1.37 + for (n = 0, i = 0 ; i < length - 1; i += 2) {
1.38 + n += snprintf(&((*str)[n]), 6, "%02x%02x ", *fpr++, *fpr++);
1.39 + }
1.40 snprintf(&((*str)[n]), 5, "%02x%02x", *fpr++, *fpr++);
1.41
1.42 - return 1;
1.43 + return 1;
1.44 }
1.45
1.46 static unsigned
1.47 @@ -561,18 +561,65 @@
1.48 return 1;
1.49 }
1.50
1.51 +static PEP_STATUS import_key_or_keypair(netpgp_t *netpgp, pgp_key_t *newkey){
1.52 + pgp_key_t pubkey;
1.53 + unsigned public;
1.54 + PEP_STATUS result;
1.55 +
1.56 + if ((public = (newkey->type == PGP_PTAG_CT_PUBLIC_KEY))){
1.57 + pubkey = *newkey;
1.58 + } else {
1.59 + // Duplicate key as public only
1.60 + if (!pgp_keydata_dup(&pubkey, newkey, 1 /* make_public */)){
1.61 + return PEP_OUT_OF_MEMORY;
1.62 + }
1.63 + }
1.64 +
1.65 + // Append generated key to netpgp's rings (key ownership transfered)
1.66 + if (!public && !pgp_keyring_add(netpgp->secring, newkey)){
1.67 + result = PEP_OUT_OF_MEMORY;
1.68 + goto free_pubkey;
1.69 + } else if (!pgp_keyring_add(netpgp->pubring, &pubkey)){
1.70 + result = PEP_OUT_OF_MEMORY;
1.71 + goto pop_secring;
1.72 + }
1.73 +
1.74 + // save rings
1.75 + if (netpgp_save_pubring(netpgp) &&
1.76 + (!public || netpgp_save_secring(netpgp)))
1.77 + {
1.78 + /* free nothing, everything transfered */
1.79 + return PEP_STATUS_OK;
1.80 + } else {
1.81 + /* XXX in case only pubring save succeed
1.82 + * pubring file is left as-is, but backup restore
1.83 + * could be attempted if such corner case matters */
1.84 + result = PEP_UNKNOWN_ERROR;
1.85 + }
1.86 +
1.87 +pop_pubring:
1.88 + ((pgp_keyring_t *)netpgp->pubring)->keyc--;
1.89 +pop_secring:
1.90 + ((pgp_keyring_t *)netpgp->secring)->keyc--;
1.91 +free_pubkey:
1.92 + pgp_key_free(&pubkey);
1.93 +
1.94 + return result;
1.95 +}
1.96 +
1.97 PEP_STATUS pgp_generate_keypair(
1.98 PEP_SESSION session, pEp_identity *identity
1.99 )
1.100 {
1.101 netpgp_t *netpgp;
1.102 - pgp_key_t newkey;
1.103 - pgp_key_t pubkey;
1.104 + pgp_key_t newkey;
1.105 + pgp_key_t pubkey;
1.106
1.107 PEP_STATUS result;
1.108 - char newid[1024];
1.109 + char newid[1024];
1.110 const char *hashalg;
1.111 const char *cipher;
1.112 + char *fprstr = NULL;
1.113
1.114 assert(session);
1.115 assert(identity);
1.116 @@ -600,38 +647,34 @@
1.117 // Generate the key
1.118 if (!pgp_rsa_generate_keypair(&newkey, 4096, 65537UL, hashalg, cipher,
1.119 (const uint8_t *) "", (const size_t) 0) ||
1.120 - !pgp_add_selfsigned_userid(&newkey, (const uint8_t *)newid)) {
1.121 - return PEP_CANNOT_CREATE_KEY;
1.122 - }
1.123 + !pgp_add_selfsigned_userid(&newkey, (uint8_t *)newid)) {
1.124 + result = PEP_CANNOT_CREATE_KEY;
1.125 + goto free_newkey;
1.126 + }
1.127
1.128 // TODO "Expire-Date: 1y\n";
1.129
1.130 - // Duplicate key as public only
1.131 - pgp_keydata_dup(&pubkey, &newkey, 1 /* make_public */);
1.132 + fpr_to_str(&fprstr,
1.133 + newkey.sigfingerprint.fingerprint,
1.134 + newkey.sigfingerprint.length);
1.135 + if (fprstr == NULL) {
1.136 + result = PEP_OUT_OF_MEMORY;
1.137 + goto free_newkey;
1.138 + }
1.139
1.140 - // Append generated key to netpgp's rings
1.141 - pgp_keyring_add(netpgp->secring, &newkey);
1.142 - pgp_keyring_add(netpgp->pubring, &pubkey);
1.143 - // FIXME doesn't check result since always true
1.144 - // TODO alloc error feedback in netpgp
1.145 + result = import_key_or_keypair(netpgp, &newkey);
1.146
1.147 - // save rings (key ownership transfered)
1.148 - if (netpgp_save_pubring(netpgp) &&
1.149 - netpgp_save_secring(netpgp))
1.150 - {
1.151 - char *fprstr = NULL;
1.152 - fpr_to_str(&fprstr,
1.153 - newkey.sigfingerprint.fingerprint,
1.154 - newkey.sigfingerprint.length);
1.155 - if ((identity->fpr = fprstr) == NULL) {
1.156 - result = PEP_OUT_OF_MEMORY;
1.157 - }else{
1.158 - result = PEP_STATUS_OK;
1.159 - }
1.160 - }else{
1.161 - result = PEP_UNKNOWN_ERROR;
1.162 + if (result == PEP_STATUS_OK) {
1.163 + identity->fpr = fprstr;
1.164 + /* free nothing, everything transfered */
1.165 + return PEP_STATUS_OK;
1.166 }
1.167
1.168 +free_fprstr:
1.169 + free(fprstr);
1.170 +free_newkey:
1.171 + pgp_key_free(&newkey);
1.172 +
1.173 return result;
1.174 }
1.175
1.176 @@ -654,8 +697,8 @@
1.177
1.178 if (str_to_fpr(fprstr, fpr, &length)) {
1.179 if (!pgp_deletekeybyfpr(netpgp->io,
1.180 - (pgp_pubkey_t *)netpgp->secring,
1.181 - fpr, length)) {
1.182 + (pgp_keyring_t *)netpgp->secring,
1.183 + (const uint8_t *)fpr, length)) {
1.184 return PEP_KEY_NOT_FOUND;
1.185 }
1.186 }else{
1.187 @@ -666,8 +709,8 @@
1.188 * in pubring if it exists */
1.189 if(res) {
1.190 pgp_deletekeybyfpr(netpgp->io,
1.191 - (pgp_pubkey_t *)netpgp->pubring,
1.192 - fpr, length);
1.193 + (pgp_keyring_t *)netpgp->pubring,
1.194 + (const uint8_t *)fpr, length);
1.195 }
1.196
1.197 // save rings (key ownership transfered)
1.198 @@ -682,54 +725,121 @@
1.199 return result;
1.200 }
1.201
1.202 +#define ARMOR_KEY_HEAD "^-----BEGIN PGP (PUBLIC|PRIVATE) KEY BLOCK-----\\s*$"
1.203 PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data, size_t size)
1.204 {
1.205 +
1.206 + netpgp_t *netpgp;
1.207 + pgp_memory_t *mem;
1.208 + pgp_keyring_t tmpring;
1.209 +
1.210 + PEP_STATUS result;
1.211 +
1.212 assert(session);
1.213 assert(key_data);
1.214
1.215 - /* TODO import */
1.216 + if(!session || !key_data)
1.217 return PEP_UNKNOWN_ERROR;
1.218 - return PEP_ILLEGAL_VALUE;
1.219 - return PEP_UNKNOWN_ERROR;
1.220 - return PEP_STATUS_OK;
1.221 +
1.222 + netpgp = &session->ctx;
1.223 +
1.224 + mem = pgp_memory_new();
1.225 + if (mem == NULL) {
1.226 + return PEP_OUT_OF_MEMORY;
1.227 + }
1.228 + pgp_memory_add(mem, (const uint8_t*)key_data, size);
1.229 +
1.230 + if (pgp_keyring_read_from_mem(netpgp->io, &tmpring,
1.231 + _armoured(key_data, size, ARMOR_KEY_HEAD),
1.232 + mem) == 0){
1.233 + result = PEP_ILLEGAL_VALUE;
1.234 + }else if (tmpring.keyc == 0){
1.235 + result = PEP_UNKNOWN_ERROR;
1.236 + }else if (tmpring.keyc > 1){
1.237 + /* too many keys given */
1.238 + result = PEP_ILLEGAL_VALUE;
1.239 + }else{
1.240 + result = import_key_or_keypair(netpgp, &tmpring.keys[0]);
1.241 + }
1.242 +
1.243 + pgp_memory_free(mem);
1.244 +
1.245 + if (result != PEP_STATUS_OK){
1.246 + pgp_keyring_purge(&tmpring);
1.247 + }
1.248 +
1.249 + return result;
1.250 }
1.251
1.252 PEP_STATUS pgp_export_keydata(
1.253 - PEP_SESSION session, const char *fpr, char **key_data, size_t *size
1.254 + PEP_SESSION session, const char *fprstr, char **key_data, size_t *size
1.255 )
1.256 {
1.257 - size_t _size;
1.258 + netpgp_t *netpgp;
1.259 + pgp_key_t *key;
1.260 + pgp_output_t *output;
1.261 + pgp_memory_t *mem;
1.262 + uint8_t fpr[PGP_FINGERPRINT_SIZE];
1.263 + size_t fprlen;
1.264 +
1.265 + PEP_STATUS result;
1.266 char *buffer;
1.267 - int reading;
1.268 + size_t buflen;
1.269
1.270 assert(session);
1.271 assert(fpr);
1.272 assert(key_data);
1.273 assert(size);
1.274
1.275 + netpgp = &session->ctx;
1.276
1.277 - /* TODO export */
1.278 - return PEP_KEY_NOT_FOUND;
1.279 - return PEP_UNKNOWN_ERROR;
1.280 + if (!session || !fpr || !key_data || !size)
1.281 return PEP_UNKNOWN_ERROR;
1.282
1.283 - _size = /* TODO */ 0;
1.284 - assert(_size != -1);
1.285 + if (str_to_fpr(fprstr, fpr, &fprlen)) {
1.286 + unsigned from = 0;
1.287 + if ((key = (pgp_key_t *)pgp_getkeybyfpr(netpgp->io, netpgp->pubring,
1.288 + fpr, fprlen,
1.289 + &from, NULL)) == NULL) {
1.290 + return PEP_KEY_NOT_FOUND;
1.291 + }
1.292 + }else{
1.293 + return PEP_OUT_OF_MEMORY;
1.294 + }
1.295 +
1.296 + pgp_setup_memory_write(&output, &mem, 128);
1.297
1.298 - buffer = malloc(_size + 1);
1.299 - assert(buffer);
1.300 - if (buffer == NULL) {
1.301 - /* TODO clean */
1.302 + if (mem == NULL || output == NULL) {
1.303 return PEP_OUT_OF_MEMORY;
1.304 }
1.305
1.306 - // safeguard for the naive user
1.307 - buffer[_size] = 0;
1.308 + if (!pgp_write_xfer_pubkey(output, key, 1)) {
1.309 + result = PEP_UNKNOWN_ERROR;
1.310 + goto free_mem;
1.311 + }
1.312 +
1.313 + buffer = NULL;
1.314 + buflen = pgp_mem_len(mem);
1.315 +
1.316 + // Allocate transferable buffer
1.317 + buffer = malloc(buflen + 1);
1.318 + assert(buffer);
1.319 + if (buffer == NULL) {
1.320 + result = PEP_OUT_OF_MEMORY;
1.321 + goto free_mem;
1.322 + }
1.323 +
1.324 + memcpy(buffer, pgp_mem_data(mem), buflen);
1.325
1.326 *key_data = buffer;
1.327 - *size = _size;
1.328 + *size = buflen;
1.329 + (*key_data)[*size] = 0; // safeguard for naive users
1.330 + result = PEP_STATUS_OK;
1.331
1.332 - return PEP_STATUS_OK;
1.333 +free_mem :
1.334 + pgp_teardown_memory_write(output, mem);
1.335 +
1.336 + return result;
1.337 }
1.338
1.339 // "keyserver"