diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml
new file mode 100644
index 0000000..ab896b7
--- /dev/null
+++ b/.github/workflows/clippy.yml
@@ -0,0 +1,24 @@
+name: Clippy
+on:
+ workflow_dispatch:
+ push:
+ branches: [trunk]
+ pull_request:
+ branches: [trunk]
+
+permissions:
+ contents: read
+
+jobs:
+ clippy:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ - name: Install Rust
+ run: rustup update stable
+
+ - name: Install Clippy
+ run: rustup component add clippy
+
+ - name: Run Clippy
+ run: cargo clippy
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..8023044
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,17 @@
+## v0.2.1
+
+- Fix linter warnings
+- Add linter workflow
+- Add OpenSSF Best Practices badge
+
+## v0.2.0
+
+- Interoperability with other Atsign SDKs
+- Autobug workflow
+- Removed direct dependency on a specific TLS client
+- OpenSSF Scorecard
+- create at_secrets from values
+
+## v0.1.0
+
+- Initial version with PKAM auth and simple data exchange
diff --git a/Cargo.toml b/Cargo.toml
index 235b4ae..a591804 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "at_rust"
-version = "0.2.0"
+version = "0.2.1"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/README.md b/README.md
index cd4aafa..36edd7c 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/atsign-foundation/at_rust/badge)](https://api.securityscorecards.dev/projects/github.com/atsign-foundation/at_rust)
+[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8148/badge)](https://www.bestpractices.dev/projects/8148)
# Rust SDK - (⚠️Alpha version⚠️)
This repo contains libraries, tools, samples and examples for developers who wish to work with the atPlatform from Rust code.
diff --git a/src/at_chops/at_chops.rs b/src/at_chops/chops.rs
similarity index 89%
rename from src/at_chops/at_chops.rs
rename to src/at_chops/chops.rs
index f6c2606..f4849db 100644
--- a/src/at_chops/at_chops.rs
+++ b/src/at_chops/chops.rs
@@ -1,4 +1,4 @@
-use log::{info, warn};
+//use log::{info, warn};
use super::utils::{
base64_decode, base64_encode, construct_aes_key, construct_rsa_private_key,
@@ -19,7 +19,7 @@ pub fn decrypt_private_key(
) -> String {
let iv: [u8; 16] = [0x00; 16];
let mut cypher = construct_aes_key(decoded_self_encryption_key, &iv);
- let decoded_private_key = base64_decode(&encrypted_private_key);
+ let decoded_private_key = base64_decode(encrypted_private_key);
let mut output: Vec = vec![0; decoded_private_key.len()];
cypher.process(&decoded_private_key, &mut output);
@@ -36,9 +36,9 @@ pub fn decrypt_private_key(
/// Sign a given challenge with the decrypted private key.
pub fn sign_challenge(challenge: &str, decrypted_private_key: &str) -> String {
- let decoded_private_key = base64_decode(&decrypted_private_key);
+ let decoded_private_key = base64_decode(decrypted_private_key);
let rsa_private_key = construct_rsa_private_key(&decoded_private_key);
- rsa_sign(rsa_private_key, &challenge.as_bytes())
+ rsa_sign(rsa_private_key, challenge.as_bytes())
}
/// Cut a new symmetric key to be used when interacting with a new atSign.
@@ -49,37 +49,35 @@ pub fn create_new_shared_symmetric_key() -> String {
/// Decrypt the symmetric key with "our" private key.
pub fn decrypt_symmetric_key(encrypted_symmetric_key: &str, decrypted_private_key: &str) -> String {
- let decoded_private_key = base64_decode(&decrypted_private_key);
+ let decoded_private_key = base64_decode(decrypted_private_key);
let rsa_private_key = construct_rsa_private_key(&decoded_private_key);
- let decoded_symmetric_key = base64_decode(&encrypted_symmetric_key);
- let decrypted_symmetric_key =
- decrypt_symm_key_with_private_key(&rsa_private_key, &decoded_symmetric_key);
- decrypted_symmetric_key
+ let decoded_symmetric_key = base64_decode(encrypted_symmetric_key);
+ decrypt_symm_key_with_private_key(&rsa_private_key, &decoded_symmetric_key)
}
/// Encrypt data with our RSA public key.
pub fn encrypt_data_with_public_key(encoded_public_key: &str, data: &str) -> String {
- let decoded_public_key = base64_decode(&encoded_public_key);
+ let decoded_public_key = base64_decode(encoded_public_key);
let rsa_public_key = construct_rsa_public_key(&decoded_public_key);
- let encrypted_data = encrypt_with_public_key(&rsa_public_key, &data.as_bytes());
+ let encrypted_data = encrypt_with_public_key(&rsa_public_key, data.as_bytes());
encrypted_data
}
/// Encrypt data with AES symm key.
pub fn encrypt_data_with_shared_symmetric_key(encoded_symmetric_key: &str, data: &str) -> String {
- let decoded_symmetric_key = base64_decode(&encoded_symmetric_key);
+ let decoded_symmetric_key = base64_decode(encoded_symmetric_key);
let iv: [u8; 16] = [0x00; 16];
let mut cypher = construct_aes_key(&decoded_symmetric_key, &iv);
- let encrypted_data = encrypt_data_with_aes_key(&mut cypher, &data.as_bytes());
+ let encrypted_data = encrypt_data_with_aes_key(&mut cypher, data.as_bytes());
base64_encode(&encrypted_data)
}
/// Decrypt data with an encoded AES symm key.
pub fn decrypt_data_with_shared_symmetric_key(encoded_symmetric_key: &str, data: &str) -> String {
- let decoded_symmetric_key = base64_decode(&encoded_symmetric_key);
+ let decoded_symmetric_key = base64_decode(encoded_symmetric_key);
let iv: [u8; 16] = [0x00; 16];
let mut cypher = construct_aes_key(&decoded_symmetric_key, &iv);
- let decoded_data = base64_decode(&data);
+ let decoded_data = base64_decode(data);
let decrypted_data = decrypt_data_with_aes_key(&mut cypher, &decoded_data);
String::from_utf8(decrypted_data).expect("Unable to convert to UTF-8")
}
@@ -115,13 +113,13 @@ mod test {
#[test]
fn decrypt_private_key_test() {
let self_encryption_key = decode_self_encryption_key(SELF_ENCRYPTION_KEY_ENCODED);
- let result = decrypt_private_key(&PKAM_KEY_ENCRYPTED_AND_ENCODED, &self_encryption_key);
+ let result = decrypt_private_key(PKAM_KEY_ENCRYPTED_AND_ENCODED, &self_encryption_key);
assert_eq!(result, PKAM_KEY_DECRYPTED_AND_ENCODED);
}
#[test]
fn sign_challenge_test() {
- let result = sign_challenge(CHALLENGE_TEXT, &PKAM_KEY_DECRYPTED_AND_ENCODED);
+ let result = sign_challenge(CHALLENGE_TEXT, PKAM_KEY_DECRYPTED_AND_ENCODED);
assert_eq!(result, CHALLENGE_RESULT);
}
diff --git a/src/at_chops/mod.rs b/src/at_chops/mod.rs
index f85f6c7..a17b577 100644
--- a/src/at_chops/mod.rs
+++ b/src/at_chops/mod.rs
@@ -1,4 +1,4 @@
-pub mod at_chops;
+pub mod chops;
mod b64_encoded_string;
mod utils;
diff --git a/src/at_chops/utils.rs b/src/at_chops/utils.rs
index bbc73c3..0c3bf97 100644
--- a/src/at_chops/utils.rs
+++ b/src/at_chops/utils.rs
@@ -1,9 +1,9 @@
-use std::iter::repeat;
+//use std::iter::repeat;
use crypto::{aes::KeySize, symmetriccipher::SynchronousStreamCipher};
use base64::{engine::general_purpose, Engine as _};
-use log::info;
+//use log::info;
use rsa::{
pkcs1v15::SigningKey,
pkcs8::{DecodePrivateKey, DecodePublicKey},
@@ -33,16 +33,14 @@ pub fn construct_aes_key(data: &[u8], iv: &[u8; 16]) -> Box RsaPrivateKey {
- let rsa_key = RsaPrivateKey::from_pkcs8_der(&data).expect("Unable to create RSA Private Key");
+ let rsa_key = RsaPrivateKey::from_pkcs8_der(data).expect("Unable to create RSA Private Key");
rsa_key.validate().expect("Invalid RSA Private Key");
rsa_key
}
/// Construct an RSA public key from a decoded key.
pub fn construct_rsa_public_key(data: &[u8]) -> RsaPublicKey {
- let rsa_key =
- RsaPublicKey::from_public_key_der(&data).expect("Unable to create RSA Public Key");
- rsa_key
+ RsaPublicKey::from_public_key_der(data).expect("Unable to create RSA Public Key")
}
/// Sign data using an RSA private key.
@@ -53,16 +51,15 @@ pub fn rsa_sign(key: RsaPrivateKey, data: &[u8]) -> String {
let verifying_key = signing_key.verifying_key();
// Sign
- let signature = signing_key.sign_with_rng(&mut rng, &data);
+ let signature = signing_key.sign_with_rng(&mut rng, data);
verifying_key
- .verify(&data, &signature)
+ .verify(data, &signature)
.expect("failed to verify");
let binding = signature.to_bytes();
let signature_bytes = binding.as_ref();
// Encode signature
- let sha256_signature_encoded = base64_encode(&signature_bytes);
- sha256_signature_encoded
+ base64_encode(signature_bytes)
}
/// Create a new AES-256 key from scratch.
@@ -116,7 +113,7 @@ pub fn decrypt_data_with_aes_key(
data: &[u8],
) -> Vec {
let mut output: Vec = vec![0; data.len()];
- aes_key.process(&data, &mut output);
+ aes_key.process(data, &mut output);
// Remove padding due to PkCS#7 padding used by other SDKs
let last = output.last().unwrap();
output.truncate(output.len() - usize::from(*last));
@@ -182,7 +179,7 @@ mod test {
#[test]
fn construct_rsa_private_key_test() {
// Arrange
- let private_key = base64_decode(&PKAM_KEY_DECRYPTED_AND_ENCODED);
+ let private_key = base64_decode(PKAM_KEY_DECRYPTED_AND_ENCODED);
// Act
let _ = construct_rsa_private_key(&private_key);
// Assert it doesn't panic
@@ -191,7 +188,7 @@ mod test {
#[test]
fn construct_rsa_public_key_test() {
// Arrange
- let public_key = base64_decode(&PUBLIC_ENCRYPTION_KEY);
+ let public_key = base64_decode(PUBLIC_ENCRYPTION_KEY);
// Act
let _ = construct_rsa_public_key(&public_key);
// Assert it doesn't panic
@@ -200,7 +197,7 @@ mod test {
#[test]
fn rsa_sign_test() {
// Arrange
- let private_key = base64_decode(&PKAM_KEY_DECRYPTED_AND_ENCODED);
+ let private_key = base64_decode(PKAM_KEY_DECRYPTED_AND_ENCODED);
let rsa_key = construct_rsa_private_key(&private_key);
// Act
let decrypted = rsa_sign(rsa_key, CHALLENGE_TEXT.as_bytes());
@@ -216,7 +213,7 @@ mod test {
#[test]
fn encrypt_with_public_key_test() {
- let public_key = base64_decode(&PUBLIC_ENCRYPTION_KEY);
+ let public_key = base64_decode(PUBLIC_ENCRYPTION_KEY);
let public_key = construct_rsa_public_key(&public_key);
let _ = encrypt_with_public_key(&public_key, &TEST_KEY_DECODED);
// Assert it doesn't panic.
diff --git a/src/at_client.rs b/src/at_client.rs
index 7e6b124..573b1f5 100644
--- a/src/at_client.rs
+++ b/src/at_client.rs
@@ -1,6 +1,6 @@
use log::info;
-use crate::at_chops::at_chops::{
+use crate::at_chops::chops::{
create_new_shared_symmetric_key, decrypt_data_with_shared_symmetric_key, decrypt_symmetric_key,
encrypt_data_with_public_key, encrypt_data_with_shared_symmetric_key,
};
@@ -59,7 +59,7 @@ impl AtClient {
// Save for our use
let encrypted_encoded_sym_key =
encrypt_data_with_public_key(&self.secrets.encrypt_public_key, &new_key);
- let _ = UpdateVerb::execute(
+ UpdateVerb::execute(
&mut self.tls_client,
UpdateVerbInputs::new(
&self.at_sign,
@@ -82,7 +82,7 @@ impl AtClient {
symm_key_encrypted_with_recipient_public_key
);
// Send data
- let _ = UpdateVerb::execute(
+ UpdateVerb::execute(
&mut self.tls_client,
UpdateVerbInputs::new(
&self.at_sign,
@@ -96,9 +96,9 @@ impl AtClient {
} else if response.contains("data") {
info!("Already have a copy of the key");
// Decrypt symm key
- let encrypted_symmetric_key = response.split(":").collect::>()[1];
+ let encrypted_symmetric_key = response.split(':').collect::>()[1];
symm_key =
- decrypt_symmetric_key(&encrypted_symmetric_key, &self.secrets.encrypt_private_key);
+ decrypt_symmetric_key(encrypted_symmetric_key, &self.secrets.encrypt_private_key);
info!("Decrypted symmetric key: {}", symm_key);
} else {
return Err(AtError::new(String::from("Unknown response from server")));
@@ -110,7 +110,7 @@ impl AtClient {
UpdateVerbInputs::new(
&self.at_sign,
// TODO: Pass this in as an option somewhere
- &record_id,
+ record_id,
&encrypted_data_to_send,
Some(&self.namespace),
None,
@@ -128,7 +128,7 @@ impl AtClient {
&mut self.tls_client,
LookupVerbInputs::new(&from, record_id, Some(&self.namespace)),
)?;
- let encrypted_and_encoded_data = response.split(":").collect::>()[1];
+ let encrypted_and_encoded_data = response.split(':').collect::>()[1];
info!("Fetching symmetric key");
// Fetch symm key
let response = LookupVerb::execute(
@@ -136,15 +136,15 @@ impl AtClient {
LookupVerbInputs::new(&from, "shared_key", None),
)?;
info!("Decrypting symmetric key");
- let encrypted_and_encoded_symm_key = response.split(":").collect::>()[1];
+ let encrypted_and_encoded_symm_key = response.split(':').collect::>()[1];
let symm_key = decrypt_symmetric_key(
- &encrypted_and_encoded_symm_key,
+ encrypted_and_encoded_symm_key,
&self.secrets.encrypt_private_key,
);
info!("Decrypted symmetric key: {}", symm_key);
info!("Decrypting data");
let encoded_data =
- decrypt_data_with_shared_symmetric_key(&symm_key, &encrypted_and_encoded_data);
+ decrypt_data_with_shared_symmetric_key(&symm_key, encrypted_and_encoded_data);
info!("Decrypted data: {}", encoded_data);
Ok(())
@@ -183,7 +183,7 @@ fn get_at_sign_server_addr(
// Trimming to remove the newline character
let addr = addr.trim();
- let addr = addr.split(":").collect::>();
+ let addr = addr.split(':').collect::>();
let host = addr[0].to_string();
let port = addr[1]
.parse::()
diff --git a/src/at_secrets.rs b/src/at_secrets.rs
index ae48f1f..ac02247 100644
--- a/src/at_secrets.rs
+++ b/src/at_secrets.rs
@@ -1,4 +1,4 @@
-use crate::at_chops::at_chops::{decode_self_encryption_key, decrypt_private_key};
+use crate::at_chops::chops::{decode_self_encryption_key, decrypt_private_key};
use crate::at_error::Result;
use log::info;
use serde_json::{from_str, Value};
@@ -64,17 +64,17 @@ impl AtSecrets {
) -> Result {
info!("Decoding keys");
// Decode the self encrypt key from base64
- let decoded_self_encrypted_key = decode_self_encryption_key(&aes_self_encrypt_key);
+ let decoded_self_encrypted_key = decode_self_encryption_key(aes_self_encrypt_key);
// Use the key to decrypt all the other private keys
let pkam_public_key =
- decrypt_private_key(&aes_pkam_public_key, &decoded_self_encrypted_key);
+ decrypt_private_key(aes_pkam_public_key, &decoded_self_encrypted_key);
let pkam_private_key =
- decrypt_private_key(&aes_pkam_private_key, &decoded_self_encrypted_key);
+ decrypt_private_key(aes_pkam_private_key, &decoded_self_encrypted_key);
let encrypt_public_key =
- decrypt_private_key(&aes_encrypt_public_key, &decoded_self_encrypted_key);
+ decrypt_private_key(aes_encrypt_public_key, &decoded_self_encrypted_key);
let encrypt_private_key =
- decrypt_private_key(&aes_encrypt_private_key, &decoded_self_encrypted_key);
+ decrypt_private_key(aes_encrypt_private_key, &decoded_self_encrypted_key);
info!("Keys decoded and decrypted");
diff --git a/src/verbs/from.rs b/src/verbs/from.rs
index bdc38b8..3213685 100644
--- a/src/verbs/from.rs
+++ b/src/verbs/from.rs
@@ -1,6 +1,6 @@
use log::info;
-use crate::at_chops::at_chops::sign_challenge;
+use crate::at_chops::chops::sign_challenge;
use super::{prelude::*, Verb};
@@ -29,7 +29,7 @@ impl<'a> Verb<'a> for FromVerb {
let (_, data) = response.split_at(6);
info!("Challenge: {}", data);
- let signed_challenge = sign_challenge(&data, input.priv_pkam);
+ let signed_challenge = sign_challenge(data, input.priv_pkam);
tls_client.send(format!("pkam:{}\n", signed_challenge))?;
let response = tls_client.read_line()?;
diff --git a/src/verbs/lookup.rs b/src/verbs/lookup.rs
index b0fcd7f..ae50ed7 100644
--- a/src/verbs/lookup.rs
+++ b/src/verbs/lookup.rs
@@ -32,7 +32,7 @@ impl<'a> Verb<'a> for LookupVerb {
send_string.push_str(&format!(".{}", namespace));
}
send_string.push_str(&format!("@{}", input.to_at_sign.get_at_sign()));
- send_string.push_str(&format!("\n"));
+ send_string.push('\n');
tls_client.send(send_string)?;
let response = tls_client.read_line()?;
Ok(response)