pgp functions + high-level sign-text in, not compiled yet. fdik_sync
authorKrista Grothoff <krista@pep-project.org>
Wed, 15 Mar 2017 15:00:19 +0100
branchfdik_sync
changeset 1673559931685411
parent 1672 d4820ecaf7a2
child 1675 369041ac3724
pgp functions + high-level sign-text in, not compiled yet.
src/cryptotech.c
src/cryptotech.h
src/pEpEngine.c
src/pEp_internal.h
src/pgp_gpg.c
src/pgp_gpg.h
src/pgp_gpg_internal.h
src/pgp_netpgp.c
     1.1 --- a/src/cryptotech.c	Wed Mar 15 14:16:43 2017 +0100
     1.2 +++ b/src/cryptotech.c	Wed Mar 15 15:00:19 2017 +0100
     1.3 @@ -37,6 +37,7 @@
     1.4          cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify = pgp_decrypt_and_verify;
     1.5          cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign = pgp_encrypt_and_sign;
     1.6          cryptotech[PEP_crypt_OpenPGP].encrypt_only = pgp_encrypt_only;
     1.7 +        cryptotech[PEP_crypt_OpenPGP].sign_text = pgp_sign_text;
     1.8          cryptotech[PEP_crypt_OpenPGP].verify_text = pgp_verify_text;
     1.9          cryptotech[PEP_crypt_OpenPGP].delete_keypair = pgp_delete_keypair;
    1.10          cryptotech[PEP_crypt_OpenPGP].export_key = pgp_export_keydata;
     2.1 --- a/src/cryptotech.h	Wed Mar 15 14:16:43 2017 +0100
     2.2 +++ b/src/cryptotech.h	Wed Mar 15 15:00:19 2017 +0100
     2.3 @@ -37,6 +37,11 @@
     2.4          size_t psize, char **ctext, size_t *csize
     2.5      );
     2.6  
     2.7 +typedef PEP_STATUS (*sign_t)(
     2.8 +        PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
     2.9 +        size_t psize, char **stext, size_t *ssize
    2.10 +    );
    2.11 +
    2.12  typedef PEP_STATUS (*delete_keypair_t)(PEP_SESSION session, const char *fpr);
    2.13  
    2.14  typedef PEP_STATUS (*export_key_t)(
    2.15 @@ -98,6 +103,7 @@
    2.16      verify_text_t verify_text;
    2.17      encrypt_and_sign_t encrypt_and_sign;
    2.18      encrypt_only_t encrypt_only;
    2.19 +    sign_t sign_text;
    2.20      delete_keypair_t delete_keypair;
    2.21      export_key_t export_key;
    2.22      find_keys_t find_keys;
     3.1 --- a/src/pEpEngine.c	Wed Mar 15 14:16:43 2017 +0100
     3.2 +++ b/src/pEpEngine.c	Wed Mar 15 15:00:19 2017 +0100
     3.3 @@ -1498,6 +1498,24 @@
     3.4              keylist, ptext, psize, ctext, csize);
     3.5  }
     3.6  
     3.7 +PEP_STATUS sign_text(
     3.8 +    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
     3.9 +    size_t psize, char **stext, size_t *ssize
    3.10 +    )
    3.11 +{
    3.12 +    assert(session);
    3.13 +    assert(keylist);
    3.14 +    assert(ptext);
    3.15 +    assert(psize);
    3.16 +    assert(stext);
    3.17 +    assert(ssize);
    3.18 +
    3.19 +    if (!(session && keylist && ptext && psize && stext && ssize))
    3.20 +        return PEP_ILLEGAL_VALUE;
    3.21 +
    3.22 +    return session->cryptotech[PEP_crypt_OpenPGP].sign_text(session,
    3.23 +            keylist, ptext, psize, stext, ssize);
    3.24 +}
    3.25  
    3.26  DYNAMIC_API PEP_STATUS verify_text(
    3.27      PEP_SESSION session, const char *text, size_t size,
     4.1 --- a/src/pEp_internal.h	Wed Mar 15 14:16:43 2017 +0100
     4.2 +++ b/src/pEp_internal.h	Wed Mar 15 15:00:19 2017 +0100
     4.3 @@ -173,6 +173,13 @@
     4.4          size_t psize, char **ctext, size_t *csize
     4.5  );
     4.6  
     4.7 +/* NOT to be exposed to the outside!!! */
     4.8 +PEP_STATUS sign_text(
     4.9 +        PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
    4.10 +        size_t psize, char **stext, size_t *ssize
    4.11 +);
    4.12 +
    4.13 +
    4.14  #ifdef NDEBUG
    4.15  #define DEBUG_LOG(TITLE, ENTITY, DESC)
    4.16  #else
     5.1 --- a/src/pgp_gpg.c	Wed Mar 15 14:16:43 2017 +0100
     5.2 +++ b/src/pgp_gpg.c	Wed Mar 15 15:00:19 2017 +0100
     5.3 @@ -1055,6 +1055,153 @@
     5.4          psize, ctext, csize, true);
     5.5  }
     5.6  
     5.7 +PEP_STATUS pgp_sign_text(
     5.8 +    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
     5.9 +    size_t psize, char **stext, size_t *ssize
    5.10 +    )
    5.11 +{
    5.12 +    PEP_STATUS result;
    5.13 +    gpgme_error_t gpgme_error;
    5.14 +    gpgme_data_t plain, signeddata;
    5.15 +    gpgme_key_t *rcpt;
    5.16 +    gpgme_sig_mode_t sig_mode;
    5.17 +    const stringlist_t *_keylist;
    5.18 +    int i, j;
    5.19 +
    5.20 +    assert(session);
    5.21 +    assert(keylist);
    5.22 +    assert(ptext);
    5.23 +    assert(psize);
    5.24 +    assert(stext);
    5.25 +    assert(ssize);
    5.26 +
    5.27 +    *stext = NULL;
    5.28 +    *ssize = 0;
    5.29 +
    5.30 +    gpgme_error = gpg.gpgme_data_new_from_mem(&plain, ptext, psize, 0);
    5.31 +    gpgme_error = _GPGERR(gpgme_error);
    5.32 +    assert(gpgme_error == GPG_ERR_NO_ERROR);
    5.33 +    if (gpgme_error != GPG_ERR_NO_ERROR) {
    5.34 +        if (gpgme_error == GPG_ERR_ENOMEM)
    5.35 +            return PEP_OUT_OF_MEMORY;
    5.36 +        else
    5.37 +            return PEP_UNKNOWN_ERROR;
    5.38 +    }
    5.39 +
    5.40 +    gpgme_error = gpg.gpgme_data_new(&signeddata);
    5.41 +    gpgme_error = _GPGERR(gpgme_error);
    5.42 +    assert(gpgme_error == GPG_ERR_NO_ERROR);
    5.43 +    if (gpgme_error != GPG_ERR_NO_ERROR) {
    5.44 +        gpg.gpgme_data_release(plain);
    5.45 +        if (gpgme_error == GPG_ERR_ENOMEM)
    5.46 +            return PEP_OUT_OF_MEMORY;
    5.47 +        else
    5.48 +            return PEP_UNKNOWN_ERROR;
    5.49 +    }
    5.50 +
    5.51 +    /* FIXME: Why +1? */
    5.52 +    rcpt = calloc(2, sizeof(gpgme_key_t));
    5.53 +    assert(rcpt);
    5.54 +    if (rcpt == NULL) {
    5.55 +        gpg.gpgme_data_release(plain);
    5.56 +        gpg.gpgme_data_release(signeddata);
    5.57 +        return PEP_OUT_OF_MEMORY;
    5.58 +    }
    5.59 +
    5.60 +    gpg.gpgme_signers_clear(session->ctx);
    5.61 +
    5.62 +    assert(keylist->value);
    5.63 +    if (!keylist->value)
    5.64 +        return PEP_KEY_NOT_FOUND;
    5.65 +        
    5.66 +    gpgme_error = gpg.gpgme_get_key(session->ctx, _keylist->value,
    5.67 +        &rcpt[0], 0);
    5.68 +        
    5.69 +    gpgme_error = _GPGERR(gpgme_error);
    5.70 +    assert(gpgme_error != GPG_ERR_ENOMEM);
    5.71 +
    5.72 +    switch (gpgme_error) {
    5.73 +        case GPG_ERR_ENOMEM:
    5.74 +            gpg.gpgme_key_unref(rcpt[0]);
    5.75 +            free(rcpt);
    5.76 +            gpg.gpgme_data_release(plain);
    5.77 +            gpg.gpgme_data_release(signeddata);
    5.78 +            return PEP_OUT_OF_MEMORY;
    5.79 +        case GPG_ERR_NO_ERROR:
    5.80 +            gpgme_error_t _gpgme_error = gpg.gpgme_signers_add(session->ctx, rcpt[0]);
    5.81 +            _gpgme_error = _GPGERR(_gpgme_error);
    5.82 +            assert(_gpgme_error == GPG_ERR_NO_ERROR);
    5.83 +            break;
    5.84 +        case GPG_ERR_EOF:
    5.85 +            gpg.gpgme_key_unref(rcpt[0]);
    5.86 +            free(rcpt);
    5.87 +            gpg.gpgme_data_release(plain);
    5.88 +            gpg.gpgme_data_release(signeddata);
    5.89 +            return PEP_KEY_NOT_FOUND;
    5.90 +        case GPG_ERR_AMBIGUOUS_NAME:
    5.91 +            gpg.gpgme_key_unref(rcpt[0]);
    5.92 +            free(rcpt);
    5.93 +            gpg.gpgme_data_release(plain);
    5.94 +            gpg.gpgme_data_release(signeddata);
    5.95 +            return PEP_KEY_HAS_AMBIG_NAME;
    5.96 +        default: // GPG_ERR_INV_VALUE if CTX or R_KEY is not a valid pointer or
    5.97 +            // FPR is not a fingerprint or key ID
    5.98 +            gpg.gpgme_key_unref(rcpt[0]);
    5.99 +            free(rcpt);
   5.100 +            gpg.gpgme_data_release(plain);
   5.101 +            gpg.gpgme_data_release(signeddata);
   5.102 +            return PEP_GET_KEY_FAILED;
   5.103 +        }
   5.104 +    }
   5.105 +
   5.106 +    sig_mode = GPGME_SIG_MODE_NORMAL;
   5.107 +    
   5.108 +    gpgme_error = gpg.gpgme_op_sign(session->ctx, plain, signeddata, sig_mode);
   5.109 +    
   5.110 +    gpgme_error = _GPGERR(gpgme_error);
   5.111 +    switch (gpgme_error) {
   5.112 +    case GPG_ERR_NO_ERROR:
   5.113 +    {
   5.114 +        char *_buffer = NULL;
   5.115 +        size_t reading;
   5.116 +        size_t length = gpg.gpgme_data_seek(signeddata, 0, SEEK_END);
   5.117 +        assert(length != -1);
   5.118 +        gpg.gpgme_data_seek(signeddata, 0, SEEK_SET);
   5.119 +
   5.120 +        // TODO: make things less memory consuming
   5.121 +        // the following algorithm allocates a buffer for the complete text
   5.122 +
   5.123 +        _buffer = malloc(length + 1);
   5.124 +        assert(_buffer);
   5.125 +        if (_buffer == NULL) {
   5.126 +            for (j = 0; j<stringlist_length(keylist); j++)
   5.127 +                gpg.gpgme_key_unref(rcpt[j]);
   5.128 +            free(rcpt);
   5.129 +            gpg.gpgme_data_release(plain);
   5.130 +            gpg.gpgme_data_release(signeddata);
   5.131 +            return PEP_OUT_OF_MEMORY;
   5.132 +        }
   5.133 +
   5.134 +        reading = gpg.gpgme_data_read(signeddata, _buffer, length);
   5.135 +        assert(length == reading);
   5.136 +
   5.137 +        *stext = _buffer;
   5.138 +        *ssize = reading;
   5.139 +        (*stext)[*ssize] = 0; // safeguard for naive users
   5.140 +        result = PEP_STATUS_OK;
   5.141 +        break;
   5.142 +    }
   5.143 +    default:
   5.144 +        result = PEP_UNKNOWN_ERROR;
   5.145 +    }
   5.146 +
   5.147 +    gpg.gpgme_key_unref(rcpt[0]);
   5.148 +    free(rcpt);
   5.149 +    gpg.gpgme_data_release(plain);
   5.150 +    gpg.gpgme_data_release(signeddata);
   5.151 +    return result;
   5.152 +}
   5.153 +
   5.154  PEP_STATUS pgp_generate_keypair(
   5.155      PEP_SESSION session, pEp_identity *identity
   5.156      )
     6.1 --- a/src/pgp_gpg.h	Wed Mar 15 14:16:43 2017 +0100
     6.2 +++ b/src/pgp_gpg.h	Wed Mar 15 15:00:19 2017 +0100
     6.3 @@ -24,6 +24,11 @@
     6.4          size_t psize, char **ctext, size_t *csize
     6.5      );
     6.6  
     6.7 +PEP_STATUS pgp_sign_text(
     6.8 +        PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
     6.9 +        size_t psize, char **ctext, size_t *csize
    6.10 +    );
    6.11 +
    6.12  
    6.13  PEP_STATUS pgp_verify_text(
    6.14          PEP_SESSION session, const char *text, size_t size,
     7.1 --- a/src/pgp_gpg_internal.h	Wed Mar 15 14:16:43 2017 +0100
     7.2 +++ b/src/pgp_gpg_internal.h	Wed Mar 15 15:00:19 2017 +0100
     7.3 @@ -44,8 +44,10 @@
     7.4      gpgme_key_t RECP[], gpgme_encrypt_flags_t FLAGS, gpgme_data_t PLAIN,
     7.5      gpgme_data_t CIPHER);
     7.6  typedef gpgme_error_t(*gpgme_op_encrypt_t)(gpgme_ctx_t CTX,
     7.7 -        gpgme_key_t RECP[], gpgme_encrypt_flags_t FLAGS, gpgme_data_t PLAIN,
     7.8 -        gpgme_data_t CIPHER);
     7.9 +    gpgme_key_t RECP[], gpgme_encrypt_flags_t FLAGS, gpgme_data_t PLAIN,
    7.10 +    gpgme_data_t CIPHER);
    7.11 +typedef gpgme_error_t(*gpgme_op_sign_t)(gpgme_ctx_t CTX, gpgme_data_t PLAIN, 
    7.12 +    gpgme_data_t SIG, gpgme_sig_mode_t MODE);
    7.13  typedef gpgme_verify_result_t(*gpgme_op_verify_result_t)(gpgme_ctx_t CTX);
    7.14  typedef void(*gpgme_signers_clear_t)(gpgme_ctx_t CTX);
    7.15  typedef gpgme_error_t(*gpgme_signers_add_t)(gpgme_ctx_t CTX, const gpgme_key_t KEY);
    7.16 @@ -106,6 +108,7 @@
    7.17      gpgme_op_decrypt_result_t gpgme_op_decrypt_result;
    7.18      gpgme_op_encrypt_sign_t gpgme_op_encrypt_sign;
    7.19      gpgme_op_encrypt_t gpgme_op_encrypt;
    7.20 +    gpgme_op_sign_t gpgme_op_sign;
    7.21      gpgme_op_verify_result_t gpgme_op_verify_result;
    7.22      gpgme_signers_clear_t gpgme_signers_clear;
    7.23      gpgme_signers_add_t gpgme_signers_add;
     8.1 --- a/src/pgp_netpgp.c	Wed Mar 15 14:16:43 2017 +0100
     8.2 +++ b/src/pgp_netpgp.c	Wed Mar 15 15:00:19 2017 +0100
     8.3 @@ -687,6 +687,14 @@
     8.4      return result;
     8.5  }
     8.6  
     8.7 +PEP_STATUS pgp_sign_text(
     8.8 +    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
     8.9 +    size_t psize, char **stext, size_t *ssize
    8.10 +    )
    8.11 +{
    8.12 +    return PEP_UNKNOWN_ERROR; // We need a PEP_UNIMPLEMENTED, really.
    8.13 +}
    8.14 +
    8.15  PEP_STATUS pgp_generate_keypair(
    8.16      PEP_SESSION session, pEp_identity *identity
    8.17      )