Re: [gmime-devel] [PATCH 6/6] Support extraction of session keys during decryption.
On 12/2/2016 7:48 PM, Daniel Kahn Gillmor wrote: On Fri 2016-12-02 18:52:04 -0500, Jeffrey Stedfast wrote: On 12/2/2016 3:31 PM, Daniel Kahn Gillmor wrote: (and hm, actually, maybe that means we should be zeroing the RAM before releasing the stored session key; i can make that change if that sounds good to you) Yes, please :) thanks for scrubbing the ram already :) the other advantage for keeping this command is that it makes it clearer in the API which cryptocontexts are capable of this kind of operation. Would it be better to make this function part of the GMimeCryptoContext API instead of the GMimeGpgContext, though? If the plan is to also add it to the S/MIME context, then yes. I have no idea whether it makes sense to add it to the S/MIME context -- it might, but i haven't tried. i don't think S/MIME can do decryption anyway yet, can it? What API would you prefer for a "try-this-session-key" approach? I see two mechanisms: (a) give the session key to the context for any number of subsequent decryptions until it is cleared or re-set: g_mime_gpg_context_set_session_key_for_decryption() g_mime_gpg_context_clear_session_key_for_decryption() This is a bit awkward, though: what should happen if the wrong session key is given; should it fall back to trying to use the available public keys? if so, then we'd need to do some fancy footwork, because gpg simply fails to decrypt if you give it the wrong session key. (b) have some variation on g_mime_multipart_encrypted_decrypt() or g_mime_crypto_context_decrypt(), which has an additional parameter of "session_key". (b) makes the most sense. Perhaps g_mime_crypto_context_decrypt_session? and a g_mime_multipart_encrypted_decrypt_session() as well? I can work on this patch if it's something that you'd like. --dkg I am not in a rush to have it since at this moment, you are the only one using the session_key at all and you don't seem to need it in any sort of immediate timeframe. I was more just curious. Feel free to implement as time and/or desire permits. Jeff ___ gmime-devel-list mailing list gmime-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gmime-devel-list
Re: [gmime-devel] [PATCH 6/6] Support extraction of session keys during decryption.
On Fri 2016-12-02 18:52:04 -0500, Jeffrey Stedfast wrote: > On 12/2/2016 3:31 PM, Daniel Kahn Gillmor wrote: >> (and hm, actually, maybe that means we should be zeroing the RAM before >> releasing the stored session key; i can make that change if that sounds >> good to you) > > Yes, please :) thanks for scrubbing the ram already :) >> the other advantage for keeping this command is that it makes it clearer >> in the API which cryptocontexts are capable of this kind of operation. >> Would it be better to make this function part of the GMimeCryptoContext >> API instead of the GMimeGpgContext, though? > > If the plan is to also add it to the S/MIME context, then yes. I have no idea whether it makes sense to add it to the S/MIME context -- it might, but i haven't tried. i don't think S/MIME can do decryption anyway yet, can it? >> What API would you prefer for a "try-this-session-key" approach? I see >> two mechanisms: >> >> (a) give the session key to the context for any number of subsequent >> decryptions until it is cleared or re-set: >> >> g_mime_gpg_context_set_session_key_for_decryption() >> g_mime_gpg_context_clear_session_key_for_decryption() >> >> This is a bit awkward, though: what should happen if the wrong >> session key is given; should it fall back to trying to use the >> available public keys? if so, then we'd need to do some fancy >> footwork, because gpg simply fails to decrypt if you give it the >> wrong session key. >> >> >> (b) have some variation on g_mime_multipart_encrypted_decrypt() or >> g_mime_crypto_context_decrypt(), which has an additional parameter >> of "session_key". > > (b) makes the most sense. > > Perhaps g_mime_crypto_context_decrypt_session? and a g_mime_multipart_encrypted_decrypt_session() as well? I can work on this patch if it's something that you'd like. --dkg signature.asc Description: PGP signature ___ gmime-devel-list mailing list gmime-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gmime-devel-list
Re: [gmime-devel] [PATCH 6/6] Support extraction of session keys during decryption.
On 12/2/2016 3:31 PM, Daniel Kahn Gillmor wrote: On Fri 2016-12-02 10:37:38 -0500, Jeffrey Stedfast wrote: I just read the man page for gpg's --show-session-key and --override-session-key. It looks like the gpg authors advise against using it unless you need to (while providing what they feel is a valuable use-case). So I guess that answers my question. I think the way to think about this is that the session key is a bit of secret key material, capable on its own of decrypting the secret message. If a user deletes the resultant cleartext MIME part but somehow fails to delete the DecryptResult, then someone who gets access to the DecryptResult can decrypt the ciphertext again. That seems like "opt in" behavior to me. Right. (and hm, actually, maybe that means we should be zeroing the RAM before releasing the stored session key; i can make that change if that sounds good to you) Yes, please :) the other advantage for keeping this command is that it makes it clearer in the API which cryptocontexts are capable of this kind of operation. Would it be better to make this function part of the GMimeCryptoContext API instead of the GMimeGpgContext, though? If the plan is to also add it to the S/MIME context, then yes. However, I have another question which is: Do we want to have an API to allow the use of a session-key when decrypting? yes, ultimately, we'll want something like that, but it's something that'd belong in a follow-on patch. just extracting the session key data is the first step. What API would you prefer for a "try-this-session-key" approach? I see two mechanisms: (a) give the session key to the context for any number of subsequent decryptions until it is cleared or re-set: g_mime_gpg_context_set_session_key_for_decryption() g_mime_gpg_context_clear_session_key_for_decryption() This is a bit awkward, though: what should happen if the wrong session key is given; should it fall back to trying to use the available public keys? if so, then we'd need to do some fancy footwork, because gpg simply fails to decrypt if you give it the wrong session key. (b) have some variation on g_mime_multipart_encrypted_decrypt() or g_mime_crypto_context_decrypt(), which has an additional parameter of "session_key". (b) makes the most sense. Perhaps g_mime_crypto_context_decrypt_session? I really wish C allowed method overloading :( Jeff ___ gmime-devel-list mailing list gmime-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gmime-devel-list
Re: [gmime-devel] [PATCH 6/6] Support extraction of session keys during decryption.
On Fri 2016-12-02 10:37:38 -0500, Jeffrey Stedfast wrote: > I just read the man page for gpg's --show-session-key and > --override-session-key. > > It looks like the gpg authors advise against using it unless you need to > (while providing what they feel is a valuable use-case). > > So I guess that answers my question. I think the way to think about this is that the session key is a bit of secret key material, capable on its own of decrypting the secret message. If a user deletes the resultant cleartext MIME part but somehow fails to delete the DecryptResult, then someone who gets access to the DecryptResult can decrypt the ciphertext again. That seems like "opt in" behavior to me. (and hm, actually, maybe that means we should be zeroing the RAM before releasing the stored session key; i can make that change if that sounds good to you) the other advantage for keeping this command is that it makes it clearer in the API which cryptocontexts are capable of this kind of operation. Would it be better to make this function part of the GMimeCryptoContext API instead of the GMimeGpgContext, though? > However, I have another question which is: Do we want to have an API to > allow the use of a session-key when decrypting? yes, ultimately, we'll want something like that, but it's something that'd belong in a follow-on patch. just extracting the session key data is the first step. What API would you prefer for a "try-this-session-key" approach? I see two mechanisms: (a) give the session key to the context for any number of subsequent decryptions until it is cleared or re-set: g_mime_gpg_context_set_session_key_for_decryption() g_mime_gpg_context_clear_session_key_for_decryption() This is a bit awkward, though: what should happen if the wrong session key is given; should it fall back to trying to use the available public keys? if so, then we'd need to do some fancy footwork, because gpg simply fails to decrypt if you give it the wrong session key. (b) have some variation on g_mime_multipart_encrypted_decrypt() or g_mime_crypto_context_decrypt(), which has an additional parameter of "session_key". Any other suggestions? --dkg ___ gmime-devel-list mailing list gmime-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gmime-devel-list
Re: [gmime-devel] [PATCH 6/6] Support extraction of session keys during decryption.
I just read the man page for gpg's --show-session-key and --override-session-key. It looks like the gpg authors advise against using it unless you need to (while providing what they feel is a valuable use-case). So I guess that answers my question. However, I have another question which is: Do we want to have an API to allow the use of a session-key when decrypting? Jeff On 12/2/2016 10:20 AM, Jeffrey Stedfast wrote: Overall this patch looks good to me, but I am wondering if there is a reason to have the retrieve_session_key API? I guess what I am asking is why would we *not* want to default to *always* retrieving the session key in GMime? Does it pose a security risk? I think that if it's not a risk, we might as well just always request it to simplify things. Do you agree? Jeff On 12/2/2016 2:02 AM, Daniel Kahn Gillmor wrote: Some message stores can be optimized by caching session keys of encrypted messages, rather than incurring asymmetric crypto operations on each subsequent decryption. This patch allows gmime to perform extraction of session keys during message decryption to support that use case. See the discussion starting here for more detail on the API/design choices: https://mail.gnome.org/archives/gmime-devel-list/2016-July/msg5.html --- gmime/gmime-crypto-context.c | 41 gmime/gmime-crypto-context.h | 4 gmime/gmime-gpg-context.c| 50 +++- gmime/gmime-gpg-context.h| 4 tests/test-pgp.c | 5 + tests/test-pgpmime.c | 9 +++- 6 files changed, 111 insertions(+), 2 deletions(-) diff --git a/gmime/gmime-crypto-context.c b/gmime/gmime-crypto-context.c index 5269440..90fa390 100644 --- a/gmime/gmime-crypto-context.c +++ b/gmime/gmime-crypto-context.c @@ -573,6 +573,7 @@ g_mime_decrypt_result_init (GMimeDecryptResult *result, GMimeDecryptResultClass result->mdc = GMIME_DIGEST_ALGO_DEFAULT; result->recipients = NULL; result->signatures = NULL; +result->session_key = NULL; } static void @@ -586,6 +587,8 @@ g_mime_decrypt_result_finalize (GObject *object) if (result->signatures) g_object_unref (result->signatures); +g_free (result->session_key); + G_OBJECT_CLASS (result_parent_class)->finalize (object); } @@ -755,3 +758,41 @@ g_mime_decryption_result_get_mdc (GMimeDecryptResult *result) return result->mdc; } + + +/** + * g_mime_decrypt_result_set_session_key: + * @result: a #GMimeDecryptResult + * @session_key: a pointer to a null-terminated string representing the session key + * + * Set the session_key to be returned by this decryption result. + **/ +void +g_mime_decrypt_result_set_session_key (GMimeDecryptResult *result, const char *session_key) +{ +g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result)); + +g_free (result->session_key); +result->session_key = g_strdup(session_key); +} + + +/** + * g_mime_decrypt_result_get_session_key: + * @result: a #GMimeDecryptResult + * + * Get the session_key used for this decryption, if the underlying + * crypto context is capable of and (configured to) retrieve session + * keys during decryption. See, for example, + * g_mime_gpg_context_set_retrieve_session_key(). + * + * Returns: the session_key digest algorithm used, or NULL if no + * session key was requested or found. + **/ +const char* +g_mime_decryption_result_get_session_key (GMimeDecryptResult *result) +{ +g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), GMIME_DIGEST_ALGO_DEFAULT); + +return result->session_key; +} diff --git a/gmime/gmime-crypto-context.h b/gmime/gmime-crypto-context.h index cd38760..72573ed 100644 --- a/gmime/gmime-crypto-context.h +++ b/gmime/gmime-crypto-context.h @@ -206,6 +206,7 @@ struct _GMimeDecryptResult { GMimeSignatureList *signatures; GMimeCipherAlgo cipher; GMimeDigestAlgo mdc; +char *session_key; }; struct _GMimeDecryptResultClass { @@ -229,6 +230,9 @@ GMimeCipherAlgo g_mime_decrypt_result_get_cipher (GMimeDecryptResult *result); void g_mime_decrypt_result_set_mdc (GMimeDecryptResult *result, GMimeDigestAlgo mdc); GMimeDigestAlgo g_mime_decrypt_result_get_mdc (GMimeDecryptResult *result); +void g_mime_decrypt_result_set_session_key (GMimeDecryptResult *result, const char *session_key); +const char *g_mime_decrypt_result_get_session_key (GMimeDecryptResult *result); + G_END_DECLS #endif /* __GMIME_CRYPTO_CONTEXT_H__ */ diff --git a/gmime/gmime-gpg-context.c b/gmime/gmime-gpg-context.c index 2ca280a..6f7d374 100644 --- a/gmime/gmime-gpg-context.c +++ b/gmime/gmime-gpg-context.c @@ -172,6 +172,7 @@ g_mime_gpg_context_init (GMimeGpgContext *ctx, GMimeGpgContextClass *klass) ctx->always_trust = FALSE; ctx->use_agent = FALSE; ctx->path = NULL; +ctx->retrieve_session_key = FALSE; } static void @@ -311,6 +312,7 @@ struct _GpgCtx {
Re: [gmime-devel] [PATCH 6/6] Support extraction of session keys during decryption.
Overall this patch looks good to me, but I am wondering if there is a reason to have the retrieve_session_key API? I guess what I am asking is why would we *not* want to default to *always* retrieving the session key in GMime? Does it pose a security risk? I think that if it's not a risk, we might as well just always request it to simplify things. Do you agree? Jeff On 12/2/2016 2:02 AM, Daniel Kahn Gillmor wrote: Some message stores can be optimized by caching session keys of encrypted messages, rather than incurring asymmetric crypto operations on each subsequent decryption. This patch allows gmime to perform extraction of session keys during message decryption to support that use case. See the discussion starting here for more detail on the API/design choices: https://mail.gnome.org/archives/gmime-devel-list/2016-July/msg5.html --- gmime/gmime-crypto-context.c | 41 gmime/gmime-crypto-context.h | 4 gmime/gmime-gpg-context.c| 50 +++- gmime/gmime-gpg-context.h| 4 tests/test-pgp.c | 5 + tests/test-pgpmime.c | 9 +++- 6 files changed, 111 insertions(+), 2 deletions(-) diff --git a/gmime/gmime-crypto-context.c b/gmime/gmime-crypto-context.c index 5269440..90fa390 100644 --- a/gmime/gmime-crypto-context.c +++ b/gmime/gmime-crypto-context.c @@ -573,6 +573,7 @@ g_mime_decrypt_result_init (GMimeDecryptResult *result, GMimeDecryptResultClass result->mdc = GMIME_DIGEST_ALGO_DEFAULT; result->recipients = NULL; result->signatures = NULL; + result->session_key = NULL; } static void @@ -586,6 +587,8 @@ g_mime_decrypt_result_finalize (GObject *object) if (result->signatures) g_object_unref (result->signatures); + g_free (result->session_key); + G_OBJECT_CLASS (result_parent_class)->finalize (object); } @@ -755,3 +758,41 @@ g_mime_decryption_result_get_mdc (GMimeDecryptResult *result) return result->mdc; } + + +/** + * g_mime_decrypt_result_set_session_key: + * @result: a #GMimeDecryptResult + * @session_key: a pointer to a null-terminated string representing the session key + * + * Set the session_key to be returned by this decryption result. + **/ +void +g_mime_decrypt_result_set_session_key (GMimeDecryptResult *result, const char *session_key) +{ + g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result)); + + g_free (result->session_key); + result->session_key = g_strdup(session_key); +} + + +/** + * g_mime_decrypt_result_get_session_key: + * @result: a #GMimeDecryptResult + * + * Get the session_key used for this decryption, if the underlying + * crypto context is capable of and (configured to) retrieve session + * keys during decryption. See, for example, + * g_mime_gpg_context_set_retrieve_session_key(). + * + * Returns: the session_key digest algorithm used, or NULL if no + * session key was requested or found. + **/ +const char* +g_mime_decryption_result_get_session_key (GMimeDecryptResult *result) +{ + g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), GMIME_DIGEST_ALGO_DEFAULT); + + return result->session_key; +} diff --git a/gmime/gmime-crypto-context.h b/gmime/gmime-crypto-context.h index cd38760..72573ed 100644 --- a/gmime/gmime-crypto-context.h +++ b/gmime/gmime-crypto-context.h @@ -206,6 +206,7 @@ struct _GMimeDecryptResult { GMimeSignatureList *signatures; GMimeCipherAlgo cipher; GMimeDigestAlgo mdc; + char *session_key; }; struct _GMimeDecryptResultClass { @@ -229,6 +230,9 @@ GMimeCipherAlgo g_mime_decrypt_result_get_cipher (GMimeDecryptResult *result); void g_mime_decrypt_result_set_mdc (GMimeDecryptResult *result, GMimeDigestAlgo mdc); GMimeDigestAlgo g_mime_decrypt_result_get_mdc (GMimeDecryptResult *result); +void g_mime_decrypt_result_set_session_key (GMimeDecryptResult *result, const char *session_key); +const char *g_mime_decrypt_result_get_session_key (GMimeDecryptResult *result); + G_END_DECLS #endif /* __GMIME_CRYPTO_CONTEXT_H__ */ diff --git a/gmime/gmime-gpg-context.c b/gmime/gmime-gpg-context.c index 2ca280a..6f7d374 100644 --- a/gmime/gmime-gpg-context.c +++ b/gmime/gmime-gpg-context.c @@ -172,6 +172,7 @@ g_mime_gpg_context_init (GMimeGpgContext *ctx, GMimeGpgContextClass *klass) ctx->always_trust = FALSE; ctx->use_agent = FALSE; ctx->path = NULL; + ctx->retrieve_session_key = FALSE; } static void @@ -311,6 +312,7 @@ struct _GpgCtx { GMimeStream *diagnostics; GMimeCertificateList *encrypted_to; /* full list of encrypted-to recipients */ + char *session_key; GMimeSignatureList *signatures; GMimeSignature *signature; @@ -375,6 +377,7 @@ gpg_ctx_new (GMimeGpgContext *ctx) gpg->need_id = NULL;
[gmime-devel] [PATCH 6/6] Support extraction of session keys during decryption.
Some message stores can be optimized by caching session keys of encrypted messages, rather than incurring asymmetric crypto operations on each subsequent decryption. This patch allows gmime to perform extraction of session keys during message decryption to support that use case. See the discussion starting here for more detail on the API/design choices: https://mail.gnome.org/archives/gmime-devel-list/2016-July/msg5.html --- gmime/gmime-crypto-context.c | 41 gmime/gmime-crypto-context.h | 4 gmime/gmime-gpg-context.c| 50 +++- gmime/gmime-gpg-context.h| 4 tests/test-pgp.c | 5 + tests/test-pgpmime.c | 9 +++- 6 files changed, 111 insertions(+), 2 deletions(-) diff --git a/gmime/gmime-crypto-context.c b/gmime/gmime-crypto-context.c index 5269440..90fa390 100644 --- a/gmime/gmime-crypto-context.c +++ b/gmime/gmime-crypto-context.c @@ -573,6 +573,7 @@ g_mime_decrypt_result_init (GMimeDecryptResult *result, GMimeDecryptResultClass result->mdc = GMIME_DIGEST_ALGO_DEFAULT; result->recipients = NULL; result->signatures = NULL; + result->session_key = NULL; } static void @@ -586,6 +587,8 @@ g_mime_decrypt_result_finalize (GObject *object) if (result->signatures) g_object_unref (result->signatures); + g_free (result->session_key); + G_OBJECT_CLASS (result_parent_class)->finalize (object); } @@ -755,3 +758,41 @@ g_mime_decryption_result_get_mdc (GMimeDecryptResult *result) return result->mdc; } + + +/** + * g_mime_decrypt_result_set_session_key: + * @result: a #GMimeDecryptResult + * @session_key: a pointer to a null-terminated string representing the session key + * + * Set the session_key to be returned by this decryption result. + **/ +void +g_mime_decrypt_result_set_session_key (GMimeDecryptResult *result, const char *session_key) +{ + g_return_if_fail (GMIME_IS_DECRYPT_RESULT (result)); + + g_free (result->session_key); + result->session_key = g_strdup(session_key); +} + + +/** + * g_mime_decrypt_result_get_session_key: + * @result: a #GMimeDecryptResult + * + * Get the session_key used for this decryption, if the underlying + * crypto context is capable of and (configured to) retrieve session + * keys during decryption. See, for example, + * g_mime_gpg_context_set_retrieve_session_key(). + * + * Returns: the session_key digest algorithm used, or NULL if no + * session key was requested or found. + **/ +const char* +g_mime_decryption_result_get_session_key (GMimeDecryptResult *result) +{ + g_return_val_if_fail (GMIME_IS_DECRYPT_RESULT (result), GMIME_DIGEST_ALGO_DEFAULT); + + return result->session_key; +} diff --git a/gmime/gmime-crypto-context.h b/gmime/gmime-crypto-context.h index cd38760..72573ed 100644 --- a/gmime/gmime-crypto-context.h +++ b/gmime/gmime-crypto-context.h @@ -206,6 +206,7 @@ struct _GMimeDecryptResult { GMimeSignatureList *signatures; GMimeCipherAlgo cipher; GMimeDigestAlgo mdc; + char *session_key; }; struct _GMimeDecryptResultClass { @@ -229,6 +230,9 @@ GMimeCipherAlgo g_mime_decrypt_result_get_cipher (GMimeDecryptResult *result); void g_mime_decrypt_result_set_mdc (GMimeDecryptResult *result, GMimeDigestAlgo mdc); GMimeDigestAlgo g_mime_decrypt_result_get_mdc (GMimeDecryptResult *result); +void g_mime_decrypt_result_set_session_key (GMimeDecryptResult *result, const char *session_key); +const char *g_mime_decrypt_result_get_session_key (GMimeDecryptResult *result); + G_END_DECLS #endif /* __GMIME_CRYPTO_CONTEXT_H__ */ diff --git a/gmime/gmime-gpg-context.c b/gmime/gmime-gpg-context.c index 2ca280a..6f7d374 100644 --- a/gmime/gmime-gpg-context.c +++ b/gmime/gmime-gpg-context.c @@ -172,6 +172,7 @@ g_mime_gpg_context_init (GMimeGpgContext *ctx, GMimeGpgContextClass *klass) ctx->always_trust = FALSE; ctx->use_agent = FALSE; ctx->path = NULL; + ctx->retrieve_session_key = FALSE; } static void @@ -311,6 +312,7 @@ struct _GpgCtx { GMimeStream *diagnostics; GMimeCertificateList *encrypted_to; /* full list of encrypted-to recipients */ + char *session_key; GMimeSignatureList *signatures; GMimeSignature *signature; @@ -375,6 +377,7 @@ gpg_ctx_new (GMimeGpgContext *ctx) gpg->need_id = NULL; gpg->encrypted_to = NULL; + gpg->session_key = NULL; gpg->signatures = NULL; gpg->signature = NULL; @@ -555,6 +558,8 @@ gpg_ctx_free (struct _GpgCtx *gpg) if (gpg->encrypted_to) g_object_unref (gpg->encrypted_to); + g_free (gpg->session_key); + if (gpg->signatures) g_object_unref (gpg->signatures); @@ -691,6 +696,9 @@ gpg_ctx_get_argv (struct _GpgCtx *gpg, int