renew_key fixed
authorVolker Birk <vb@pep-project.org>
Mon, 20 Apr 2015 15:59:13 +0200
changeset 20006655f7634a6
parent 199 545944999924
child 201 79bb3ac04b41
renew_key fixed
src/cryptotech.c
src/cryptotech.h
src/pEpEngine.c
src/pEpEngine.h
src/pgp_gpg.c
src/pgp_gpg.h
test/Makefile
     1.1 --- a/src/cryptotech.c	Fri Apr 17 10:55:56 2015 +0200
     1.2 +++ b/src/cryptotech.c	Mon Apr 20 15:59:13 2015 +0200
     1.3 @@ -38,6 +38,8 @@
     1.4          cryptotech[PEP_crypt_OpenPGP].import_key = pgp_import_keydata;
     1.5          cryptotech[PEP_crypt_OpenPGP].recv_key = pgp_recv_key;
     1.6          cryptotech[PEP_crypt_OpenPGP].send_key = pgp_send_key;
     1.7 +        cryptotech[PEP_crypt_OpenPGP].renew_key = pgp_renew_key;
     1.8 +        cryptotech[PEP_crypt_OpenPGP].revoke_key = pgp_revoke_key;
     1.9      }
    1.10  
    1.11      session->cryptotech = cryptotech;
     2.1 --- a/src/cryptotech.h	Fri Apr 17 10:55:56 2015 +0200
     2.2 +++ b/src/cryptotech.h	Mon Apr 20 15:59:13 2015 +0200
     2.3 @@ -53,6 +53,10 @@
     2.4  
     2.5  typedef PEP_STATUS (*send_key_t)(PEP_SESSION session, const char *pattern);
     2.6  
     2.7 +typedef PEP_STATUS (*renew_key_t)(PEP_SESSION session, const char *key_id);
     2.8 +
     2.9 +typedef PEP_STATUS (*revoke_key_t)(PEP_SESSION session, const char *key_id);
    2.10 +
    2.11  typedef struct _PEP_cryptotech_t {
    2.12      uint8_t id;
    2.13      // the following are default values; comm_type may vary with key length or b0rken crypto
    2.14 @@ -69,6 +73,8 @@
    2.15      import_key_t import_key;
    2.16      recv_key_t recv_key;
    2.17      send_key_t send_key;
    2.18 +    renew_key_t renew_key;
    2.19 +    revoke_key_t revoke_key;
    2.20  } PEP_cryptotech_t;
    2.21  
    2.22  typedef uint64_t cryptotech_mask;
     3.1 --- a/src/pEpEngine.c	Fri Apr 17 10:55:56 2015 +0200
     3.2 +++ b/src/pEpEngine.c	Mon Apr 20 15:59:13 2015 +0200
     3.3 @@ -898,25 +898,25 @@
     3.4      return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
     3.5  }
     3.6  
     3.7 -DYNAMIC_API PEP_STATUS renew_key(PEP_SESSION session, const char *key_id)
     3.8 +DYNAMIC_API PEP_STATUS renew_key(PEP_SESSION session, const char *fpr)
     3.9  {
    3.10      assert(session);
    3.11 -    assert(key_id);
    3.12 +    assert(fpr);
    3.13  
    3.14 -    if (!(session && key_id))
    3.15 +    if (!(session && fpr))
    3.16          return PEP_ILLEGAL_VALUE;
    3.17  
    3.18 -    return PEP_UNKNOWN_ERROR;
    3.19 +    return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr);
    3.20  }
    3.21  
    3.22 -DYNAMIC_API PEP_STATUS revoke_key(PEP_SESSION session, const char *key_id)
    3.23 +DYNAMIC_API PEP_STATUS revoke_key(PEP_SESSION session, const char *fpr)
    3.24  {
    3.25      assert(session);
    3.26 -    assert(key_id);
    3.27 +    assert(fpr);
    3.28  
    3.29 -    if (!(session && key_id))
    3.30 +    if (!(session && fpr))
    3.31          return PEP_ILLEGAL_VALUE;
    3.32  
    3.33 -    return PEP_UNKNOWN_ERROR;
    3.34 +    return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr);
    3.35  }
    3.36  
     4.1 --- a/src/pEpEngine.h	Fri Apr 17 10:55:56 2015 +0200
     4.2 +++ b/src/pEpEngine.h	Mon Apr 20 15:59:13 2015 +0200
     4.3 @@ -612,7 +612,7 @@
     4.4  //      session (in)            session handle
     4.5  //      key_id (in)             ID of key to renew as UTF-8 string
     4.6  
     4.7 -DYNAMIC_API PEP_STATUS renew_key(PEP_SESSION session, const char *key_id);
     4.8 +DYNAMIC_API PEP_STATUS renew_key(PEP_SESSION session, const char *fpr);
     4.9  
    4.10  
    4.11  // revoke_key() - revoke an expired key
    4.12 @@ -621,7 +621,7 @@
    4.13  //      session (in)            session handle
    4.14  //      key_id (in)             ID of key to revoke as UTF-8 string
    4.15  
    4.16 -DYNAMIC_API PEP_STATUS revoke_key(PEP_SESSION session, const char *key_id);
    4.17 +DYNAMIC_API PEP_STATUS revoke_key(PEP_SESSION session, const char *fpr);
    4.18  
    4.19  
    4.20  #ifdef __cplusplus
     5.1 --- a/src/pgp_gpg.c	Fri Apr 17 10:55:56 2015 +0200
     5.2 +++ b/src/pgp_gpg.c	Mon Apr 20 15:59:13 2015 +0200
     5.3 @@ -1193,7 +1193,6 @@
     5.4          return PEP_CANNOT_SEND_KEY;
     5.5  }
     5.6  
     5.7 -
     5.8  PEP_STATUS pgp_get_key_rating(
     5.9      PEP_SESSION session,
    5.10      const char *fpr,
    5.11 @@ -1291,3 +1290,176 @@
    5.12  
    5.13      return status;
    5.14  }
    5.15 +
    5.16 +static PEP_STATUS find_single_key(
    5.17 +        PEP_SESSION session,
    5.18 +        const char *fpr,
    5.19 +        gpgme_key_t *key
    5.20 +    )
    5.21 +{
    5.22 +    gpgme_error_t gpgme_error;
    5.23 +
    5.24 +    *key = NULL;
    5.25 +
    5.26 +    gpgme_error = gpg.gpgme_op_keylist_start(session->ctx, fpr, 0);
    5.27 +    gpgme_error = _GPGERR(gpgme_error);
    5.28 +    switch (gpgme_error) {
    5.29 +    case GPG_ERR_NO_ERROR:
    5.30 +        break;
    5.31 +    case GPG_ERR_INV_VALUE:
    5.32 +        assert(0);
    5.33 +        return PEP_UNKNOWN_ERROR;
    5.34 +    default:
    5.35 +        return PEP_GET_KEY_FAILED;
    5.36 +    };
    5.37 +
    5.38 +    gpgme_error = gpg.gpgme_op_keylist_next(session->ctx, key);
    5.39 +    gpgme_error = _GPGERR(gpgme_error);
    5.40 +    assert(gpgme_error != GPG_ERR_INV_VALUE);
    5.41 +
    5.42 +    gpg.gpgme_op_keylist_end(session->ctx);
    5.43 +
    5.44 +    return PEP_STATUS_OK;
    5.45 +}
    5.46 +
    5.47 +typedef struct _renew_data {
    5.48 +    enum state_t {
    5.49 +        renew_command = 0,
    5.50 +        renew_date,
    5.51 +        renew_secret_key,
    5.52 +        renew_command2,
    5.53 +        renew_date2,
    5.54 +        renew_quit,
    5.55 +        renew_save,
    5.56 +        renew_exit,
    5.57 +        renew_error = -1
    5.58 +    } state;
    5.59 +    const char *fpr_ref;
    5.60 +} renew_data;
    5.61 +
    5.62 +static gpgme_error_t renew_player(
    5.63 +        void *_handle,
    5.64 +        gpgme_status_code_t statuscode,
    5.65 +        const char *args,
    5.66 +        int fd
    5.67 +    )
    5.68 +{
    5.69 +    renew_data *handle = _handle;
    5.70 +
    5.71 +    switch (handle->state) {
    5.72 +        case renew_command:
    5.73 +            if (statuscode == GPGME_STATUS_GET_LINE) {
    5.74 +                write(fd, "expire\n", 7);
    5.75 +                handle->state = renew_date;
    5.76 +            }
    5.77 +            break;
    5.78 +
    5.79 +        case renew_date:
    5.80 +            if (statuscode == GPGME_STATUS_GET_LINE) {
    5.81 +                write(fd, "2015-12-31\n", 11);
    5.82 +                handle->state = renew_secret_key;
    5.83 +            }
    5.84 +            break;
    5.85 +
    5.86 +        case renew_secret_key:
    5.87 +            if (statuscode == GPGME_STATUS_GET_LINE) {
    5.88 +                write(fd, "key 1\n", 6);
    5.89 +                handle->state = renew_command2;
    5.90 +            }
    5.91 +            break;
    5.92 +
    5.93 +        case renew_command2:
    5.94 +            if (statuscode == GPGME_STATUS_GET_LINE) {
    5.95 +                write(fd, "expire\n", 7);
    5.96 +                handle->state = renew_date2;
    5.97 +            }
    5.98 +            break;
    5.99 +
   5.100 +        case renew_date2:
   5.101 +            if (statuscode == GPGME_STATUS_GET_LINE) {
   5.102 +                write(fd, "2015-12-31\n", 11);
   5.103 +                handle->state = renew_quit;
   5.104 +            }
   5.105 +            break;
   5.106 +
   5.107 +        case renew_quit:
   5.108 +            if (statuscode == GPGME_STATUS_GET_LINE) {
   5.109 +                write(fd, "quit\n", 5);
   5.110 +                handle->state = renew_save;
   5.111 +            }
   5.112 +            break;
   5.113 +
   5.114 +        case renew_save:
   5.115 +            if (statuscode == GPGME_STATUS_GET_BOOL) {
   5.116 +                write(fd, "Y\n", 2);
   5.117 +                handle->state = renew_exit;
   5.118 +            }
   5.119 +            break;
   5.120 +
   5.121 +        case renew_exit:
   5.122 +            break;
   5.123 +
   5.124 +        case renew_error:
   5.125 +            return GPG_ERR_GENERAL;
   5.126 +    }
   5.127 +
   5.128 +    return GPG_ERR_NO_ERROR;
   5.129 +}
   5.130 +
   5.131 +static ssize_t _nullwriter(
   5.132 +        void *_handle,
   5.133 +        const void *buffer,
   5.134 +        size_t size
   5.135 +    )
   5.136 +{
   5.137 +    return size;
   5.138 +}
   5.139 +
   5.140 +PEP_STATUS pgp_renew_key(PEP_SESSION session, const char *fpr)
   5.141 +{
   5.142 +    PEP_STATUS status = PEP_STATUS_OK;
   5.143 +    gpgme_error_t gpgme_error;
   5.144 +    gpgme_key_t key;
   5.145 +    gpgme_data_t output;
   5.146 +    renew_data handle;
   5.147 +
   5.148 +    assert(session);
   5.149 +    assert(fpr);
   5.150 +
   5.151 +    memset(&handle, 0, sizeof(renew_data));
   5.152 +    handle.fpr_ref = fpr;
   5.153 +
   5.154 +    status = find_single_key(session, fpr, &key);
   5.155 +    if (status != PEP_STATUS_OK)
   5.156 +        return status;
   5.157 +
   5.158 +    struct gpgme_data_cbs data_cbs;
   5.159 +    memset(&data_cbs, 0, sizeof(struct gpgme_data_cbs));
   5.160 +    data_cbs.write = _nullwriter;
   5.161 +    gpgme_data_new_from_cbs(&output, &data_cbs, &handle);
   5.162 +
   5.163 +    gpgme_error = gpgme_op_edit(session->ctx, key, renew_player, &handle,
   5.164 +            output);
   5.165 +    assert(gpgme_error == GPG_ERR_NO_ERROR);
   5.166 +
   5.167 +    gpg.gpgme_data_release(output);
   5.168 +    gpg.gpgme_key_unref(key);
   5.169 +
   5.170 +    return PEP_STATUS_OK;
   5.171 +}
   5.172 +
   5.173 +PEP_STATUS pgp_revoke_key(PEP_SESSION session, const char *fpr)
   5.174 +{
   5.175 +    PEP_STATUS status = PEP_STATUS_OK;
   5.176 +    gpgme_key_t key;
   5.177 +    
   5.178 +    assert(session);
   5.179 +    assert(fpr);
   5.180 +
   5.181 +    status = find_single_key(session, fpr, &key);
   5.182 +    if (status != PEP_STATUS_OK)
   5.183 +        return status;
   5.184 +
   5.185 +    return PEP_STATUS_OK;
   5.186 +}
   5.187 +
     6.1 --- a/src/pgp_gpg.h	Fri Apr 17 10:55:56 2015 +0200
     6.2 +++ b/src/pgp_gpg.h	Mon Apr 20 15:59:13 2015 +0200
     6.3 @@ -44,6 +44,7 @@
     6.4          size_t size);
     6.5  
     6.6  PEP_STATUS pgp_recv_key(PEP_SESSION session, const char *pattern);
     6.7 +PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern);
     6.8 +PEP_STATUS pgp_renew_key(PEP_SESSION session, const char *fpr);
     6.9 +PEP_STATUS pgp_revoke_key(PEP_SESSION session, const char *fpr);
    6.10  
    6.11 -PEP_STATUS pgp_send_key(PEP_SESSION session, const char *pattern);
    6.12 -
     7.1 --- a/test/Makefile	Fri Apr 17 10:55:56 2015 +0200
     7.2 +++ b/test/Makefile	Mon Apr 20 15:59:13 2015 +0200
     7.3 @@ -29,7 +29,7 @@
     7.4  
     7.5  unit_tests: $(UNIT_TESTS)
     7.6  	for t in ./*_test ; do \
     7.7 -		LD_LIBRARY_PATH=~/lib:../src $$t ; \
     7.8 +		if LD_LIBRARY_PATH=~/lib:../src $$t ; then true; else break; fi \
     7.9  	done
    7.10  
    7.11  install: