"Private key not available");
return -1;
}
- dcrypt_key_ref_private(stream->priv_key);
} else {
io_stream_set_error(&stream->istream.iostream,
"Private key not available");
return -1;
}
if (ret > 0) {
- dcrypt_key_ref_private(stream->priv_key);
have_key = TRUE;
break;
}
};
/* Look for a private key for a specified public key digest and set it to
- priv_key_r. Returns 1 if ok, 0 if key doesn't exist, -1 on internal error. */
+ priv_key_r. Returns 1 if ok, 0 if key doesn't exist, -1 on internal error.
+
+ Note that the private key will be unreferenced when the istream is
+ destroyed. If the callback is returning a persistent key, it must reference
+ the key first. (This is required, because otherwise a key newly created by
+ the callback couldn't be automatically freed.) */
typedef int
i_stream_decrypt_get_key_callback_t(const char *pubkey_digest,
struct dcrypt_private_key **priv_key_r,
return -1;
*priv_key_r = mail_crypt_global_key_find(&file->fs->keys, pubkey_digest);
- return *priv_key_r == NULL ? 0 : 1;
+ if (*priv_key_r == NULL)
+ return 0;
+ dcrypt_key_ref_private(*priv_key_r);
+ return 1;
}
static struct istream *
*priv_key_r = mail_crypt_global_key_find(&muser->global_keys,
pubkey_digest);
- if (*priv_key_r != NULL) return 1;
+ if (*priv_key_r != NULL) {
+ dcrypt_key_ref_private(*priv_key_r);
+ return 1;
+ }
struct mail_namespace *ns = mailbox_get_namespace(_mail->box);
if (ns->type == MAIL_NAMESPACE_TYPE_SHARED) {
ret = mail_crypt_box_get_shared_key(_mail->box, pubkey_digest,
priv_key_r, error_r);
+ /* priv_key_r is already referenced */
} else if (ns->type != MAIL_NAMESPACE_TYPE_PUBLIC) {
ret = mail_crypt_get_private_key(_mail->box, pubkey_digest,
FALSE, FALSE, priv_key_r,
error_r);
+ /* priv_key_r is already referenced */
} else {
*error_r = "Public emails cannot have keys";
ret = -1;