gpg and internal API changes for ENGINE-172 implemented and tested (no-sign); no-key not in yet

doc_update_sequoia
Krista Grothoff 6 years ago
parent bb5c734f46
commit 6e01c347d8

@ -36,6 +36,7 @@ PEP_STATUS init_cryptotech(PEP_SESSION session, bool in_first)
cryptotech[PEP_crypt_OpenPGP].confirmed_comm_type = PEP_ct_OpenPGP;
cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify = pgp_decrypt_and_verify;
cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign = pgp_encrypt_and_sign;
cryptotech[PEP_crypt_OpenPGP].encrypt_only = pgp_encrypt_only;
cryptotech[PEP_crypt_OpenPGP].verify_text = pgp_verify_text;
cryptotech[PEP_crypt_OpenPGP].delete_keypair = pgp_delete_keypair;
cryptotech[PEP_crypt_OpenPGP].export_key = pgp_export_keydata;

@ -32,6 +32,11 @@ typedef PEP_STATUS (*encrypt_and_sign_t)(
size_t psize, char **ctext, size_t *csize
);
typedef PEP_STATUS (*encrypt_only_t)(
PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
size_t psize, char **ctext, size_t *csize
);
typedef PEP_STATUS (*delete_keypair_t)(PEP_SESSION session, const char *fpr);
typedef PEP_STATUS (*export_key_t)(
@ -92,6 +97,7 @@ typedef struct _PEP_cryptotech_t {
decrypt_and_verify_t decrypt_and_verify;
verify_text_t verify_text;
encrypt_and_sign_t encrypt_and_sign;
encrypt_only_t encrypt_only;
delete_keypair_t delete_keypair;
export_key_t export_key;
find_keys_t find_keys;

@ -779,10 +779,10 @@ DYNAMIC_API PEP_STATUS trust_personal_key(
assert(!EMPTYSTR(ident->address));
assert(!EMPTYSTR(ident->user_id));
assert(!EMPTYSTR(ident->fpr));
assert(!ident->me);
// assert(!ident->me);
if (!ident || EMPTYSTR(ident->address) || EMPTYSTR(ident->user_id) ||
EMPTYSTR(ident->fpr) || ident->me)
EMPTYSTR(ident->fpr)) // || ident->me)
return PEP_ILLEGAL_VALUE;
status = update_identity(session, ident);

@ -340,7 +340,8 @@ static PEP_STATUS encrypt_PGP_MIME(
PEP_SESSION session,
const message *src,
stringlist_t *keys,
message *dst
message *dst,
PEP_encrypt_flags_t flags
)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -396,8 +397,12 @@ static PEP_STATUS encrypt_PGP_MIME(
if (mimetext == NULL)
goto pep_error;
status = encrypt_and_sign(session, keys, mimetext, strlen(mimetext),
&ctext, &csize);
if (flags & PEP_encrypt_flag_force_unsigned)
status = encrypt_only(session, keys, mimetext, strlen(mimetext),
&ctext, &csize);
else
status = encrypt_and_sign(session, keys, mimetext, strlen(mimetext),
&ctext, &csize);
free(mimetext);
if (ctext == NULL)
goto pep_error;
@ -439,7 +444,8 @@ static PEP_STATUS encrypt_PGP_in_pieces(
PEP_SESSION session,
const message *src,
stringlist_t *keys,
message *dst
message *dst,
PEP_encrypt_flags_t flags
)
{
PEP_STATUS status = PEP_STATUS_OK;
@ -453,6 +459,8 @@ static PEP_STATUS encrypt_PGP_in_pieces(
dst->enc_format = PEP_enc_pieces;
bool nosign = (flags & PEP_encrypt_flag_force_unsigned);
if (src->shortmsg && src->shortmsg[0] && strcmp(src->shortmsg, "pEp") != 0) {
if (session->unencrypted_subject) {
dst->shortmsg = strdup(src->shortmsg);
@ -468,8 +476,12 @@ static PEP_STATUS encrypt_PGP_in_pieces(
free_ptext = true;
}
status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
&csize);
if (nosign)
status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
&csize);
else
status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
&csize);
if (free_ptext)
free(ptext);
free_ptext = false;
@ -482,8 +494,12 @@ static PEP_STATUS encrypt_PGP_in_pieces(
}
else if (src->longmsg && src->longmsg[0]) {
ptext = src->longmsg;
status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
&csize);
if (nosign)
status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
&csize);
else
status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
&csize);
if (ctext) {
dst->longmsg = ctext;
}
@ -500,8 +516,12 @@ static PEP_STATUS encrypt_PGP_in_pieces(
if (src->longmsg_formatted && src->longmsg_formatted[0]) {
ptext = src->longmsg_formatted;
status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
&csize);
if (nosign)
status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
&csize);
else
status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
&csize);
if (ctext) {
bloblist_t *_a = bloblist_add(dst->attachments, ctext, csize,
@ -535,8 +555,12 @@ static PEP_STATUS encrypt_PGP_in_pieces(
else {
size_t psize = _s->size;
ptext = _s->value;
status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
&csize);
if (nosign)
status = encrypt_only(session, keys, ptext, psize, &ctext,
&csize);
else
status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
&csize);
if (ctext) {
char *filename = NULL;
@ -1187,11 +1211,11 @@ DYNAMIC_API PEP_STATUS encrypt_message(
switch (enc_format) {
case PEP_enc_PGP_MIME:
case PEP_enc_PEP: // BUG: should be implemented extra
status = encrypt_PGP_MIME(session, src, keys, msg);
status = encrypt_PGP_MIME(session, src, keys, msg, flags);
break;
case PEP_enc_pieces:
status = encrypt_PGP_in_pieces(session, src, keys, msg);
status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
break;
/* case PEP_enc_PEP:
@ -1298,11 +1322,11 @@ DYNAMIC_API PEP_STATUS encrypt_message_for_self(
switch (enc_format) {
case PEP_enc_PGP_MIME:
case PEP_enc_PEP: // BUG: should be implemented extra
status = encrypt_PGP_MIME(session, src, keys, msg);
status = encrypt_PGP_MIME(session, src, keys, msg, flags);
break;
case PEP_enc_pieces:
status = encrypt_PGP_in_pieces(session, src, keys, msg);
status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
break;
/* case PEP_enc_PEP:

@ -23,6 +23,8 @@ PEP_cryptotech determine_encryption_format(message *msg);
void add_opt_field(message *msg, const char *name, const char *value);
typedef enum _PEP_encrypt_flags {
// "default" means whatever the default behaviour for the function is.
PEP_encrypt_flag_default = 0x0,
PEP_encrypt_flag_force_encryption = 0x1,
// This flag is for special use cases and should not be used
@ -383,4 +385,3 @@ DYNAMIC_API PEP_STATUS get_message_trustwords(
#ifdef __cplusplus
}
#endif

@ -1477,6 +1477,26 @@ DYNAMIC_API PEP_STATUS encrypt_and_sign(
keylist, ptext, psize, ctext, csize);
}
PEP_STATUS encrypt_only(
PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
size_t psize, char **ctext, size_t *csize
)
{
assert(session);
assert(keylist);
assert(ptext);
assert(psize);
assert(ctext);
assert(csize);
if (!(session && keylist && ptext && psize && ctext && csize))
return PEP_ILLEGAL_VALUE;
return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
keylist, ptext, psize, ctext, csize);
}
DYNAMIC_API PEP_STATUS verify_text(
PEP_SESSION session, const char *text, size_t size,
const char *signature, size_t sig_size, stringlist_t **keylist

@ -167,6 +167,12 @@ struct _pEpSession {
PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first);
void release_transport_system(PEP_SESSION session, bool out_last);
/* NOT to be exposed to the outside!!! */
PEP_STATUS encrypt_only(
PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
size_t psize, char **ctext, size_t *csize
);
#ifdef NDEBUG
#define DEBUG_LOG(TITLE, ENTITY, DESC)
#define LOGD(...)

@ -250,6 +250,11 @@ PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
"gpgme_op_encrypt_sign");
assert(gpg.gpgme_op_encrypt_sign);
gpg.gpgme_op_encrypt
= (gpgme_op_encrypt_t) (intptr_t) dlsym(gpgme,
"gpgme_op_encrypt");
assert(gpg.gpgme_op_encrypt);
gpg.gpgme_op_verify_result
= (gpgme_op_verify_result_t) (intptr_t) dlsym(gpgme,
"gpgme_op_verify_result");
@ -873,11 +878,12 @@ PEP_STATUS pgp_verify_text(
return result;
}
PEP_STATUS pgp_encrypt_and_sign(
static PEP_STATUS pgp_encrypt_sign_optional(
PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
size_t psize, char **ctext, size_t *csize
)
{
size_t psize, char **ctext, size_t *csize, bool sign
)
{
PEP_STATUS result;
gpgme_error_t gpgme_error;
gpgme_data_t plain, cipher;
@ -943,7 +949,7 @@ PEP_STATUS pgp_encrypt_and_sign(
gpg.gpgme_data_release(cipher);
return PEP_OUT_OF_MEMORY;
case GPG_ERR_NO_ERROR:
if (i == 0) {
if (i == 0 && sign) {
gpgme_error_t _gpgme_error = gpg.gpgme_signers_add(session->ctx, rcpt[0]);
_gpgme_error = _GPGERR(_gpgme_error);
assert(_gpgme_error == GPG_ERR_NO_ERROR);
@ -976,9 +982,16 @@ PEP_STATUS pgp_encrypt_and_sign(
// TODO: remove that and replace with proper key management
flags = GPGME_ENCRYPT_ALWAYS_TRUST;
gpgme_error = gpg.gpgme_op_encrypt_sign(session->ctx, rcpt, flags,
plain, cipher);
if (sign) {
gpgme_error = gpg.gpgme_op_encrypt_sign(session->ctx, rcpt, flags,
plain, cipher);
}
else {
gpgme_error = gpg.gpgme_op_encrypt(session->ctx, rcpt, flags,
plain, cipher);
}
gpgme_error = _GPGERR(gpgme_error);
switch (gpgme_error) {
case GPG_ERR_NO_ERROR:
@ -1024,6 +1037,24 @@ PEP_STATUS pgp_encrypt_and_sign(
return result;
}
PEP_STATUS pgp_encrypt_only(
PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
size_t psize, char **ctext, size_t *csize
)
{
return pgp_encrypt_sign_optional(session, keylist, ptext,
psize, ctext, csize, false);
}
PEP_STATUS pgp_encrypt_and_sign(
PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
size_t psize, char **ctext, size_t *csize
)
{
return pgp_encrypt_sign_optional(session, keylist, ptext,
psize, ctext, csize, true);
}
PEP_STATUS pgp_generate_keypair(
PEP_SESSION session, pEp_identity *identity
)

@ -19,6 +19,12 @@ PEP_STATUS pgp_encrypt_and_sign(
size_t psize, char **ctext, size_t *csize
);
PEP_STATUS pgp_encrypt_only(
PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
size_t psize, char **ctext, size_t *csize
);
PEP_STATUS pgp_verify_text(
PEP_SESSION session, const char *text, size_t size,
const char *signature, size_t sig_size, stringlist_t **keylist
@ -100,4 +106,3 @@ PEP_STATUS pgp_find_private_keys(
PEP_STATUS pgp_binary(const char **path);
#define PGP_BINARY_PATH pgp_binary

@ -43,6 +43,9 @@ typedef gpgme_decrypt_result_t(*gpgme_op_decrypt_result_t)(gpgme_ctx_t CTX);
typedef gpgme_error_t(*gpgme_op_encrypt_sign_t)(gpgme_ctx_t CTX,
gpgme_key_t RECP[], gpgme_encrypt_flags_t FLAGS, gpgme_data_t PLAIN,
gpgme_data_t CIPHER);
typedef gpgme_error_t(*gpgme_op_encrypt_t)(gpgme_ctx_t CTX,
gpgme_key_t RECP[], gpgme_encrypt_flags_t FLAGS, gpgme_data_t PLAIN,
gpgme_data_t CIPHER);
typedef gpgme_verify_result_t(*gpgme_op_verify_result_t)(gpgme_ctx_t CTX);
typedef void(*gpgme_signers_clear_t)(gpgme_ctx_t CTX);
typedef gpgme_error_t(*gpgme_signers_add_t)(gpgme_ctx_t CTX, const gpgme_key_t KEY);
@ -102,6 +105,7 @@ struct gpg_s {
gpgme_op_decrypt_verify_t gpgme_op_decrypt_verify;
gpgme_op_decrypt_result_t gpgme_op_decrypt_result;
gpgme_op_encrypt_sign_t gpgme_op_encrypt_sign;
gpgme_op_encrypt_t gpgme_op_encrypt;
gpgme_op_verify_result_t gpgme_op_verify_result;
gpgme_signers_clear_t gpgme_signers_clear;
gpgme_signers_add_t gpgme_signers_add;
@ -125,4 +129,3 @@ struct gpg_s {
gpgme_op_edit_t gpgme_op_edit;
gpgme_io_write_t gpgme_io_write;
};

@ -51,7 +51,7 @@ int main() {
cout << "encrypting message as MIME multipart…\n";
message* encrypted_msg = nullptr;
cout << "calling encrypt_message_for_identity()\n";
status = encrypt_message_for_self(session, alice, outgoing_message, &encrypted_msg, PEP_enc_PGP_MIME);
status = encrypt_message_for_self(session, alice, outgoing_message, &encrypted_msg, PEP_enc_PGP_MIME, PEP_encrypt_flag_default);
cout << "encrypt_message() returns " << std::hex << status << '.' << endl;
assert(status == PEP_STATUS_OK);
assert(encrypted_msg);

Loading…
Cancel
Save