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

Secure Cell passphrase API: RustThemis #630

Merged
merged 6 commits into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 1 addition & 3 deletions .github/workflows/test-rust.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,7 @@ jobs:
- name: Test examples (Secure Cell)
if: always()
run: |
cargo run --example secure_cell -- --encrypt --password "secret" README.md README.md.enc
cargo run --example secure_cell -- --decrypt --password "secret" README.md.enc README.md.dec
diff -q README.md README.md.dec
cargo run --example secure_cell
- name: Test examples (Secure Message)
if: always()
run: |
Expand Down
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,24 @@ _Code:_

- New object `themis::keys::SymmetricKey` can be used to generate symmetric keys for Secure Cell ([#561](https://github.com/cossacklabs/themis/pull/561)).
- Significantly reduced compilation time by removing `bindgen` crate from dependencies ([#626](https://github.com/cossacklabs/themis/pull/626)).
- Passphrase API support in Secure Cell ([#630](https://github.com/cossacklabs/themis/pull/630)).

RustThemis now supports _passphrase API_ of Secure Cell in Seal mode:

```rust
use themis::secure_cell::SecureCell;

let cell = SecureCell::with_passphase("secret")?.seal();

let encrypted = cell.encrypt(b"message data")?;
let decrypted = cell.decrypt(&encrypted)?;
```

You can safely and securely use short, human-readable passphrases as strings with this new API.

Existing master key API (available as `SecureCell::with_key(...)`) should not be used with passphrases or passwords.
Use master key API with symmetric encryption keys, such as generated by `themis::keys::SymmetricKey` ([#561](https://github.com/cossacklabs/themis/pull/561)).
Use passphrase API with human-readable passphrases.

- **WebAssembly**

Expand Down
11 changes: 5 additions & 6 deletions docs/examples/rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

In this directory, we have some examples of Themis usage.

* [**keygen**](keygen.rs) — a tool for generating ECDSA keys (usable by other examples).
* [**secure_cell**](secure_cell.rs) — simple file encryption/decryption based on [Secure Cell](https://docs.cossacklabs.com/pages/secure-cell-cryptosystem/).
* [**keygen**](keygen.rs) — a tool for generating ECDSA keys (usable by other examples).
* [**secure_cell**](secure_cell.rs) — showcase of [Secure Cell](https://docs.cossacklabs.com/pages/secure-cell-cryptosystem/) API.
* [**secure_compare**](secure_compare.rs) — zero-knowledge secret comparison based on [Secure Comparator](https://docs.cossacklabs.com/pages/secure-comparator-cryptosystem/).
* <b>secure_message_*</b> — secure group chat implemented with [Secure Message](https://docs.cossacklabs.com/pages/secure-message-cryptosystem/)
* <b>secure_message_*</b> — secure group chat implemented with [Secure Message](https://docs.cossacklabs.com/pages/secure-message-cryptosystem/)
* [**secure_message_server**](secure_message_server.rs) — simple relay server.
* [**secure_message_client_encrypt**](secure_message_client_encrypt.rs) — chat client which encrypts messages.
* [**secure_message_client_verify**](secure_message_client_verify.rs) — chat client which signs and verifies messages.
Expand Down Expand Up @@ -42,9 +42,8 @@ This tool can be used to generate key files usable for other examples.

## secure_cell

This is a simple file encryption tool.
It supports only the Seal mode of _Secure Cell_.

This is a simple API demo, it has no command-line arguments.
Note how encrypted message length depends on the mode being used.

## secure_compare

Expand Down
122 changes: 75 additions & 47 deletions docs/examples/rust/secure_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,57 +12,85 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fs::File;
use std::io::{self, Read, Write};

use clap::clap_app;
use themis::keys::SymmetricKey;
use themis::secure_cell::SecureCell;

fn main() {
let matches = clap_app!(secure_cell =>
(version: env!("CARGO_PKG_VERSION"))
(about: "Simple encryption with Secure Cell.")
(@group mode =>
(@arg encrypt: -e --encrypt "Encrypt the input [default]")
(@arg decrypt: -d --decrypt "Decrypt the input")
)
(@arg password: -p --password <string> "Password to use")
(@arg input: +required "Input file")
(@arg output: +required "Output file")
)
.get_matches();

let encrypt = !matches.is_present("decrypt");
let password = matches.value_of("password").unwrap();
let input_path = matches.value_of("input").unwrap();
let output_path = matches.value_of("output").unwrap();

let cell = SecureCell::with_key(&password).unwrap().seal();

let input = read_file(&input_path).unwrap();
let output = if encrypt {
cell.encrypt(&input).unwrap()
} else {
cell.decrypt(&input).unwrap()
};
write_file(&output_path, &output).unwrap();

if encrypt {
eprintln!("encrypted {} as {}", input_path, output_path);
} else {
eprintln!("decrypted {} into {}", input_path, output_path);
fn main() -> themis::Result<()> {
let message = b"We must all play our assigned roles. Are you a pawn or a queen?".as_ref();
let context = b"Consider the prospect that you have been misled, Alice.".as_ref();
let key = SymmetricKey::new();
let passphrase = "Then ask, by whom?";

println!("# Secure Cell in Seal mode");
println!();

println!("## Master key API");
println!();
{
let scell_mk = SecureCell::with_key(&key)?.seal();

println!("Encoded: {}", base64::encode(&message));

let encrypted_message = scell_mk.encrypt(&message)?;
println!("Encrypted: {}", base64::encode(&encrypted_message));

let decrypted_message = scell_mk.decrypt(&encrypted_message)?;
println!("Decrypted: {}", as_str(&decrypted_message));
assert_eq!(decrypted_message, message);
}
}
println!();

fn read_file(path: &str) -> Result<Vec<u8>, io::Error> {
let mut file = File::open(path)?;
let mut content = Vec::new();
file.read_to_end(&mut content)?;
Ok(content)
}
println!("## Passphrase API");
{
let scell_pw = SecureCell::with_passphrase(&passphrase)?.seal();

println!("Encoded: {}", base64::encode(&message));

let encrypted_message = scell_pw.encrypt(&message)?;
println!("Encrypted: {}", base64::encode(&encrypted_message));

let decrypted_message = scell_pw.decrypt(&encrypted_message)?;
println!("Decrypted: {}", as_str(&decrypted_message));
assert_eq!(decrypted_message, message);
}
println!();

println!("# Secure Cell in Token Protect mode");
println!();
{
let scell_tp = SecureCell::with_key(&key)?.token_protect();

println!("Encoded: {}", base64::encode(&message));

let (encrypted_message, auth_token) = scell_tp.encrypt(&message)?;
println!("Encrypted: {}", base64::encode(&encrypted_message));
println!("Auth token: {}", base64::encode(&auth_token));

let decrypted_message = scell_tp.decrypt(encrypted_message, auth_token)?;
println!("Decrypted: {}", as_str(&decrypted_message));
assert_eq!(decrypted_message, message);
}
println!();

println!("# Secure Cell in Context Imprint mode");
println!();
{
let scell_ci = SecureCell::with_key(&key)?.context_imprint();

println!("Encoded: {}", base64::encode(&message));

let encrypted_message = scell_ci.encrypt_with_context(&message, &context)?;
println!("Encrypted: {}", base64::encode(&encrypted_message));

let decrypted_message = scell_ci.decrypt_with_context(&encrypted_message, &context)?;
println!("Decrypted: {}", as_str(&decrypted_message));
assert_eq!(decrypted_message, message);
}
println!();

fn write_file(path: &str, data: &[u8]) -> Result<(), io::Error> {
let mut file = File::create(path)?;
file.write_all(data)?;
Ok(())
}

fn as_str(utf8_bytes: &[u8]) -> &str {
std::str::from_utf8(utf8_bytes).expect("valid UTF-8")
}
7 changes: 4 additions & 3 deletions src/wrappers/themis/rust/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ The version currently in development.

## New features

- New `SymmetricKey` objects can be used as master keys for `SecureCell`. ([#561])

[#561]: https://github.com/cossacklabs/themis/pull/561
- New `SymmetricKey` objects can be used as master keys for `SecureCell`.
([#561](https://github.com/cossacklabs/themis/pull/561))
- Safe passphrase API of Secure Cell: `SecureCell::with_passphrase`.
([#630](https://github.com/cossacklabs/themis/pull/630))

## Internal improvements

Expand Down
Loading