Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: ossf fixes #13

Merged
merged 31 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
056d1a8
docs: Add CHANGELOG
cpswan Dec 1, 2023
1166232
fix: Clippy warning - unused import
cpswan Dec 1, 2023
6739941
fix: Clippy warning - unused import
cpswan Dec 1, 2023
4f0113e
ci: Add Clippy workflow
cpswan Dec 1, 2023
ebcdfc2
fix: Clippy warning - unused import
cpswan Dec 1, 2023
f0bff3c
fix: Clippy warning - module_inception
cpswan Dec 1, 2023
c8a6296
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
7b18773
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
1e8e2f8
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
d07f7b0
fix: Clippy warning - unnecessary let binding
cpswan Dec 1, 2023
77fcd10
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
4713e31
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
8fd3284
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
b045e87
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
ce44584
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
0e022fa
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
af35e74
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
0758049
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
7c78d43
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
40e9961
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
fb6145e
fix: Clippy warning - unnecessary let binding
cpswan Dec 1, 2023
2c27e73
fix: Clippy warning - unnecessary let binding
cpswan Dec 1, 2023
0f42f91
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
1f6e7b1
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
f48bc78
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
7a86d79
fix: Clippy warning - immediate dereference
cpswan Dec 1, 2023
dc92213
fix: Clippy --fix
cpswan Dec 1, 2023
04f2880
fix: Clippy warning - char literal
cpswan Dec 1, 2023
a169008
docs: Bump version number after linting
cpswan Dec 1, 2023
43bc89e
docs: Add OpenSSF Best Practices badge
cpswan Dec 1, 2023
b8329f2
docs: Add 0.2.1 changes
cpswan Dec 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## 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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "at_rust"
version = "0.2.0"
version = "0.2.1"
cpswan marked this conversation as resolved.
Show resolved Hide resolved
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<img width=250px src="https://atsign.dev/assets/img/atPlatform_logo_gray.svg?sanitize=true">

[![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.
Expand Down
32 changes: 15 additions & 17 deletions src/at_chops/at_chops.rs → src/at_chops/chops.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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<u8> = vec![0; decoded_private_key.len()];
cypher.process(&decoded_private_key, &mut output);
Expand All @@ -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.
Expand All @@ -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")
}
Expand Down Expand Up @@ -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);
}

Expand Down
2 changes: 1 addition & 1 deletion src/at_chops/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod at_chops;
pub mod chops;
mod b64_encoded_string;
mod utils;

27 changes: 12 additions & 15 deletions src/at_chops/utils.rs
Original file line number Diff line number Diff line change
@@ -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},
Expand Down Expand Up @@ -33,16 +33,14 @@ pub fn construct_aes_key(data: &[u8], iv: &[u8; 16]) -> Box<dyn SynchronousStrea

/// Construct an RSA private key from a decoded key.
pub fn construct_rsa_private_key(data: &[u8]) -> 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.
Expand All @@ -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.
Expand Down Expand Up @@ -116,7 +113,7 @@ pub fn decrypt_data_with_aes_key(
data: &[u8],
) -> Vec<u8> {
let mut output: Vec<u8> = 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));
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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());
Expand All @@ -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.
Expand Down
22 changes: 11 additions & 11 deletions src/at_client.rs
Original file line number Diff line number Diff line change
@@ -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,
};
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand All @@ -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::<Vec<_>>()[1];
let encrypted_symmetric_key = response.split(':').collect::<Vec<_>>()[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")));
Expand All @@ -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,
Expand All @@ -128,23 +128,23 @@ impl AtClient {
&mut self.tls_client,
LookupVerbInputs::new(&from, record_id, Some(&self.namespace)),
)?;
let encrypted_and_encoded_data = response.split(":").collect::<Vec<_>>()[1];
let encrypted_and_encoded_data = response.split(':').collect::<Vec<_>>()[1];
info!("Fetching symmetric key");
// Fetch symm key
let response = LookupVerb::execute(
&mut self.tls_client,
LookupVerbInputs::new(&from, "shared_key", None),
)?;
info!("Decrypting symmetric key");
let encrypted_and_encoded_symm_key = response.split(":").collect::<Vec<_>>()[1];
let encrypted_and_encoded_symm_key = response.split(':').collect::<Vec<_>>()[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(())
Expand Down Expand Up @@ -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::<Vec<_>>();
let addr = addr.split(':').collect::<Vec<_>>();
let host = addr[0].to_string();
let port = addr[1]
.parse::<u16>()
Expand Down
12 changes: 6 additions & 6 deletions src/at_secrets.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -64,17 +64,17 @@ impl AtSecrets {
) -> Result<AtSecrets> {
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");

Expand Down
4 changes: 2 additions & 2 deletions src/verbs/from.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -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()?;
Expand Down
2 changes: 1 addition & 1 deletion src/verbs/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down