merge
authorVolker Birk <vb@pep-project.org>
Thu, 30 Apr 2015 19:03:18 +0200
changeset 231d862ff6c48c7
parent 230 5b36a2663539
parent 229 313d152239bf
child 232 3d44d9bb18e5
merge
     1.1 --- a/src/pEpEngine.h	Thu Apr 30 19:01:58 2015 +0200
     1.2 +++ b/src/pEpEngine.h	Thu Apr 30 19:03:18 2015 +0200
     1.3 @@ -622,7 +622,7 @@
     1.4      );
     1.5  
     1.6  
     1.7 -// revoke_key() - revoke an expired key
     1.8 +// revoke_key() - revoke a key
     1.9  //
    1.10  //  parameters:
    1.11  //      session (in)            session handle
    1.12 @@ -632,6 +632,8 @@
    1.13  //
    1.14  //  caveat:
    1.15  //      reason text must not include empty lines
    1.16 +//      this function is meant for internal use only; better use
    1.17 +//      key_compromized() of keymanagement API
    1.18  
    1.19  DYNAMIC_API PEP_STATUS revoke_key(
    1.20          PEP_SESSION session,
     2.1 --- a/src/pEp_internal.h	Thu Apr 30 19:01:58 2015 +0200
     2.2 +++ b/src/pEp_internal.h	Thu Apr 30 19:03:18 2015 +0200
     2.3 @@ -53,7 +53,7 @@
     2.4  
     2.5  #ifdef USE_GPG
     2.6  #include "pgp_gpg_internal.h"
     2.7 -#elif USE_NETPGP
     2.8 +#elif defined(USE_NETPGP)
     2.9  #include "pgp_netpgp_internal.h"
    2.10  #endif
    2.11  
    2.12 @@ -66,7 +66,7 @@
    2.13      const char *version;
    2.14  #ifdef USE_GPG
    2.15      gpgme_ctx_t ctx;
    2.16 -#elif USE_NETPGP
    2.17 +#elif defined(USE_NETPGP)
    2.18      netpgp_t ctx;
    2.19  #endif
    2.20  
     3.1 --- a/src/pgp_netpgp.c	Thu Apr 30 19:01:58 2015 +0200
     3.2 +++ b/src/pgp_netpgp.c	Thu Apr 30 19:03:18 2015 +0200
     3.3 @@ -11,6 +11,7 @@
     3.4  #include <netpgp/crypto.h>
     3.5  #include <netpgp/netpgpsdk.h>
     3.6  #include <netpgp/validate.h>
     3.7 +#include <netpgp/readerwriter.h>
     3.8  
     3.9  #include <regex.h>
    3.10  
    3.11 @@ -52,7 +53,7 @@
    3.12  
    3.13      // subset of gpg's personal-cipher-preferences
    3.14      // here only one cipher can be selected
    3.15 -    netpgp_setvar(netpgp, "cipher", "AES256");
    3.16 +    netpgp_setvar(netpgp, "cipher", "CAST5");
    3.17  
    3.18      if (!netpgp_init(netpgp)) {
    3.19          status = PEP_INIT_NETPGP_INIT_FAILED;
    3.20 @@ -98,6 +99,18 @@
    3.21      return armoured;
    3.22  }
    3.23  
    3.24 +/* return key ID's hexdump as a string */
    3.25 +static void id_to_str(const uint8_t *userid, char *fpr)
    3.26 +{
    3.27 +    int i;
    3.28 +    static const char *hexes = "0123456789abcdef";
    3.29 +    for (i = 0; i < 8 ; i++) {
    3.30 +        fpr[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4];
    3.31 +        fpr[(i * 2) + 1] = hexes[userid[i] & 0xf];
    3.32 +    }
    3.33 +    fpr[8 * 2] = 0x0;
    3.34 +}
    3.35 +
    3.36  // Iterate through netpgp' reported valid signatures 
    3.37  // fill a list of valid figerprints
    3.38  // returns PEP_STATUS_OK if all sig reported valid
    3.39 @@ -141,9 +154,7 @@
    3.40          }
    3.41          k = *_keylist;
    3.42          for (n = 0; n < vresult->validc; ++n) {
    3.43 -            int i;
    3.44              char id[MAX_ID_LENGTH + 1];
    3.45 -            static const char *hexes = "0123456789abcdef";
    3.46              const uint8_t *userid = vresult->valid_sigs[n].signer_id;
    3.47  
    3.48  #ifdef PEP_NETPGP_DEBUG
    3.49 @@ -156,11 +167,7 @@
    3.50              pgp_print_keydata(netpgp->io, netpgp->pubring, key, "valid signature ", &key->key.pubkey, 0);
    3.51  #endif //PEP_NETPGP_DEBUG
    3.52  
    3.53 -            for (i = 0; i < 8 ; i++) {
    3.54 -                id[i * 2] = hexes[(unsigned)(userid[i] & 0xf0) >> 4];
    3.55 -                id[(i * 2) + 1] = hexes[userid[i] & 0xf];
    3.56 -            }
    3.57 -            id[8 * 2] = 0x0;
    3.58 +            id_to_str(userid, id);
    3.59  
    3.60              k = stringlist_add(k, id);
    3.61              if(!k){
    3.62 @@ -391,7 +398,6 @@
    3.63  
    3.64      PEP_STATUS result;
    3.65      const stringlist_t *_keylist;
    3.66 -    int i;
    3.67  
    3.68      assert(session);
    3.69      assert(keylist);
    3.70 @@ -477,7 +483,6 @@
    3.71  
    3.72          char *_buffer = NULL;
    3.73          size_t length = pgp_mem_len(cmem);
    3.74 -        assert(length != -1);
    3.75  
    3.76          // Allocate transferable buffer
    3.77          _buffer = malloc(length + 1);
    3.78 @@ -505,19 +510,116 @@
    3.79      return result;
    3.80  }
    3.81  
    3.82 +/* return the hexdump as a string */
    3.83 +static unsigned
    3.84 +fpr_to_str (char **str, const uint8_t *fpr, size_t length)
    3.85 +{
    3.86 +    unsigned i;
    3.87 +    int	n;
    3.88 +
    3.89 +    /* 5 char per byte (hexes + space) tuple -1 space at the end + null */
    3.90 +    *str = malloc((length / 2) * 5 - 1 + 1);
    3.91 +
    3.92 +    if(*str == NULL)
    3.93 +        return 0;
    3.94 +
    3.95 +    for (n = 0, i = 0 ; i < length - 1; i += 2) {
    3.96 +    	n += snprintf(&((*str)[n]), 6, "%02x%02x ", *fpr++, *fpr++);
    3.97 +    }
    3.98 +    snprintf(&((*str)[n]), 5, "%02x%02x", *fpr++, *fpr++);
    3.99 +
   3.100 +    return 1;
   3.101 +}
   3.102 +
   3.103 +static unsigned
   3.104 +str_to_fpr (const char *str, uint8_t *fpr, size_t *length)
   3.105 +{
   3.106 +    unsigned i,j;
   3.107 +
   3.108 +    *length = 0;
   3.109 +
   3.110 +    while(*str && *length < PGP_FINGERPRINT_SIZE){
   3.111 +        while (*str == ' ') str++;
   3.112 +        for (j = 0; j < 2; j++) {
   3.113 +            uint8_t *byte = &fpr[*length];
   3.114 +            for (i = 0; i < 2; i++) {
   3.115 +                if (i > 0)
   3.116 +                    *byte *= 16;
   3.117 +                if (*str >= 'a' && *str <= 'f')
   3.118 +                    *byte += 10 + *str - 'a';
   3.119 +                else if (*str >= 'A' && *str <= 'F')
   3.120 +                    *byte += 10 + *str - 'A';
   3.121 +                else if (*str >= '0' && *str <= '9')
   3.122 +                    *byte += *str - '0';
   3.123 +                else 
   3.124 +                    return 0;
   3.125 +                str++;
   3.126 +            }
   3.127 +            *length++;
   3.128 +        }
   3.129 +    }
   3.130 +    return 1;
   3.131 +}
   3.132 +
   3.133 +static PEP_STATUS import_key_or_keypair(netpgp_t *netpgp, pgp_key_t *newkey){
   3.134 +    pgp_key_t	pubkey;
   3.135 +    unsigned public;
   3.136 +    PEP_STATUS result;
   3.137 +
   3.138 +    if ((public = (newkey->type == PGP_PTAG_CT_PUBLIC_KEY))){
   3.139 +        pubkey = *newkey;
   3.140 +    } else {
   3.141 +        // Duplicate key as public only
   3.142 +        if (!pgp_keydata_dup(&pubkey, newkey, 1 /* make_public */)){
   3.143 +            return PEP_OUT_OF_MEMORY;
   3.144 +        }
   3.145 +    }
   3.146 +
   3.147 +    // Append generated key to netpgp's rings (key ownership transfered)
   3.148 +    if (!public && !pgp_keyring_add(netpgp->secring, newkey)){
   3.149 +        result = PEP_OUT_OF_MEMORY;
   3.150 +        goto free_pubkey;
   3.151 +    } else if (!pgp_keyring_add(netpgp->pubring, &pubkey)){
   3.152 +        result = PEP_OUT_OF_MEMORY;
   3.153 +        goto pop_secring;
   3.154 +    }
   3.155 +
   3.156 +    // save rings 
   3.157 +    if (netpgp_save_pubring(netpgp) && 
   3.158 +        (!public || netpgp_save_secring(netpgp)))
   3.159 +    {
   3.160 +        /* free nothing, everything transfered */
   3.161 +        return PEP_STATUS_OK;
   3.162 +    } else {
   3.163 +        /* XXX in case only pubring save succeed
   3.164 +         * pubring file is left as-is, but backup restore
   3.165 +         * could be attempted if such corner case matters */
   3.166 +        result = PEP_UNKNOWN_ERROR;
   3.167 +    }
   3.168 +
   3.169 +pop_pubring:
   3.170 +    ((pgp_keyring_t *)netpgp->pubring)->keyc--;
   3.171 +pop_secring:
   3.172 +    ((pgp_keyring_t *)netpgp->secring)->keyc--;
   3.173 +free_pubkey:
   3.174 +    pgp_key_free(&pubkey);
   3.175 +
   3.176 +    return result;
   3.177 +}
   3.178 +
   3.179  PEP_STATUS pgp_generate_keypair(
   3.180      PEP_SESSION session, pEp_identity *identity
   3.181      )
   3.182  {
   3.183 -    char *parms;
   3.184 -    const char *template =
   3.185 -        "Key-Type: RSA\n"
   3.186 -        "Key-Length: 4096\n"
   3.187 -        "Name-Real: %s\n"
   3.188 -        "Name-Email: %s\n"
   3.189 -        /* "Passphrase: %s\n" */
   3.190 -        "Expire-Date: 1y\n";
   3.191 -    int result;
   3.192 +    netpgp_t *netpgp;
   3.193 +    pgp_key_t	newkey;
   3.194 +    pgp_key_t	pubkey;
   3.195 +
   3.196 +    PEP_STATUS result;
   3.197 +    char newid[1024];
   3.198 +    const char *hashalg;
   3.199 +    const char *cipher;
   3.200 +    char *fprstr = NULL;
   3.201  
   3.202      assert(session);
   3.203      assert(identity);
   3.204 @@ -525,101 +627,219 @@
   3.205      assert(identity->fpr == NULL);
   3.206      assert(identity->username);
   3.207  
   3.208 -    parms = calloc(1, PARMS_MAX);
   3.209 -    assert(parms);
   3.210 -    if (parms == NULL)
   3.211 -        return PEP_OUT_OF_MEMORY;
   3.212 +    if(!session || !identity || 
   3.213 +       !identity->address || identity->fpr || !identity->username)
   3.214 +        return PEP_UNKNOWN_ERROR;
   3.215  
   3.216 -    result = snprintf(parms, PARMS_MAX, template, identity->username,
   3.217 -        identity->address);
   3.218 -    assert(result < PARMS_MAX);
   3.219 -    if (result >= PARMS_MAX) {
   3.220 -        free(parms);
   3.221 +    netpgp = &session->ctx;
   3.222 +
   3.223 +    if(snprintf(newid, sizeof(newid),
   3.224 +        "%s <%s>", identity->username, identity->address) >= sizeof(newid)){
   3.225          return PEP_BUFFER_TOO_SMALL;
   3.226      }
   3.227 +    
   3.228 +    hashalg = netpgp_getvar(netpgp, "hash");
   3.229 +    cipher = netpgp_getvar(netpgp, "cipher");
   3.230  
   3.231 -    /* TODO generate key */
   3.232 +    bzero(&newkey, sizeof(newkey));
   3.233 +    bzero(&pubkey, sizeof(pubkey));
   3.234  
   3.235 -    free(parms);
   3.236 +    // Generate the key
   3.237 +    if (!pgp_rsa_generate_keypair(&newkey, 4096, 65537UL, hashalg, cipher,
   3.238 +                                  (const uint8_t *) "", (const size_t) 0) ||
   3.239 +        !pgp_add_selfsigned_userid(&newkey, (uint8_t *)newid)) {
   3.240 +        result = PEP_CANNOT_CREATE_KEY;
   3.241 +        goto free_newkey;
   3.242 +    }
   3.243  
   3.244 -        return PEP_UNKNOWN_ERROR;
   3.245 -        return PEP_ILLEGAL_VALUE;
   3.246 -        return PEP_CANNOT_CREATE_KEY;
   3.247 +    // TODO "Expire-Date: 1y\n";
   3.248  
   3.249 -    identity->fpr = strdup("TODO generated key fpr");
   3.250 +    fpr_to_str(&fprstr,
   3.251 +               newkey.sigfingerprint.fingerprint,
   3.252 +               newkey.sigfingerprint.length);
   3.253 +    if (fprstr == NULL) {
   3.254 +        result = PEP_OUT_OF_MEMORY;
   3.255 +        goto free_newkey;
   3.256 +    } 
   3.257  
   3.258 -    return PEP_STATUS_OK;
   3.259 +    result = import_key_or_keypair(netpgp, &newkey);
   3.260 +
   3.261 +    if (result == PEP_STATUS_OK) {
   3.262 +        identity->fpr = fprstr;
   3.263 +        /* free nothing, everything transfered */
   3.264 +        return PEP_STATUS_OK;
   3.265 +    }
   3.266 +
   3.267 +free_fprstr:
   3.268 +    free(fprstr);
   3.269 +free_newkey:
   3.270 +    pgp_key_free(&newkey);
   3.271 +
   3.272 +    return result;
   3.273  }
   3.274  
   3.275 -PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr)
   3.276 +PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fprstr)
   3.277  {
   3.278 +    netpgp_t *netpgp;
   3.279 +    uint8_t fpr[PGP_FINGERPRINT_SIZE];
   3.280 +    size_t length;
   3.281 +    unsigned res;
   3.282 +
   3.283 +    PEP_STATUS result;
   3.284 +
   3.285      assert(session);
   3.286      assert(fpr);
   3.287  
   3.288 -    /* TODO get key with given fpr */
   3.289 -        return PEP_KEY_NOT_FOUND;
   3.290 -        return PEP_ILLEGAL_VALUE;
   3.291 -        return PEP_KEY_HAS_AMBIG_NAME;
   3.292 -        return PEP_OUT_OF_MEMORY;
   3.293 +    if (!session || !fpr)
   3.294          return PEP_UNKNOWN_ERROR;
   3.295  
   3.296 -    /* TODO delete that key */
   3.297 -        return PEP_UNKNOWN_ERROR;
   3.298 -        return PEP_KEY_NOT_FOUND;
   3.299 -        return PEP_KEY_HAS_AMBIG_NAME;
   3.300 -        return PEP_UNKNOWN_ERROR;
   3.301 +    netpgp = &session->ctx;
   3.302 +    
   3.303 +    if (str_to_fpr(fprstr, fpr, &length)) {
   3.304 +        if (!pgp_deletekeybyfpr(netpgp->io,
   3.305 +                                (pgp_keyring_t *)netpgp->secring, 
   3.306 +                                (const uint8_t *)fpr, length)) {
   3.307 +            return PEP_KEY_NOT_FOUND;
   3.308 +        }
   3.309 +    }else{
   3.310 +        return PEP_OUT_OF_MEMORY;
   3.311 +    }
   3.312  
   3.313 -    return PEP_STATUS_OK;
   3.314 +    /* pair was found in secring delete also corresponding pubkey 
   3.315 +     * in pubring if it exists */
   3.316 +    if(res) {
   3.317 +        pgp_deletekeybyfpr(netpgp->io,
   3.318 +                           (pgp_keyring_t *)netpgp->pubring, 
   3.319 +                           (const uint8_t *)fpr, length);
   3.320 +    }
   3.321 +
   3.322 +    // save rings (key ownership transfered)
   3.323 +    if (netpgp_save_pubring(netpgp) && 
   3.324 +        netpgp_save_secring(netpgp))
   3.325 +    {
   3.326 +        result = PEP_STATUS_OK;
   3.327 +    }else{
   3.328 +        result = PEP_UNKNOWN_ERROR;
   3.329 +    }
   3.330 +
   3.331 +    return result;
   3.332  }
   3.333  
   3.334 +#define ARMOR_KEY_HEAD    "^-----BEGIN PGP (PUBLIC|PRIVATE) KEY BLOCK-----\\s*$"
   3.335  PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data, size_t size)
   3.336  {
   3.337 +
   3.338 +    netpgp_t *netpgp;
   3.339 +    pgp_memory_t *mem;
   3.340 +    pgp_keyring_t tmpring;
   3.341 +
   3.342 +    PEP_STATUS result;
   3.343 +
   3.344      assert(session);
   3.345      assert(key_data);
   3.346  
   3.347 -    /* TODO import */
   3.348 +    if(!session || !key_data) 
   3.349          return PEP_UNKNOWN_ERROR;
   3.350 -        return PEP_ILLEGAL_VALUE;
   3.351 -        return PEP_UNKNOWN_ERROR;
   3.352 -    return PEP_STATUS_OK;
   3.353 +
   3.354 +    netpgp = &session->ctx;
   3.355 +
   3.356 +    mem = pgp_memory_new();
   3.357 +    if (mem == NULL) {
   3.358 +        return PEP_OUT_OF_MEMORY;
   3.359 +    }
   3.360 +    pgp_memory_add(mem, (const uint8_t*)key_data, size);
   3.361 +
   3.362 +    if (pgp_keyring_read_from_mem(netpgp->io, &tmpring, 
   3.363 +                                  _armoured(key_data, size, ARMOR_KEY_HEAD),
   3.364 +                                  mem) == 0){
   3.365 +        result = PEP_ILLEGAL_VALUE;
   3.366 +    }else if (tmpring.keyc == 0){
   3.367 +        result = PEP_UNKNOWN_ERROR;
   3.368 +    }else if (tmpring.keyc > 1){
   3.369 +        /* too many keys given */
   3.370 +        result = PEP_ILLEGAL_VALUE;
   3.371 +    }else{
   3.372 +        result = import_key_or_keypair(netpgp, &tmpring.keys[0]);
   3.373 +    }
   3.374 +    
   3.375 +    pgp_memory_free(mem);
   3.376 +
   3.377 +    if (result != PEP_STATUS_OK){
   3.378 +        pgp_keyring_purge(&tmpring);
   3.379 +    }
   3.380 +
   3.381 +    return result;
   3.382  }
   3.383  
   3.384  PEP_STATUS pgp_export_keydata(
   3.385 -    PEP_SESSION session, const char *fpr, char **key_data, size_t *size
   3.386 +    PEP_SESSION session, const char *fprstr, char **key_data, size_t *size
   3.387      )
   3.388  {
   3.389 -    size_t _size;
   3.390 +    netpgp_t *netpgp;
   3.391 +    pgp_key_t *key;
   3.392 +	pgp_output_t *output;
   3.393 +    pgp_memory_t *mem;
   3.394 +    uint8_t fpr[PGP_FINGERPRINT_SIZE];
   3.395 +    size_t fprlen;
   3.396 +
   3.397 +    PEP_STATUS result;
   3.398      char *buffer;
   3.399 -    int reading;
   3.400 +    size_t buflen;
   3.401  
   3.402      assert(session);
   3.403      assert(fpr);
   3.404      assert(key_data);
   3.405      assert(size);
   3.406  
   3.407 +    netpgp = &session->ctx;
   3.408  
   3.409 -    /* TODO export */
   3.410 -        return PEP_KEY_NOT_FOUND;
   3.411 -        return PEP_UNKNOWN_ERROR;
   3.412 +    if (!session || !fpr || !key_data || !size)
   3.413          return PEP_UNKNOWN_ERROR;
   3.414  
   3.415 -    _size = /* TODO */ 0;
   3.416 -    assert(_size != -1);
   3.417 +    if (str_to_fpr(fprstr, fpr, &fprlen)) {
   3.418 +        unsigned from = 0;
   3.419 +        if ((key = (pgp_key_t *)pgp_getkeybyfpr(netpgp->io, netpgp->pubring, 
   3.420 +                                                fpr, fprlen,
   3.421 +                                                &from, NULL)) == NULL) {
   3.422 +            return PEP_KEY_NOT_FOUND;
   3.423 +        }
   3.424 +    }else{
   3.425 +        return PEP_OUT_OF_MEMORY;
   3.426 +    }
   3.427 +    
   3.428 +	pgp_setup_memory_write(&output, &mem, 128);
   3.429  
   3.430 -    buffer = malloc(_size + 1);
   3.431 -    assert(buffer);
   3.432 -    if (buffer == NULL) {
   3.433 -        /* TODO clean */
   3.434 +    if (mem == NULL || output == NULL) {
   3.435          return PEP_OUT_OF_MEMORY;
   3.436      }
   3.437  
   3.438 -    // safeguard for the naive user
   3.439 -    buffer[_size] = 0;
   3.440 +    if (!pgp_write_xfer_pubkey(output, key, 1)) {
   3.441 +        result = PEP_UNKNOWN_ERROR;
   3.442 +        goto free_mem;
   3.443 +    }
   3.444 +
   3.445 +    buffer = NULL;
   3.446 +    buflen = pgp_mem_len(mem);
   3.447 +
   3.448 +    // Allocate transferable buffer
   3.449 +    buffer = malloc(buflen + 1);
   3.450 +    assert(buffer);
   3.451 +    if (buffer == NULL) {
   3.452 +        result = PEP_OUT_OF_MEMORY;
   3.453 +        goto free_mem;
   3.454 +    }
   3.455 +
   3.456 +    memcpy(buffer, pgp_mem_data(mem), buflen);
   3.457  
   3.458      *key_data = buffer;
   3.459 -    *size = _size;
   3.460 +    *size = buflen;
   3.461 +    (*key_data)[*size] = 0; // safeguard for naive users
   3.462 +    result = PEP_STATUS_OK;
   3.463  
   3.464 -    return PEP_STATUS_OK;
   3.465 +free_mem :
   3.466 +	pgp_teardown_memory_write(output, mem);
   3.467 +
   3.468 +    return result;
   3.469  }
   3.470  
   3.471  // "keyserver"
   3.472 @@ -774,7 +994,11 @@
   3.473      return PEP_STATUS_OK;
   3.474  }
   3.475  
   3.476 -PEP_STATUS pgp_revoke_key(PEP_SESSION session, const char *fpr)
   3.477 +PEP_STATUS pgp_revoke_key(
   3.478 +        PEP_SESSION session,
   3.479 +        const char *fpr,
   3.480 +        const char *reason
   3.481 +    )
   3.482  {
   3.483      PEP_STATUS status = PEP_STATUS_OK;
   3.484      
   3.485 @@ -786,3 +1010,23 @@
   3.486      return PEP_STATUS_OK;
   3.487  }
   3.488  
   3.489 +PEP_STATUS pgp_key_expired(
   3.490 +        PEP_SESSION session,
   3.491 +        const char *fpr,
   3.492 +        bool *expired
   3.493 +    )
   3.494 +{
   3.495 +    PEP_STATUS status = PEP_STATUS_OK;
   3.496 +
   3.497 +    assert(session);
   3.498 +    assert(fpr);
   3.499 +    assert(expired);
   3.500 +
   3.501 +    *expired = false;
   3.502 +
   3.503 +    if (status != PEP_STATUS_OK)
   3.504 +        return status;
   3.505 +
   3.506 +    return PEP_STATUS_OK;
   3.507 +}
   3.508 +
     4.1 --- a/src/pgp_netpgp.h	Thu Apr 30 19:01:58 2015 +0200
     4.2 +++ b/src/pgp_netpgp.h	Thu Apr 30 19:03:18 2015 +0200
     4.3 @@ -44,7 +44,6 @@
     4.4          size_t size);
     4.5  
     4.6  PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern);
     4.7 -
     4.8  PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern);
     4.9  
    4.10  PEP_STATUS pgp_renew_key(
    4.11 @@ -53,4 +52,15 @@
    4.12          const timestamp *ts
    4.13      );
    4.14  
    4.15 -PEP_STATUS pgp_revoke_key(PEP_SESSION session, const char *fpr);
    4.16 +PEP_STATUS pgp_revoke_key(
    4.17 +        PEP_SESSION session,
    4.18 +        const char *fpr,
    4.19 +        const char *reason
    4.20 +    );
    4.21 +
    4.22 +PEP_STATUS pgp_key_expired(
    4.23 +        PEP_SESSION session,
    4.24 +        const char *fpr,
    4.25 +        bool *expired
    4.26 +    );
    4.27 +
     5.1 --- a/src/platform_unix.h	Thu Apr 30 19:01:58 2015 +0200
     5.2 +++ b/src/platform_unix.h	Thu Apr 30 19:03:18 2015 +0200
     5.3 @@ -4,6 +4,10 @@
     5.4  #include <strings.h>
     5.5  #include <sys/select.h>
     5.6  
     5.7 +#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
     5.8 +#define USE_NETPGP
     5.9 +#endif
    5.10 +
    5.11  #ifdef __cplusplus
    5.12  extern "C" {
    5.13  #endif