diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 311106525..90a7d90f6 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -364,6 +364,12 @@ char* dc_get_blobdir (const dc_context_t* context); * also show all mails of confirmed contacts, * DC_SHOW_EMAILS_ALL (2)= * also show mails of unconfirmed contacts in the deaddrop. + * - `key_gen_type` = DC_KEY_GEN_DEFAULT (0)= + * generate recommended key type (default), + * DC_KEY_GEN_RSA2048 (1)= + * generate RSA 2048 keypair + * DC_KEY_GEN_ED25519 (2)= + * generate Ed25519 keypair * - `save_mime_headers` = 1=save mime headers * and make dc_get_mime_headers() work for subsequent calls, * 0=do not save mime headers (default) @@ -4529,6 +4535,13 @@ void dc_array_add_id (dc_array_t*, uint32_t); // depreca #define DC_SHOW_EMAILS_ACCEPTED_CONTACTS 1 #define DC_SHOW_EMAILS_ALL 2 +/* + * Values for dc_get|set_config("key_gen_type") + */ +#define DC_KEY_GEN_DEFAULT 0 +#define DC_KEY_GEN_RSA2048 1 +#define DC_KEY_GEN_ED25519 2 + /** * @defgroup DC_PROVIDER_STATUS DC_PROVIDER_STATUS diff --git a/python/src/deltachat/const.py b/python/src/deltachat/const.py index 8fc413811..7135b4905 100644 --- a/python/src/deltachat/const.py +++ b/python/src/deltachat/const.py @@ -103,6 +103,9 @@ DC_EVENT_FILE_COPIED = 2055 DC_EVENT_IS_OFFLINE = 2081 DC_EVENT_GET_STRING = 2091 DC_STR_SELFNOTINGRP = 21 +DC_KEY_GEN_DEFAULT = 0 +DC_KEY_GEN_RSA2048 = 1 +DC_KEY_GEN_ED25519 = 2 DC_PROVIDER_STATUS_OK = 1 DC_PROVIDER_STATUS_PREPARATION = 2 DC_PROVIDER_STATUS_BROKEN = 3 @@ -161,7 +164,7 @@ DC_STR_COUNT = 68 def read_event_defines(f): rex = re.compile(r'#define\s+((?:DC_EVENT|DC_QR|DC_MSG|DC_LP|DC_EMPTY|DC_CERTCK|DC_STATE|DC_STR|' - r'DC_CONTACT_ID|DC_GCL|DC_CHAT|DC_PROVIDER)_\S+)\s+([x\d]+).*') + r'DC_CONTACT_ID|DC_GCL|DC_CHAT|DC_PROVIDER|DC_KEY_GEN)_\S+)\s+([x\d]+).*') for line in f: m = rex.match(line) if m: diff --git a/src/config.rs b/src/config.rs index d5a165ac3..a0ef749ff 100644 --- a/src/config.rs +++ b/src/config.rs @@ -62,6 +62,9 @@ pub enum Config { #[strum(props(default = "0"))] // also change ShowEmails.default() on changes ShowEmails, + #[strum(props(default = "0"))] + KeyGenType, + SaveMimeHeaders, ConfiguredAddr, ConfiguredMailServer, diff --git a/src/constants.rs b/src/constants.rs index 8816d4265..b30d735f2 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -57,6 +57,20 @@ impl Default for ShowEmails { } } +#[derive(Debug, Display, Clone, Copy, PartialEq, Eq, FromPrimitive, ToPrimitive, FromSql, ToSql)] +#[repr(u8)] +pub enum KeyGenType { + Default = 0, + Rsa2048 = 1, + Ed25519 = 2, +} + +impl Default for KeyGenType { + fn default() -> Self { + KeyGenType::Default + } +} + pub const DC_HANDSHAKE_CONTINUE_NORMAL_PROCESSING: i32 = 0x01; pub const DC_HANDSHAKE_STOP_NORMAL_PROCESSING: i32 = 0x02; pub const DC_HANDSHAKE_ADD_DELETE_JOB: i32 = 0x04; diff --git a/src/e2ee.rs b/src/e2ee.rs index d9740d11c..55baf2acb 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -8,6 +8,7 @@ use num_traits::FromPrimitive; use crate::aheader::*; use crate::config::Config; +use crate::constants::KeyGenType; use crate::context::Context; use crate::dc_tools::EmailAddress; use crate::error::*; @@ -211,11 +212,11 @@ fn load_or_generate_self_public_key( } let start = std::time::Instant::now(); - info!( - context, - "Generating keypair with {} bits, e={} ...", 2048, 65537, - ); - let keypair = pgp::create_keypair(EmailAddress::new(self_addr.as_ref())?)?; + + let keygen_type = + KeyGenType::from_i32(context.get_config_int(Config::KeyGenType)).unwrap_or_default(); + info!(context, "Generating keypair with type {}", keygen_type); + let keypair = pgp::create_keypair(EmailAddress::new(self_addr.as_ref())?, keygen_type)?; key::store_self_keypair(context, &keypair, KeyPairUse::Default)?; info!( context, diff --git a/src/pgp.rs b/src/pgp.rs index 97572f6f6..64d64e095 100644 --- a/src/pgp.rs +++ b/src/pgp.rs @@ -16,6 +16,7 @@ use pgp::types::{ }; use rand::{thread_rng, CryptoRng, Rng}; +use crate::constants::KeyGenType; use crate::dc_tools::EmailAddress; use crate::error::Result; use crate::key::*; @@ -147,10 +148,18 @@ pub struct KeyPair { } /// Create a new key pair. -pub(crate) fn create_keypair(addr: EmailAddress) -> std::result::Result { +pub(crate) fn create_keypair( + addr: EmailAddress, + keygen_type: KeyGenType, +) -> std::result::Result { + let (secret_key_type, public_key_type) = match keygen_type { + KeyGenType::Rsa2048 => (PgpKeyType::Rsa(2048), PgpKeyType::Rsa(2048)), + KeyGenType::Ed25519 | KeyGenType::Default => (PgpKeyType::EdDSA, PgpKeyType::ECDH), + }; + let user_id = format!("<{}>", addr); let key_params = SecretKeyParamsBuilder::default() - .key_type(PgpKeyType::EdDSA) + .key_type(secret_key_type) .can_create_certificates(true) .can_sign(true) .primary_user_id(user_id) @@ -173,7 +182,7 @@ pub(crate) fn create_keypair(addr: EmailAddress) -> std::result::Result