141 lines
4.2 KiB
Rust
141 lines
4.2 KiB
Rust
use std::io;
|
|
|
|
use tink_proto::{KeysetInfo, keyset_info::KeyInfo};
|
|
|
|
use crate::ManagedSecretValue;
|
|
|
|
use super::UploadKey;
|
|
|
|
#[test]
|
|
fn test_import_public_keyset() {
|
|
super::init();
|
|
|
|
// A base64-encoded public keyset as returned by warp-server.
|
|
let public_key = "COvInMIBEnAKZAo0dHlwZS5nb29nbGVhcGlzLmNvbS9nb29nbGUuY3J5cHRvLnRpbmsuSHBrZVB1YmxpY0tleRIqEgYIARABGAIaIHRaibhtYbpEfh2CSpdDPhh/6lCBnfoO3nqBmZ3VQGJyGAMQARjryJzCASAB";
|
|
let upload_key =
|
|
UploadKey::import_public_keyset(public_key).expect("unable to import public keyset");
|
|
|
|
let keyset_info = upload_key.public_key.keyset_info();
|
|
assert_eq!(
|
|
keyset_info,
|
|
KeysetInfo {
|
|
primary_key_id: 407315563,
|
|
key_info: vec![KeyInfo {
|
|
key_id: 407315563,
|
|
status: tink_proto::KeyStatusType::Enabled.into(),
|
|
type_url: "type.googleapis.com/google.crypto.tink.HpkePublicKey".to_string(),
|
|
output_prefix_type: tink_proto::OutputPrefixType::Tink.into(),
|
|
}],
|
|
}
|
|
);
|
|
|
|
let encrypted = upload_key
|
|
.encrypt
|
|
.encrypt(b"hello from rust", b"rust context")
|
|
.expect("unable to encrypt");
|
|
assert!(!encrypted.is_empty());
|
|
}
|
|
|
|
/// An HPKE private key for use in tests.
|
|
///
|
|
/// Created with:
|
|
/// ```sh
|
|
/// $ java -jar /opt/homebrew/Cellar/tinkey/1.12.0/bin/tinkey_deploy.jar create-keyset --key-template DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM --out-format json | jq .
|
|
/// ```
|
|
const TEST_PRIVATE_KEY: &str = r#"
|
|
{
|
|
"primaryKeyId": 625520774,
|
|
"key": [
|
|
{
|
|
"keyData": {
|
|
"typeUrl": "type.googleapis.com/google.crypto.tink.HpkePrivateKey",
|
|
"value": "EioSBggBEAEYAhogGHVh0Tju/DHOWEgpuUJ+9P/pXa5tK16udRWoJJwHbnIaIHdq5FthS7H4Q6xSLzCEnbf1z/F1+PTQHev/5PJ+pc+m",
|
|
"keyMaterialType": "ASYMMETRIC_PRIVATE"
|
|
},
|
|
"status": "ENABLED",
|
|
"keyId": 625520774,
|
|
"outputPrefixType": "TINK"
|
|
}
|
|
]
|
|
}
|
|
"#;
|
|
|
|
/// An HPKE public key for use in tests, corresponding to [`TEST_PRIVATE_KEY`].
|
|
///
|
|
/// Created with:
|
|
/// ```sh
|
|
/// $ java -jar /opt/homebrew/Cellar/tinkey/1.12.0/bin/tinkey_deploy.jar create-public-keyset | jq .
|
|
/// < private key JSON on stdin >
|
|
/// ```
|
|
const TEST_PUBLIC_KEY: &str = r#"
|
|
{
|
|
"primaryKeyId": 625520774,
|
|
"key": [
|
|
{
|
|
"keyData": {
|
|
"typeUrl": "type.googleapis.com/google.crypto.tink.HpkePublicKey",
|
|
"value": "EgYIARABGAIaIBh1YdE47vwxzlhIKblCfvT/6V2ubSternUVqCScB25y",
|
|
"keyMaterialType": "ASYMMETRIC_PUBLIC"
|
|
},
|
|
"status": "ENABLED",
|
|
"keyId": 625520774,
|
|
"outputPrefixType": "TINK"
|
|
}
|
|
]
|
|
}
|
|
"#;
|
|
|
|
/// Test encrypting a managed secret value.
|
|
#[test]
|
|
fn test_encrypt_managed_secret() {
|
|
super::init();
|
|
|
|
let keyset = read_keyset_json(TEST_PUBLIC_KEY);
|
|
let upload_key = UploadKey {
|
|
encrypt: tink_hybrid::new_encrypt(&keyset).expect("failed to create encrypt primitive"),
|
|
public_key: keyset,
|
|
};
|
|
|
|
let encrypted = upload_key
|
|
.encrypt_secret(
|
|
"user123",
|
|
"MY_SECRET",
|
|
&ManagedSecretValue::RawValue {
|
|
value: "secret".to_string(),
|
|
},
|
|
)
|
|
.expect("failed to encrypt secret");
|
|
assert!(!encrypted.is_empty());
|
|
}
|
|
|
|
/// Test our HPKE encryption and decryption primitives. At the very least, they should be able to roundtrip a plaintext value.
|
|
#[test]
|
|
fn test_encrypt_decrypt() {
|
|
super::init();
|
|
|
|
let private_key = read_keyset_json(TEST_PRIVATE_KEY);
|
|
let public_key = read_keyset_json(TEST_PUBLIC_KEY);
|
|
|
|
let encrypt =
|
|
tink_hybrid::new_encrypt(&public_key).expect("failed to create encrypt primitive");
|
|
let decrypt =
|
|
tink_hybrid::new_decrypt(&private_key).expect("failed to create decrypt primitive");
|
|
|
|
let context = b"I am context";
|
|
let plaintext = b"hello from rust";
|
|
|
|
let encrypted = encrypt
|
|
.encrypt(plaintext, context)
|
|
.expect("failed to encrypt");
|
|
let decrypted = decrypt
|
|
.decrypt(&encrypted, context)
|
|
.expect("failed to decrypt");
|
|
|
|
assert_eq!(decrypted, plaintext);
|
|
}
|
|
|
|
fn read_keyset_json(json: &str) -> tink_core::keyset::Handle {
|
|
let mut reader = tink_core::keyset::JsonReader::new(io::Cursor::new(json.as_bytes()));
|
|
tink_core::keyset::insecure::read(&mut reader).expect("failed to read keyset")
|
|
}
|