#[cfg(test)]
mod tests {
use std::collections::HashMap;
use crate::*;
use eznacl::*;
fn orgentry_make_compliant_card()
-> Result<(Entry, HashMap<&'static str,CryptoString>), LKCError> {
let testname = "orgentry_make_compliant_card";
let mut entry = crate::Entry::new(EntryType::Organization)?;
let mut map = HashMap::<&str, CryptoString>::new();
let primary_keypair = match eznacl::SigningPair::from_strings(
"ED25519:)8id(gE02^S<{3H>9B;X4{DuYcb`%wo^mC&1lN88",
"ED25519:msvXw(nII<Qm6oBHc+92xwRI3>VFF-RcZ=7DEu3|") {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("{}: failed to generate primary keypair: {}",
testname, e.to_string())))
},
};
map.insert("primary.public",
CryptoString::from(&primary_keypair.get_public_str()).expect(
"Error getting inserting primary verification key in OrgEntry::chain()"));
map.insert("primary.private",
CryptoString::from(&primary_keypair.get_private_str()).expect(
"Error getting inserting primary signing key in OrgEntry::chain()"));
let secondary_keypair = match eznacl::SigningPair::from_strings(
"ED25519:^j&t+&+q3fgPe1%PLmW4i|RCV|KNWZBLByIUZg+~",
"ED25519:4%Xb|FD_^#62(<)y0>C7LM0K=bdq7pwV62{V&O+1") {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("{}: failed to generate secondary keypair: {}",
testname, e.to_string())))
},
};
map.insert("secondary.public",
CryptoString::from(&secondary_keypair.get_public_str()).expect(
"Error getting inserting secondary verification key in OrgEntry::chain()"));
map.insert("secondary.private",
CryptoString::from(&secondary_keypair.get_private_str()).expect(
"Error getting inserting secondary signing key in OrgEntry::chain()"));
let encryption_keypair = match eznacl::SigningPair::from_strings(
"CURVE25519:@b?cjpeY;<&y+LSOA&yUQ&ZIrp(JGt{W$*V>ATLG",
"CURVE25519:nQxAR1Rh{F4gKR<KZz)*)7}5s_^!`!eb!sod0<aT") {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("{}: failed to generate encryptionkeypair: {}",
testname, e.to_string())))
},
};
map.insert("encryption.public",
CryptoString::from(&encryption_keypair.get_public_str()).expect(
"Error getting inserting encryption key in OrgEntry::chain()"));
map.insert("encryption.private",
CryptoString::from(&encryption_keypair.get_private_str()).expect(
"Error getting inserting decryption key in OrgEntry::chain()"));
let carddata = vec![
(String::from("Index"), String::from("1")),
(String::from("Name"), String::from("Example, Inc.")),
(String::from("Domain"), String::from("example.com")),
(String::from("Contact-Admin"),
String::from("11111111-2222-2222-2222-333333333333/example.com")),
(String::from("Contact-Support"),
String::from("11111111-2222-2222-2222-444444444444/example.com")),
(String::from("Contact-Abuse"),
String::from("11111111-2222-2222-2222-555555555555/example.com")),
(String::from("Language"), String::from("en")),
(String::from("Primary-Verification-Key"), primary_keypair.get_public_str()),
(String::from("Secondary-Verification-Key"), secondary_keypair.get_public_str()),
(String::from("Encryption-Key"), encryption_keypair.get_public_str()),
(String::from("Time-To-Live"), String::from("14")),
(String::from("Expires"), String::from("20250601")),
(String::from("Timestamp"), String::from("20220520T120000Z"))
];
match entry.set_fields(&carddata) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_is_compliant: failed to set entry fields: {}", e.to_string())))
}
}
match entry.hash("BLAKE2B-256") {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_is_compliant: hash returned an error: {}", e.to_string())))
}
}
match entry.sign("Organization-Signature", &primary_keypair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_is_compliant: sign returned an error: {}", e.to_string())))
}
}
match entry.verify_signature("Organization-Signature", &primary_keypair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_is_compliant: org sig verification error: {}", e.to_string())))
}
}
Ok((entry, map))
}
fn userentry_make_compliant_card()
-> Result<(Entry, HashMap<&'static str,CryptoString>), LKCError> {
let testname = "userentry_make_compliant_card";
let mut entry = crate::Entry::new(EntryType::User)?;
let mut map = HashMap::<&str, CryptoString>::new();
let crskeypair = match eznacl::SigningPair::from_strings(
"ED25519:d0-oQb;{QxwnO{=!|^62+E=UYk2Y3mr2?XKScF4D",
"ED25519:ip52{ps^jH)t$k-9bc_RzkegpIW?}FFe~BX&<V}9") {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("{}: failed to generate CR signing keypair: {}",
testname, e.to_string())))
},
};
map.insert("crsigning.public",
CryptoString::from(&crskeypair.get_public_str()).expect(
"Error getting inserting primary verification key in \
UserEntry::userentry_make_compliant_card()"));
map.insert("crsigning.private",
CryptoString::from(&crskeypair.get_private_str()).expect(
"Error getting inserting primary signing key in \
UserEntry::userentry_make_compliant_card()"));
let crekeypair = match eznacl::SigningPair::from_strings(
"CURVE25519:j(IBzX*F%OZF;g77O8jrVjM1a`Y<6-ehe{S;{gph",
"CURVE25519:55t6A0y%S?{7c47p(R@C*X#at9Y`q5(Rc#YBS;r}") {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("{}: failed to generate CR encryption keypair: {}",
testname, e.to_string())))
},
};
map.insert("crencryption.public",
CryptoString::from(&crekeypair.get_public_str()).expect(
"Error getting inserting CR encryption key in userentry_make_compliant_card()"));
map.insert("crencryption.private",
CryptoString::from(&crekeypair.get_private_str()).expect(
"Error getting inserting CR decryption key in userentry_make_compliant_card()"));
let skeypair = match eznacl::SigningPair::from_strings(
"ED25519:6|HBWrxMY6-?r&Sm)_^PLPerpqOj#b&x#N_#C3}p",
"ED25519:p;XXU0XF#UO^}vKbC-wS(#5W6=OEIFmR2z`rS1j+") {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("{}: failed to generate signing keypair: {}", testname, e.to_string())))
},
};
map.insert("signing.public",
CryptoString::from(&skeypair.get_public_str()).expect(
"Error getting inserting verification key in userentry_make_compliant_card()"));
map.insert("signing.private",
CryptoString::from(&skeypair.get_private_str()).expect(
"Error getting inserting signing key in userentry_make_compliant_card()"));
let ekeypair = match eznacl::SigningPair::from_strings(
"CURVE25519:nSRso=K(WF{P+4x5S*5?Da-rseY-^>S8VN#v+)IN",
"CURVE25519:4A!nTPZSVD#tm78d=-?1OIQ43{ipSpE;@il{lYkg") {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("{}: failed to generate encryption keypair: {}",
testname, e.to_string())))
},
};
map.insert("encryption.public",
CryptoString::from(&ekeypair.get_public_str()).expect(
"Error getting inserting encryption key in userentry_make_compliant_card()"));
map.insert("encryption.private",
CryptoString::from(&ekeypair.get_private_str()).expect(
"Error getting inserting decryption key in userentry_make_compliant_card()"));
let carddata = vec![
(String::from("Index"), String::from("1")),
(String::from("Name"), String::from("Corbin Simons")),
(String::from("Workspace-ID"), String::from("4418bf6c-000b-4bb3-8111-316e72030468")),
(String::from("User-ID"), String::from("csimons")),
(String::from("Domain"), String::from("example.com")),
(String::from("Contact-Request-Verification-Key"), crskeypair.get_public_str()),
(String::from("Contact-Request-Encryption-Key"), crekeypair.get_public_str()),
(String::from("Verification-Key"), skeypair.get_public_str()),
(String::from("Encryption-Key"), ekeypair.get_public_str()),
(String::from("Time-To-Live"), String::from("14")),
(String::from("Expires"), String::from("20250601")),
(String::from("Timestamp"), String::from("20220520T120000Z"))
];
match entry.set_fields(&carddata) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_make_compliant_card: failed to set entry fields: {}", e.to_string())))
}
}
let orgspair = match SigningPair::from_strings(
"ED25519:)8id(gE02^S<{3H>9B;X4{DuYcb`%wo^mC&1lN88",
"ED25519:msvXw(nII<Qm6oBHc+92xwRI3>VFF-RcZ=7DEu3|") {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("{}: failed to generate org signing keypair: {}",
testname, e.to_string())))
},
};
map.insert("orgsigning.public",
CryptoString::from(&orgspair.get_public_str()).expect(
"Error getting inserting org verification key in userentry_make_compliant_card()"));
map.insert("orgsigning.private",
CryptoString::from(&orgspair.get_private_str()).expect(
"Error getting inserting org signing key in userentry_make_compliant_card()"));
match entry.sign("Organization-Signature", &orgspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_make_compliant_card: org signing returned an error: {}",
e.to_string())))
}
}
let orghash = match CryptoString::from(
"BLAKE2B-256:y}vk``*Rk3Ksq<?Z;Gwf-!eZco0=i`bI^V}E#{{e") {
Some(v) => v,
None => {
return Err(LKCError::ErrProgramException(
format!("userentry_make_compliant_card: failed to generate org hash")))
},
};
match entry.add_authstr("Previous-Hash", &orghash) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_make_compliant_card: failed to set previous hash: {}",
e.to_string())))
}
}
match entry.hash("BLAKE2B-256") {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_make_compliant_card: hash returned an error: {}",
e.to_string())))
}
}
match entry.sign("User-Signature", &crskeypair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_make_compliant_card: user signing returned an error: {}",
e.to_string())))
}
}
Ok((entry, map))
}
#[test]
fn orgentry_from_datacompliant() -> Result<(), LKCError> {
let good_carddata = concat!(
"Type:Organization\r\n",
"Index:2\r\n",
"Name:Acme, Inc.\r\n",
"Domain:example.com\r\n",
"Contact-Admin:11111111-2222-2222-2222-333333333333/acme.com\r\n",
"Contact-Support:11111111-2222-2222-2222-444444444444/acme.com\r\n",
"Contact-Abuse:11111111-2222-2222-2222-555555555555/acme.com\r\n",
"Language:en\r\n",
"Primary-Verification-Key:ED25519:)8id(gE02^S<{3H>9B;X4{DuYcb`%wo^mC&1lN88\r\n",
"Secondary-Verification-Key:ED25519:^j&t+&+q3fgPe1%PLmW4i|RCV|KNWZBLByIUZg+~\r\n",
"Encryption-Key:CURVE25519:@b?cjpeY;<&y+LSOA&yUQ&ZIrp(JGt{W$*V>ATLG\r\n",
"Time-To-Live:14\r\n",
"Expires:20231231\r\n",
"Timestamp:20220501T135211Z\r\n",
"Custody-Signature:ED25519:x3)dYq@S0rd1Rfbie*J7kF{fkxQ=J=A)OoO1WGx97o-utWtfbw\r\n",
"Previous-Hash:BLAKE2B-256:tSl@QzD1w-vNq@CC-5`($KuxO0#aOl^-cy(l7XXT\r\n",
"Hash:BLAKE2B-256:6XG#bSNuJyLCIJxUa-O`V~xR{kF4UWxaFJvPvcwg\r\n",
"Organization-Signature:ED25519:x3)dYq@S0rd1Rfbie*J7kF{fkxQ=J=A)OoO1WGx97o-utWtfbw\r\n");
let entry = match crate::Entry::from(good_carddata) {
Ok(v) => { v },
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_set_datacompliant failed on good data: {}", e.to_string())))
}
};
match entry.is_data_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_set_datacompliant error on compliant data: {}", e.to_string())))
}
}
Ok(())
}
#[test]
fn userentry_from_datacompliant() -> Result<(), LKCError> {
let good_carddata =
"Type:User\r\n\
Index:1\r\n\
Name:Corbin Simons\r\n\
User-ID:csimons\r\n\
Workspace-ID:4418bf6c-000b-4bb3-8111-316e72030468\r\n\
Domain:example.com\r\n\
Contact-Request-Verification-Key:ED25519:d0-oQb;{QxwnO{=!|^62+E=UYk2Y3mr2?XKScF4D\r\n\
Contact-Request-Encryption-Key:CURVE25519:j(IBzX*F%OZF;g77O8jrVjM1a`Y<6-ehe{S;{gph\r\n\
Encryption-Key:CURVE25519:nSRso=K(WF{P+4x5S*5?Da-rseY-^>S8VN#v+)IN\r\n\
Verification-Key:ED25519:6|HBWrxMY6-?r&Sm)_^PLPerpqOj#b&x#N_#C3}p\r\n\
Time-To-Live:14\r\n\
Expires:20250601\r\n\
Timestamp:20220520T120000Z\r\n\
Organization-Signature:ED25519:%WEh<1SA;@68mf1j!W>6>JL7Uf0PMiZIsMFRnQFBuZZ1?i^}$\
^elxZ<<*>N8As@(9#eM-I|DA>0KQT!T\r\n\
Previous-Hash:BLAKE2B-256:5p?~_i$tLp<u5)cide0_jfVkSEw9tuaXOQK<jx1X\r\n\
Hash:BLAKE2B-256:m@b+Gq}GZqRD@M?<D7y)?v`W#12rxX&sQ-Fc-(|6\r\n\
User-Signature:ED25519:%MBaz#oQ>Mge+0X<+S0OLGW8*`{k&%W=LB^*kLN2HB`N5d@nqJWoxk+rys\
0@1rR8`Cj)Y`ZcWX^>G+`v\r\n";
let entry = match crate::Entry::from(good_carddata) {
Ok(v) => { v },
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_set_datacompliant failed on good data: {}", e.to_string())))
}
};
match entry.is_data_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_set_datacompliant error on compliant data: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn test_get_owner() -> Result<(), LKCError> {
let empty_entry = crate::Entry::new(EntryType::Organization)?;
match empty_entry.get_owner() {
Ok(_) => {
return Err(LKCError::ErrProgramException(
format!("test_get_owner passed an invalid value for org entry")))
},
Err(_) => (),
}
let (orgentry, _) = orgentry_make_compliant_card()?;
let owner = orgentry.get_owner()?;
if owner != "example.com" {
return Err(LKCError::ErrProgramException(
format!("test_get_owner org entry owner value mismatch")))
}
let empty_entry = crate::Entry::new(EntryType::User)?;
match empty_entry.get_owner() {
Ok(_) => {
return Err(LKCError::ErrProgramException(
format!("test_get_owner passed an invalid value for user entry")))
},
Err(_) => (),
}
let (userentry, _) = userentry_make_compliant_card()?;
let owner = userentry.get_owner()?;
if owner != "4418bf6c-000b-4bb3-8111-316e72030468/example.com" {
return Err(LKCError::ErrProgramException(
format!("test_get_owner user entry owner value mismatch")))
}
Ok(())
}
#[test]
fn orgentry_set_get_field() -> Result<(), LKCError> {
let mut entry = crate::Entry::new(EntryType::Organization)?;
match entry.set_field("Domain", "/123*") {
Ok(_) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_set_field passed an invalid value")))
},
Err(_) => {
}
}
match entry.set_field("Name", &"5".repeat(10000)) {
Ok(_) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_set_field passed a too-large value")))
},
Err(_) => (),
}
match entry.set_field("UserID", "csimons") {
Ok(_) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_set_field allowed an invalid entry type")))
},
Err(_) => {
}
}
match entry.set_field("Name", "Corbin Simons") {
Ok(_) => { },
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_set_field failed: {}", e.to_string())))
}
}
match entry.get_field("Domain") {
Ok(_) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_get_field passed a nonexistent field")))
},
Err(_) => {
}
}
match entry.get_field("Name") {
Ok(_) => { },
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_get_field failed: {}", e.to_string())))
}
}
Ok(())
}
#[test]
fn orgentry_set_fields() -> Result<(), LKCError> {
let mut entry = crate::Entry::new(EntryType::Organization)?;
let mut testdata = vec![
(String::from("Name"), String::from("Example, Inc.")),
(String::from("contact-Admin"),
String::from("11111111-1111-1111-1111-111111111111/example.com")),
];
match entry.set_fields(&testdata) {
Ok(_) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_set_fields passed an invalid key")))
},
Err(_) => {
}
}
testdata = vec![
(String::from("Name"), String::from("Example, Inc.")),
(String::from("Contact-Admin"),
String::from("11111111-1111-1111-1111-111111111111/example.com")),
];
match entry.set_fields(&testdata) {
Ok(_) => Ok(()),
Err(e) => {
Err(LKCError::ErrProgramException(
format!("orgentry_set_fields failed: {}", e.to_string())))
}
}
}
#[test]
fn orgentry_delete_field() -> Result<(), LKCError> {
let mut entry = crate::Entry::new(EntryType::Organization)?;
match entry.set_field("Name", "Corbin Simons") {
Ok(_) => { },
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_delete_field failed: {}", e.to_string())))
}
}
match entry.get_field("Name") {
Ok(_) => { },
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_delete_field failed to get field: {}", e.to_string())))
}
}
match entry.delete_field("Name") {
Ok(_) => {
},
Err(_) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_delete_field failed to delete a field")))
}
}
match entry.get_field("Name") {
Ok(_) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_delete_field didn't actually delete the test field")))
},
Err(_) => {
}
}
Ok(())
}
#[test]
fn orgentry_get_text() -> Result<(), LKCError> {
let (entry, _) = orgentry_make_compliant_card()?;
let entrytext = match entry.get_text() {
Ok(v) => v,
Err(_) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_get_text failed to generate entry text")))
}
};
let expectedtext = "Type:Organization\r\n\
Index:1\r\n\
Name:Example, Inc.\r\n\
Domain:example.com\r\n\
Contact-Admin:11111111-2222-2222-2222-333333333333/example.com\r\n\
Contact-Abuse:11111111-2222-2222-2222-555555555555/example.com\r\n\
Contact-Support:11111111-2222-2222-2222-444444444444/example.com\r\n\
Language:en\r\n\
Primary-Verification-Key:ED25519:)8id(gE02^S<{3H>9B;X4{DuYcb`%wo^mC&1lN88\r\n\
Secondary-Verification-Key:ED25519:^j&t+&+q3fgPe1%PLmW4i|RCV|KNWZBLByIUZg+~\r\n\
Encryption-Key:CURVE25519:@b?cjpeY;<&y+LSOA&yUQ&ZIrp(JGt{W$*V>ATLG\r\n\
Time-To-Live:14\r\n\
Expires:20250601\r\n\
Timestamp:20220520T120000Z\r\n";
let entrybytes = entrytext.as_bytes();
let expectedbytes = expectedtext.as_bytes();
if entrybytes.len() != expectedbytes.len() {
return Err(LKCError::ErrProgramException(
format!("orgentry_get_text: byte lengths differ")))
}
for i in 0..entrybytes.len() {
if entrybytes[i] != expectedbytes[i] {
print!("{}\n-----\n{}", entrytext, expectedtext);
return Err(LKCError::ErrProgramException(
format!("orgentry_get_text: strings differ at index {} ({})", i, entrybytes[i])))
}
}
Ok(())
}
#[test]
fn userentry_get_text() -> Result<(), LKCError> {
let (entry, _) = userentry_make_compliant_card()?;
let entrytext = match entry.get_text() {
Ok(v) => v,
Err(_) => {
return Err(LKCError::ErrProgramException(
format!("userentry_get_text failed to generate entry text")))
}
};
let expectedtext = "Type:User\r\n\
Index:1\r\n\
Name:Corbin Simons\r\n\
User-ID:csimons\r\n\
Workspace-ID:4418bf6c-000b-4bb3-8111-316e72030468\r\n\
Domain:example.com\r\n\
Contact-Request-Verification-Key:ED25519:d0-oQb;{QxwnO{=!|^62\
+E=UYk2Y3mr2?XKScF4D\r\n\
Contact-Request-Encryption-Key:CURVE25519:j(IBzX*F%OZF;g77O8jr\
VjM1a`Y<6-ehe{S;{gph\r\n\
Encryption-Key:CURVE25519:nSRso=K(WF{P+4x5S*5?Da-rseY-^>S8VN#v+)IN\r\n\
Verification-Key:ED25519:6|HBWrxMY6-?r&Sm)_^PLPerpqOj#b&x#N_#C3}p\r\n\
Time-To-Live:14\r\n\
Expires:20250601\r\n\
Timestamp:20220520T120000Z\r\n";
let entrybytes = entrytext.as_bytes();
let expectedbytes = expectedtext.as_bytes();
for i in 0..entrybytes.len() {
if entrybytes[i] != expectedbytes[i] {
print!("\"{}\"\n-----\n\"{}\"\n", entrytext, expectedtext);
return Err(LKCError::ErrProgramException(
format!("userentry_get_text: strings differ at index {} ({})", i, entrybytes[i])))
}
}
Ok(())
}
#[test]
fn orgentry_is_compliant() -> Result<(), LKCError> {
let (entry, _) = orgentry_make_compliant_card()?;
match entry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_is_compliant: is_compliant returned an error: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn userentry_is_compliant() -> Result<(), LKCError> {
let (entry, _) = userentry_make_compliant_card()?;
match entry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_is_compliant: is_compliant returned an error: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn orgentry_hash_sign_verify() -> Result<(), LKCError> {
let (entry, keys) = orgentry_make_compliant_card()?;
match entry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_hash_sign_verify: is_compliant returned an error: {}",
e.to_string())))
}
}
let primaryver = keys.get("primary.public")
.expect("orgentry_hash_sign_verify: Failed to get primary verification key");
let primarysign = keys.get("primary.private")
.expect("orgentry_hash_sign_verify: Failed to get primary signing key");
let primarypair = SigningPair::from(&primaryver, &primarysign).unwrap();
match entry.get_authstr("Hash") {
Ok(v) => {
if v.to_string() != "BLAKE2B-256:y}vk``*Rk3Ksq<?Z;Gwf-!eZco0=i`bI^V}E#{{e" {
println!("Quoted entry text:\n\"{}\"", entry.get_full_text("Hash")?);
return Err(LKCError::ErrProgramException(
format!("orgentry_hash_sign_verify: hash mismatch: {}", v.to_string())))
}
},
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_hash_sign_verify: failed to obtain hash: {}",
e.to_string())))
},
}
match entry.get_authstr("Organization-Signature") {
Ok(v) => {
if v.to_string() != "ED25519:;8qjG%N9rgkM|mz=*khspcTy(MnwmqCL>4h$JN^~1~7E!=P3=XRNq#(eX1r&NZr{{y*jP15K`oI12!89" {
println!("Quoted entry text:\n\"{}\"",
entry.get_full_text("Organization-Signature")?);
return Err(LKCError::ErrProgramException(
format!("orgentry_hash_sign_verify: signature mismatch: {}", v.to_string())))
}
},
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_hash_sign_verify: failed to obtain signature: {}",
e.to_string())))
},
}
match entry.verify_signature("Organization-Signature", &primarypair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_hash_sign_verify: error verifying org signature: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn userentry_hash_sign_verify() -> Result<(), LKCError> {
let (entry, keys) = userentry_make_compliant_card()?;
match entry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_hash_sign_verify: is_compliant returned an error: {}",
e.to_string())))
}
}
match entry.get_authstr("Organization-Signature") {
Ok(v) => {
if v.to_string() != "ED25519:%WEh<1SA;@68mf1j!W>6>JL7Uf0PMiZIsMFRnQFBuZZ1?i^}$^elxZ<<*>N8As@(9#eM-I|DA>0KQT!T" {
let expectedtext = "Type:User\r\n\
Index:1\r\n\
Name:Corbin Simons\r\n\
User-ID:csimons\r\n\
Workspace-ID:4418bf6c-000b-4bb3-8111-316e72030468\r\n\
Domain:example.com\r\n\
Contact-Request-Verification-Key:ED25519:d0-oQb;{QxwnO{=!|^62\
+E=UYk2Y3mr2?XKScF4D\r\n\
Contact-Request-Encryption-Key:CURVE25519:j(IBzX*F%OZF;g77O8jr\
VjM1a`Y<6-ehe{S;{gph\r\n\
Encryption-Key:CURVE25519:nSRso=K(WF{P+4x5S*5?Da-rseY-^>S8VN#v+)IN\r\n\
Verification-Key:ED25519:6|HBWrxMY6-?r&Sm)_^PLPerpqOj#b&x#N_#C3}p\r\n\
Time-To-Live:14\r\n\
Expires:20250601\r\n\
Timestamp:20220520T120000Z\r\n";
let basetext = entry.get_full_text("Organization-Signature")?;
if basetext != expectedtext {
print!("\"{}\"\n-----\n\"{}\"\n", basetext, expectedtext);
return Err(LKCError::ErrProgramException(
String::from("userentry_hash_sign_verify: base text mismatch")))
}
println!("Quoted entry text:\n\"{}\"",
entry.get_full_text("Organization-Signature")?);
return Err(LKCError::ErrProgramException(
format!("userentry_hash_sign_verify: org signature mismatch: {}",
v.to_string())))
}
},
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_hash_sign_verify: failed to obtain signature: {}",
e.to_string())))
},
}
match entry.get_authstr("Hash") {
Ok(v) => {
if v.to_string() != "BLAKE2B-256:a3d?}8lWj(aVC`n6v|n^JE0=O_Co8G#whQ@TUQ}F" {
println!("Quoted entry text:\n\"{}\"",
entry.get_full_text("")?);
return Err(LKCError::ErrProgramException(
format!("userentry_hash_sign_verify: hash mismatch: {}", v.to_string())))
}
},
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_hash_sign_verify: failed to obtain hash: {}",
e.to_string())))
},
}
match entry.get_authstr("User-Signature") {
Ok(v) => {
if v.to_string() != "ED25519:6C;cV^$<FXAqHc8ckWP%vxii-*nnS>sW}2U6h1Szsn`=;%!Z=9t^;T%Nxfg!?p=`3fBS_1aV$KOx>b|{" {
println!("Quoted entry text:\n\"{}\"",
entry.get_full_text("User-Signature")?);
return Err(LKCError::ErrProgramException(
format!("userentry_hash_sign_verify: user signature mismatch: {}",
v.to_string())))
}
},
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_hash_sign_verify: failed to obtain user signature: {}",
e.to_string())))
},
}
let orgver = keys.get("orgsigning.public")
.expect("userentry_hash_sign_verify: Failed to get org verification key");
let orgsign = keys.get("orgsigning.private")
.expect("userentry_hash_sign_verify: Failed to get org signing key");
let orgspair = SigningPair::from(&orgver, &orgsign).unwrap();
match entry.verify_signature("Organization-Signature", &orgspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_hash_sign_verify: error verifying org signature: {}",
e.to_string())))
}
}
let crver = keys.get("crsigning.public")
.expect("userentry_hash_sign_verify: Failed to get CR verification key");
let crsign = keys.get("crsigning.private")
.expect("userentry_hash_sign_verify: Failed to get CR signing key");
let crspair = SigningPair::from(&crver, &crsign).unwrap();
match entry.verify_signature("User-Signature", &crspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_hash_sign_verify: error verifying user signature: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn orgentry_chain_verify() -> Result<(), LKCError> {
let (firstentry, firstkeys) = orgentry_make_compliant_card()?;
match firstentry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_chain_verify: is_compliant returned an error: {}",
e.to_string())))
}
}
let primaryver = firstkeys.get("primary.public")
.expect("orgentry_chain_verify: Failed to get primary verification key");
let primarysign = firstkeys.get("primary.private")
.expect("orgentry_chain_verify: Failed to get primary signing key");
let primarypair = SigningPair::from(&primaryver, &primarysign).unwrap();
let (newentry, _) = match firstentry.chain(&primarypair, 365) {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_chain_verify: chain returned an error: {}",
e.to_string())))
}
};
match newentry.verify_chain(&firstentry) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_chain_verify: verify_chain returned an error: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn userentry_chain_verify() -> Result<(), LKCError> {
let (firstentry, firstkeys) = userentry_make_compliant_card()?;
match firstentry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_chain_verify: is_compliant returned an error: {}",
e.to_string())))
}
}
let crver = firstkeys.get("crsigning.public")
.expect("userentry_chain_verify: Failed to get CR verification key");
let crsign = firstkeys.get("crsigning.private")
.expect("userentry_chain_verify: Failed to get CR signing key");
let crspair = SigningPair::from(&crver, &crsign).unwrap();
let (mut newentry, newkeys) = match firstentry.chain(&crspair, 365) {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_chain_verify: chain returned an error: {}",
e.to_string())))
}
};
let orgver = firstkeys.get("orgsigning.public")
.expect("userentry_chain_verify: Failed to get org verification key");
let orgsign = firstkeys.get("orgsigning.private")
.expect("userentry_chain_verify: Failed to get org signing key");
let orgspair = SigningPair::from(&orgver, &orgsign).unwrap();
match newentry.sign("Organization-Signature", &orgspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_chain_verify: org sign returned an error: {}",
e.to_string())))
}
}
match newentry.hash("BLAKE2B-256") {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_chain_verify: hash returned an error: {}", e.to_string())))
}
}
let newverkey = newkeys.get("crsigning.public")
.expect("userentry_chain_verify: failed to get new verification key");
let newsignkey = newkeys.get("crsigning.private")
.expect("userentry_chain_verify: failed to get new signing key");
let newcrspair = SigningPair::from(newverkey, newsignkey).unwrap();
match newentry.sign("User-Signature", &newcrspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_chain_verify: is_compliant returned an error: {}",
e.to_string())))
}
}
match newentry.verify_chain(&firstentry) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_chain_verify: verify_chain returned an error: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn orgentry_revoke() -> Result<(), LKCError> {
let (firstentry, firstkeys) = orgentry_make_compliant_card()?;
match firstentry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_revoke: is_compliant returned an error: {}",
e.to_string())))
}
}
let primaryver = firstkeys.get("primary.public")
.expect("orgentry_revoke: Failed to get primary verification key");
let primarysign = firstkeys.get("primary.private")
.expect("orgentry_revoke: Failed to get primary signing key");
let primarypair = SigningPair::from(&primaryver, &primarysign).unwrap();
let mut card = Keycard::new(EntryType::Organization);
card.entries.push(firstentry);
let _ = match card.chain(&primarypair, 365) {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_revoke: chain returned an error: {}",
e.to_string())))
}
};
match card.verify() {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_revoke: card failed to verify: {}",
e.to_string())))
}
};
let current = card.get_current().expect("Failed to get current entry in orgentry_revoke");
let (newroot, _) = match current.revoke(365) {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_revoke: failed to revoke current entry: {}",
e.to_string())))
}
};
match newroot.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("orgentry_revoke: new root entry is_compliant returned an error: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn userentry_revoke() -> Result<(), LKCError> {
let (firstentry, firstkeys) = userentry_make_compliant_card()?;
match firstentry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: is_compliant returned an error: {}",
e.to_string())))
}
}
let crver = firstkeys.get("crsigning.public")
.expect("userentry_revoke: Failed to get CR verification key");
let crsign = firstkeys.get("crsigning.private")
.expect("userentry_revoke: Failed to get CR signing key");
let crspair = SigningPair::from(&crver, &crsign).unwrap();
let (_, newkeys) = match firstentry.chain(&crspair, 365) {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: chain returned an error: {}",
e.to_string())))
}
};
let mut card = Keycard::new(EntryType::User);
card.entries.push(firstentry);
let orgver = firstkeys.get("orgsigning.public")
.expect("userentry_revoke: Failed to get org verification key");
let orgsign = firstkeys.get("orgsigning.private")
.expect("userentry_revoke: Failed to get org signing key");
let orgspair = SigningPair::from(&orgver, &orgsign).unwrap();
match card.cross_sign(&orgspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: cross_sign returned an error: {}",
e.to_string())))
}
}
let newverkey = newkeys.get("crsigning.public")
.expect("userentry_revoke: failed to get new verification key");
let newsignkey = newkeys.get("crsigning.private")
.expect("userentry_revoke: failed to get new signing key");
let newcrspair = SigningPair::from(newverkey, newsignkey).unwrap();
match card.user_sign("BLAKE2B-256", &newcrspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: user_sign returned an error: {}",
e.to_string())))
}
}
match card.verify() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: verify returned an error: {}",
e.to_string())))
}
}
let current = card.get_current().expect("Failed to get current entry in userentry_revoke");
let (mut newroot, revkeys) = match current.revoke(365) {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: failed to revoke current entry: {}",
e.to_string())))
}
};
match newroot.sign("Organization-Signature", &orgspair) {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: failed to org sign new root entry: {}",
e.to_string())))
}
}
let orghash = match CryptoString::from(
"BLAKE2B-256:5p?~_i$tLp<u5)cide0_jfVkSEw9tuaXOQK<jx1X") {
Some(v) => v,
None => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: failed to generate org hash")))
},
};
match newroot.add_authstr("Previous-Hash", &orghash) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: failed to add previous hash to new root entry: {}",
e.to_string())))
}
}
let revverkey = revkeys.get("crsigning.public")
.expect("userentry_revoke: failed to get post-revocation verification key");
let revsignkey = revkeys.get("crsigning.private")
.expect("userentry_revoke: failed to get post-revocation signing key");
let revcrspair = SigningPair::from(revverkey, revsignkey).unwrap();
match newroot.hash("BLAKE2B-256") {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: new root entry hash error: {}",
e.to_string())))
}
}
match newroot.sign("User-Signature", &revcrspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: new root entry signing error: {}",
e.to_string())))
}
}
match newroot.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("userentry_revoke: new root entry is_compliant returned an error: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn org_keycard_chain_verify() -> Result<(), LKCError> {
let (firstentry, firstkeys) = orgentry_make_compliant_card()?;
match firstentry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("org_keycard_chain_verify: is_compliant returned an error: {}",
e.to_string())))
}
}
let primaryver = firstkeys.get("primary.public")
.expect("org_keycard_chain_verify: Failed to get primary verification key");
let primarysign = firstkeys.get("primary.private")
.expect("org_keycard_chain_verify: Failed to get primary signing key");
let primarypair = SigningPair::from(&primaryver, &primarysign).unwrap();
let mut card = Keycard::new(EntryType::Organization);
card.entries.push(firstentry);
let _ = match card.chain(&primarypair, 365) {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("org_keycard_chain_verify: chain returned an error: {}",
e.to_string())))
}
};
match card.verify() {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("org_keycard_chain_verify: card failed to verify: {}",
e.to_string())))
}
};
Ok(())
}
#[test]
fn user_keycard_chain_verify() -> Result<(), LKCError> {
let (firstentry, firstkeys) = userentry_make_compliant_card()?;
match firstentry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("user_keycard_chain_verify: is_compliant returned an error: {}",
e.to_string())))
}
}
let crver = firstkeys.get("crsigning.public")
.expect("user_keycard_chain_verify: Failed to get CR verification key");
let crsign = firstkeys.get("crsigning.private")
.expect("user_keycard_chain_verify: Failed to get CR signing key");
let crspair = SigningPair::from(&crver, &crsign).unwrap();
let (_, newkeys) = match firstentry.chain(&crspair, 365) {
Ok(v) => v,
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("user_keycard_chain_verify: chain returned an error: {}",
e.to_string())))
}
};
let mut card = Keycard::new(EntryType::User);
card.entries.push(firstentry);
let orgver = firstkeys.get("orgsigning.public")
.expect("user_keycard_chain_verify: Failed to get org verification key");
let orgsign = firstkeys.get("orgsigning.private")
.expect("user_keycard_chain_verify: Failed to get org signing key");
let orgspair = SigningPair::from(&orgver, &orgsign).unwrap();
match card.cross_sign(&orgspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("user_keycard_chain_verify: cross_sign returned an error: {}",
e.to_string())))
}
}
let newverkey = newkeys.get("crsigning.public")
.expect("user_keycard_chain_verify: failed to get new verification key");
let newsignkey = newkeys.get("crsigning.private")
.expect("user_keycard_chain_verify: failed to get new signing key");
let newcrspair = SigningPair::from(newverkey, newsignkey).unwrap();
match card.user_sign("BLAKE2B-256", &newcrspair) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("user_keycard_chain_verify: user_sign returned an error: {}",
e.to_string())))
}
}
match card.verify() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("user_keycard_chain_verify: verify returned an error: {}",
e.to_string())))
}
}
Ok(())
}
#[test]
fn branch_chain_verify() -> Result<(), LKCError> {
let (orgentry, _) = orgentry_make_compliant_card()?;
match orgentry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("branch_chain_verify: is_compliant for org returned an error: {}",
e.to_string())))
}
}
let (userentry, _) = userentry_make_compliant_card()?;
match userentry.is_compliant() {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("branch_chain_verify: is_compliant for user returned an error: {}",
e.to_string())))
}
}
match userentry.verify_chain(&orgentry) {
Ok(_) => (),
Err(e) => {
return Err(LKCError::ErrProgramException(
format!("branch_chain_verify: chain verify returned an error: {}",
e.to_string())))
}
}
Ok(())
}
}