add go-sbot keystore functionality
This commit is contained in:
parent
e393e7f72b
commit
15f4a4c5a3
|
@ -0,0 +1,98 @@
|
|||
//! Read and write a go-sbot secret (identity) file.
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use async_std::{
|
||||
io::{Read, Write},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use std::string::ToString;
|
||||
|
||||
use super::{
|
||||
error::{Error, Result},
|
||||
CURVE_ED25519,
|
||||
OwnedIdentity,
|
||||
JsonSSBSecret,
|
||||
};
|
||||
use crate::crypto::{ToSodiumObject, ToSsbId};
|
||||
|
||||
fn to_io_error<T: ToString>(err: T) -> async_std::io::Error {
|
||||
async_std::io::Error::new(std::io::ErrorKind::Other, err.to_string())
|
||||
}
|
||||
|
||||
/// Return an `OwnedIdentity` from the local go-sbot secret file.
|
||||
pub async fn from_gosbot_local() -> Result<OwnedIdentity> {
|
||||
let home_dir = dirs::home_dir().ok_or(Error::HomeNotFound)?;
|
||||
let local_key_file = format!("{}/.ssb-go/secret", home_dir.to_string_lossy());
|
||||
let mut file = async_std::fs::File::open(local_key_file).await?;
|
||||
read_gosbot_config(&mut file).await
|
||||
}
|
||||
|
||||
/// Read the contents of the go-sbot secret file, deserialize into a
|
||||
/// `JsonSSBSecret` and return an `OwnedIdentity`.
|
||||
pub async fn read_gosbot_config<R: Read + Unpin>(reader: &mut R) -> Result<OwnedIdentity> {
|
||||
let mut buf = String::new();
|
||||
reader.read_to_string(&mut buf).await?;
|
||||
|
||||
// parse json
|
||||
let secret: JsonSSBSecret = serde_json::from_str(buf.as_ref()).map_err(to_io_error)?;
|
||||
|
||||
if secret.curve != CURVE_ED25519 {
|
||||
return Err(Error::InvalidConfig);
|
||||
}
|
||||
|
||||
Ok(OwnedIdentity {
|
||||
id: secret.id,
|
||||
pk: secret.public.to_ed25519_pk()?,
|
||||
sk: secret.private.to_ed25519_sk()?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Write an `OwnedIdentity`.
|
||||
pub async fn write_gosbot_config<W: Write + Unpin>(
|
||||
id: &OwnedIdentity,
|
||||
writer: &mut W,
|
||||
) -> Result<()> {
|
||||
let json = JsonSSBSecret {
|
||||
curve: CURVE_ED25519.to_owned(),
|
||||
id: id.id.clone(),
|
||||
private: id.sk.to_ssb_id(),
|
||||
public: id.pk.to_ssb_id(),
|
||||
};
|
||||
let encoded = serde_json::to_vec(&json)?;
|
||||
Ok(writer.write_all(&encoded).await?)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use async_std::io::Cursor;
|
||||
use super::*;
|
||||
|
||||
// ssb secret file contents, as formatted by go-sbot
|
||||
const SECRET: &str = r#"{"curve":"ed25519","id":"@1vxS6DMi7z9uJIQG33W7mlsv21GZIbOpmWE1QEcn9oY=.ed25519","private":"F9bw6dPLaHR89hg6Q2dRmoNHHjm+COI53L0kdV3Y4w3W/FLoMyLvP24khAbfdbuaWy/bUZkhs6mZYTVARyf2hg==.ed25519","public":"1vxS6DMi7z9uJIQG33W7mlsv21GZIbOpmWE1QEcn9oY=.ed25519"}"#;
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_gosbot_secret() -> Result<()> {
|
||||
let mut secret_bytes = SECRET.as_bytes();
|
||||
let read_secret_output = read_gosbot_config(&mut secret_bytes).await?;
|
||||
let expected = OwnedIdentity {
|
||||
id: "@1vxS6DMi7z9uJIQG33W7mlsv21GZIbOpmWE1QEcn9oY=.ed25519".to_owned(),
|
||||
sk: "F9bw6dPLaHR89hg6Q2dRmoNHHjm+COI53L0kdV3Y4w3W/FLoMyLvP24khAbfdbuaWy/bUZkhs6mZYTVARyf2hg==.ed25519".to_ed25519_sk()?,
|
||||
pk: "1vxS6DMi7z9uJIQG33W7mlsv21GZIbOpmWE1QEcn9oY=.ed25519".to_ed25519_pk()?
|
||||
};
|
||||
assert_eq!(expected, read_secret_output);
|
||||
|
||||
// create a Cursor which wraps an in-memory buffer (implements `Write`)
|
||||
let mut secret_buffer = Cursor::new(Vec::new());
|
||||
// write the `OwnedIdentity` from `read_gosbot_config()` to the buffer
|
||||
write_gosbot_config(&read_secret_output, &mut secret_buffer).await?;
|
||||
// retrieve the value from inside the Cursor
|
||||
let secret_vector = secret_buffer.into_inner();
|
||||
// convert the byte slice to a string slice
|
||||
let write_secret_output = std::str::from_utf8(&secret_vector).unwrap();
|
||||
assert_eq!(SECRET, write_secret_output);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
mod error;
|
||||
pub mod gosbot;
|
||||
mod identity;
|
||||
pub mod patchwork;
|
||||
|
||||
pub use identity::OwnedIdentity;
|
||||
pub use gosbot::{from_gosbot_local, read_gosbot_config, write_gosbot_config};
|
||||
pub use identity::{JsonSSBSecret, OwnedIdentity, CURVE_ED25519};
|
||||
pub use patchwork::{from_patchwork_local, read_patchwork_config, write_patchwork_config};
|
||||
|
|
Loading…
Reference in New Issue