mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
refactor: remove addr from KeyPair
This commit is contained in:
@@ -864,13 +864,10 @@ void dc_maybe_network (dc_context_t* context);
|
|||||||
*
|
*
|
||||||
* @memberof dc_context_t
|
* @memberof dc_context_t
|
||||||
* @param context The context as created by dc_context_new().
|
* @param context The context as created by dc_context_new().
|
||||||
* @param addr The e-mail address of the user. This must match the
|
|
||||||
* configured_addr setting of the context as well as the UID of the key.
|
|
||||||
* @param public_data Ignored, actual public key is extracted from secret_data.
|
|
||||||
* @param secret_data ASCII armored secret key.
|
* @param secret_data ASCII armored secret key.
|
||||||
* @return 1 on success, 0 on failure.
|
* @return 1 on success, 0 on failure.
|
||||||
*/
|
*/
|
||||||
int dc_preconfigure_keypair (dc_context_t* context, const char *addr, const char *public_data, const char *secret_data);
|
int dc_preconfigure_keypair (dc_context_t* context, const char *secret_data);
|
||||||
|
|
||||||
|
|
||||||
// handle chatlists
|
// handle chatlists
|
||||||
|
|||||||
@@ -835,8 +835,6 @@ pub unsafe extern "C" fn dc_maybe_network(context: *mut dc_context_t) {
|
|||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_preconfigure_keypair(
|
pub unsafe extern "C" fn dc_preconfigure_keypair(
|
||||||
context: *mut dc_context_t,
|
context: *mut dc_context_t,
|
||||||
addr: *const libc::c_char,
|
|
||||||
_public_data: *const libc::c_char,
|
|
||||||
secret_data: *const libc::c_char,
|
secret_data: *const libc::c_char,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
if context.is_null() {
|
if context.is_null() {
|
||||||
@@ -844,9 +842,8 @@ pub unsafe extern "C" fn dc_preconfigure_keypair(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
let ctx = &*context;
|
let ctx = &*context;
|
||||||
let addr = to_string_lossy(addr);
|
|
||||||
let secret_data = to_string_lossy(secret_data);
|
let secret_data = to_string_lossy(secret_data);
|
||||||
block_on(preconfigure_keypair(ctx, &addr, &secret_data))
|
block_on(preconfigure_keypair(ctx, &secret_data))
|
||||||
.context("Failed to save keypair")
|
.context("Failed to save keypair")
|
||||||
.log_err(ctx)
|
.log_err(ctx)
|
||||||
.is_ok() as libc::c_int
|
.is_ok() as libc::c_int
|
||||||
|
|||||||
@@ -194,15 +194,13 @@ class Account:
|
|||||||
assert res != ffi.NULL, f"config value not found for: {name!r}"
|
assert res != ffi.NULL, f"config value not found for: {name!r}"
|
||||||
return from_dc_charpointer(res)
|
return from_dc_charpointer(res)
|
||||||
|
|
||||||
def _preconfigure_keypair(self, addr: str, secret: str) -> None:
|
def _preconfigure_keypair(self, secret: str) -> None:
|
||||||
"""See dc_preconfigure_keypair() in deltachat.h.
|
"""See dc_preconfigure_keypair() in deltachat.h.
|
||||||
|
|
||||||
In other words, you don't need this.
|
In other words, you don't need this.
|
||||||
"""
|
"""
|
||||||
res = lib.dc_preconfigure_keypair(
|
res = lib.dc_preconfigure_keypair(
|
||||||
self._dc_context,
|
self._dc_context,
|
||||||
as_dc_charpointer(addr),
|
|
||||||
ffi.NULL,
|
|
||||||
as_dc_charpointer(secret),
|
as_dc_charpointer(secret),
|
||||||
)
|
)
|
||||||
if res == 0:
|
if res == 0:
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ class ACFactory:
|
|||||||
def remove_preconfigured_keys(self) -> None:
|
def remove_preconfigured_keys(self) -> None:
|
||||||
self._preconfigured_keys = []
|
self._preconfigured_keys = []
|
||||||
|
|
||||||
def _preconfigure_key(self, account, addr):
|
def _preconfigure_key(self, account):
|
||||||
# Only set a preconfigured key if we haven't used it yet for another account.
|
# Only set a preconfigured key if we haven't used it yet for another account.
|
||||||
try:
|
try:
|
||||||
keyname = self._preconfigured_keys.pop(0)
|
keyname = self._preconfigured_keys.pop(0)
|
||||||
@@ -471,9 +471,9 @@ class ACFactory:
|
|||||||
else:
|
else:
|
||||||
fname_sec = self.data.read_path(f"key/{keyname}-secret.asc")
|
fname_sec = self.data.read_path(f"key/{keyname}-secret.asc")
|
||||||
if fname_sec:
|
if fname_sec:
|
||||||
account._preconfigure_keypair(addr, fname_sec)
|
account._preconfigure_keypair(fname_sec)
|
||||||
return True
|
return True
|
||||||
print(f"WARN: could not use preconfigured keys for {addr!r}")
|
print("WARN: could not use preconfigured keys")
|
||||||
|
|
||||||
def get_pseudo_configured_account(self, passphrase: Optional[str] = None) -> Account:
|
def get_pseudo_configured_account(self, passphrase: Optional[str] = None) -> Account:
|
||||||
# do a pseudo-configured account
|
# do a pseudo-configured account
|
||||||
@@ -492,7 +492,7 @@ class ACFactory:
|
|||||||
"configured": "1",
|
"configured": "1",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
self._preconfigure_key(ac, addr)
|
self._preconfigure_key(ac)
|
||||||
self._acsetup.init_logging(ac)
|
self._acsetup.init_logging(ac)
|
||||||
return ac
|
return ac
|
||||||
|
|
||||||
@@ -528,7 +528,7 @@ class ACFactory:
|
|||||||
configdict.setdefault("delete_server_after", 0)
|
configdict.setdefault("delete_server_after", 0)
|
||||||
ac.update_config(configdict)
|
ac.update_config(configdict)
|
||||||
self._acsetup._account2config[ac] = configdict
|
self._acsetup._account2config[ac] = configdict
|
||||||
self._preconfigure_key(ac, configdict["addr"])
|
self._preconfigure_key(ac)
|
||||||
return ac
|
return ac
|
||||||
|
|
||||||
def wait_configured(self, account) -> None:
|
def wait_configured(self, account) -> None:
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class TestOfflineAccountBasic:
|
|||||||
ac = acfactory.get_unconfigured_account()
|
ac = acfactory.get_unconfigured_account()
|
||||||
alice_secret = data.read_path("key/alice-secret.asc")
|
alice_secret = data.read_path("key/alice-secret.asc")
|
||||||
assert alice_secret
|
assert alice_secret
|
||||||
ac._preconfigure_keypair("alice@example.org", alice_secret)
|
ac._preconfigure_keypair(alice_secret)
|
||||||
|
|
||||||
def test_getinfo(self, acfactory):
|
def test_getinfo(self, acfactory):
|
||||||
ac1 = acfactory.get_unconfigured_account()
|
ac1 = acfactory.get_unconfigured_account()
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ use std::path::{Path, PathBuf};
|
|||||||
|
|
||||||
use ::pgp::types::KeyTrait;
|
use ::pgp::types::KeyTrait;
|
||||||
use anyhow::{bail, ensure, format_err, Context as _, Result};
|
use anyhow::{bail, ensure, format_err, Context as _, Result};
|
||||||
use deltachat_contact_tools::EmailAddress;
|
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use futures_lite::FutureExt;
|
use futures_lite::FutureExt;
|
||||||
|
|
||||||
@@ -178,10 +177,7 @@ async fn set_self_key(context: &Context, armored: &str, set_default: bool) -> Re
|
|||||||
info!(context, "No Autocrypt-Prefer-Encrypt header.");
|
info!(context, "No Autocrypt-Prefer-Encrypt header.");
|
||||||
};
|
};
|
||||||
|
|
||||||
let self_addr = context.get_primary_self_addr().await?;
|
|
||||||
let addr = EmailAddress::new(&self_addr)?;
|
|
||||||
let keypair = pgp::KeyPair {
|
let keypair = pgp::KeyPair {
|
||||||
addr,
|
|
||||||
public: public_key,
|
public: public_key,
|
||||||
secret: private_key,
|
secret: private_key,
|
||||||
};
|
};
|
||||||
|
|||||||
17
src/key.rs
17
src/key.rs
@@ -244,7 +244,7 @@ async fn generate_keypair(context: &Context) -> Result<KeyPair> {
|
|||||||
let _guard = context.generating_key_mutex.lock().await;
|
let _guard = context.generating_key_mutex.lock().await;
|
||||||
|
|
||||||
// Check if the key appeared while we were waiting on the lock.
|
// Check if the key appeared while we were waiting on the lock.
|
||||||
match load_keypair(context, &addr).await? {
|
match load_keypair(context).await? {
|
||||||
Some(key_pair) => Ok(key_pair),
|
Some(key_pair) => Ok(key_pair),
|
||||||
None => {
|
None => {
|
||||||
let start = tools::Time::now();
|
let start = tools::Time::now();
|
||||||
@@ -266,10 +266,7 @@ async fn generate_keypair(context: &Context) -> Result<KeyPair> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn load_keypair(
|
pub(crate) async fn load_keypair(context: &Context) -> Result<Option<KeyPair>> {
|
||||||
context: &Context,
|
|
||||||
addr: &EmailAddress,
|
|
||||||
) -> Result<Option<KeyPair>> {
|
|
||||||
let res = context
|
let res = context
|
||||||
.sql
|
.sql
|
||||||
.query_row_optional(
|
.query_row_optional(
|
||||||
@@ -287,7 +284,6 @@ pub(crate) async fn load_keypair(
|
|||||||
|
|
||||||
Ok(if let Some((pub_bytes, sec_bytes)) = res {
|
Ok(if let Some((pub_bytes, sec_bytes)) = res {
|
||||||
Some(KeyPair {
|
Some(KeyPair {
|
||||||
addr: addr.clone(),
|
|
||||||
public: SignedPublicKey::from_slice(&pub_bytes)?,
|
public: SignedPublicKey::from_slice(&pub_bytes)?,
|
||||||
secret: SignedSecretKey::from_slice(&sec_bytes)?,
|
secret: SignedSecretKey::from_slice(&sec_bytes)?,
|
||||||
})
|
})
|
||||||
@@ -371,15 +367,10 @@ pub(crate) async fn store_self_keypair(
|
|||||||
/// This API is used for testing purposes
|
/// This API is used for testing purposes
|
||||||
/// to avoid generating the key in tests.
|
/// to avoid generating the key in tests.
|
||||||
/// Use import/export APIs instead.
|
/// Use import/export APIs instead.
|
||||||
pub async fn preconfigure_keypair(context: &Context, addr: &str, secret_data: &str) -> Result<()> {
|
pub async fn preconfigure_keypair(context: &Context, secret_data: &str) -> Result<()> {
|
||||||
let addr = EmailAddress::new(addr)?;
|
|
||||||
let secret = SignedSecretKey::from_asc(secret_data)?.0;
|
let secret = SignedSecretKey::from_asc(secret_data)?.0;
|
||||||
let public = secret.split_public_key()?;
|
let public = secret.split_public_key()?;
|
||||||
let keypair = KeyPair {
|
let keypair = KeyPair { public, secret };
|
||||||
addr,
|
|
||||||
public,
|
|
||||||
secret,
|
|
||||||
};
|
|
||||||
store_self_keypair(context, &keypair, KeyPairUse::Default).await?;
|
store_self_keypair(context, &keypair, KeyPairUse::Default).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,9 +135,6 @@ pub fn split_armored_data(buf: &[u8]) -> Result<(BlockType, BTreeMap<String, Str
|
|||||||
/// keys together as they are one unit.
|
/// keys together as they are one unit.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct KeyPair {
|
pub struct KeyPair {
|
||||||
/// Email address.
|
|
||||||
pub addr: EmailAddress,
|
|
||||||
|
|
||||||
/// Public key.
|
/// Public key.
|
||||||
pub public: SignedPublicKey,
|
pub public: SignedPublicKey,
|
||||||
|
|
||||||
@@ -210,7 +207,6 @@ pub(crate) fn create_keypair(addr: EmailAddress, keygen_type: KeyGenType) -> Res
|
|||||||
.context("invalid public key generated")?;
|
.context("invalid public key generated")?;
|
||||||
|
|
||||||
Ok(KeyPair {
|
Ok(KeyPair {
|
||||||
addr,
|
|
||||||
public: public_key,
|
public: public_key,
|
||||||
secret: secret_key,
|
secret: secret_key,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -256,19 +256,28 @@ impl TestContextBuilder {
|
|||||||
|
|
||||||
/// Builds the [`TestContext`].
|
/// Builds the [`TestContext`].
|
||||||
pub async fn build(self) -> TestContext {
|
pub async fn build(self) -> TestContext {
|
||||||
let name = self.key_pair.as_ref().map(|key| key.addr.local.clone());
|
|
||||||
|
|
||||||
let test_context = TestContext::new_internal(name, self.log_sink).await;
|
|
||||||
|
|
||||||
if let Some(key_pair) = self.key_pair {
|
if let Some(key_pair) = self.key_pair {
|
||||||
test_context
|
let userid = {
|
||||||
.configure_addr(&key_pair.addr.to_string())
|
let public_key = &key_pair.public;
|
||||||
.await;
|
let id_bstr = public_key.details.users.first().unwrap().id.id();
|
||||||
|
String::from_utf8(id_bstr.to_vec()).unwrap()
|
||||||
|
};
|
||||||
|
let addr = mailparse::addrparse(&userid)
|
||||||
|
.unwrap()
|
||||||
|
.extract_single_info()
|
||||||
|
.unwrap()
|
||||||
|
.addr;
|
||||||
|
let name = EmailAddress::new(&addr).unwrap().local;
|
||||||
|
|
||||||
|
let test_context = TestContext::new_internal(Some(name), self.log_sink).await;
|
||||||
|
test_context.configure_addr(&addr).await;
|
||||||
key::store_self_keypair(&test_context, &key_pair, KeyPairUse::Default)
|
key::store_self_keypair(&test_context, &key_pair, KeyPairUse::Default)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to save key");
|
.expect("Failed to save key");
|
||||||
|
test_context
|
||||||
|
} else {
|
||||||
|
TestContext::new_internal(None, self.log_sink).await
|
||||||
}
|
}
|
||||||
test_context
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -979,55 +988,39 @@ impl SentMessage<'_> {
|
|||||||
///
|
///
|
||||||
/// The keypair was created using the crate::key::tests::gen_key test.
|
/// The keypair was created using the crate::key::tests::gen_key test.
|
||||||
pub fn alice_keypair() -> KeyPair {
|
pub fn alice_keypair() -> KeyPair {
|
||||||
let addr = EmailAddress::new("alice@example.org").unwrap();
|
|
||||||
|
|
||||||
let public = key::SignedPublicKey::from_asc(include_str!("../test-data/key/alice-public.asc"))
|
let public = key::SignedPublicKey::from_asc(include_str!("../test-data/key/alice-public.asc"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let secret = key::SignedSecretKey::from_asc(include_str!("../test-data/key/alice-secret.asc"))
|
let secret = key::SignedSecretKey::from_asc(include_str!("../test-data/key/alice-secret.asc"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
KeyPair {
|
KeyPair { public, secret }
|
||||||
addr,
|
|
||||||
public,
|
|
||||||
secret,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a pre-generated keypair for bob@example.net from disk.
|
/// Load a pre-generated keypair for bob@example.net from disk.
|
||||||
///
|
///
|
||||||
/// Like [alice_keypair] but a different key and identity.
|
/// Like [alice_keypair] but a different key and identity.
|
||||||
pub fn bob_keypair() -> KeyPair {
|
pub fn bob_keypair() -> KeyPair {
|
||||||
let addr = EmailAddress::new("bob@example.net").unwrap();
|
|
||||||
let public = key::SignedPublicKey::from_asc(include_str!("../test-data/key/bob-public.asc"))
|
let public = key::SignedPublicKey::from_asc(include_str!("../test-data/key/bob-public.asc"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let secret = key::SignedSecretKey::from_asc(include_str!("../test-data/key/bob-secret.asc"))
|
let secret = key::SignedSecretKey::from_asc(include_str!("../test-data/key/bob-secret.asc"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
KeyPair {
|
KeyPair { public, secret }
|
||||||
addr,
|
|
||||||
public,
|
|
||||||
secret,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load a pre-generated keypair for fiona@example.net from disk.
|
/// Load a pre-generated keypair for fiona@example.net from disk.
|
||||||
///
|
///
|
||||||
/// Like [alice_keypair] but a different key and identity.
|
/// Like [alice_keypair] but a different key and identity.
|
||||||
pub fn fiona_keypair() -> KeyPair {
|
pub fn fiona_keypair() -> KeyPair {
|
||||||
let addr = EmailAddress::new("fiona@example.net").unwrap();
|
|
||||||
let public = key::SignedPublicKey::from_asc(include_str!("../test-data/key/fiona-public.asc"))
|
let public = key::SignedPublicKey::from_asc(include_str!("../test-data/key/fiona-public.asc"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let secret = key::SignedSecretKey::from_asc(include_str!("../test-data/key/fiona-secret.asc"))
|
let secret = key::SignedSecretKey::from_asc(include_str!("../test-data/key/fiona-secret.asc"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
KeyPair {
|
KeyPair { public, secret }
|
||||||
addr,
|
|
||||||
public,
|
|
||||||
secret,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Utility to help wait for and retrieve events.
|
/// Utility to help wait for and retrieve events.
|
||||||
|
|||||||
Reference in New Issue
Block a user