diff options
Diffstat (limited to 'license-generator/aquatic-prime')
| -rw-r--r-- | license-generator/aquatic-prime/Cargo.toml | 3 | ||||
| -rw-r--r-- | license-generator/aquatic-prime/src/lib.rs | 148 | 
2 files changed, 150 insertions, 1 deletions
diff --git a/license-generator/aquatic-prime/Cargo.toml b/license-generator/aquatic-prime/Cargo.toml index 3106d76..2247930 100644 --- a/license-generator/aquatic-prime/Cargo.toml +++ b/license-generator/aquatic-prime/Cargo.toml @@ -6,3 +6,6 @@ version = "0.0.1"  base64 = "0.10.0"  error-chain = "0.12.0"  openssl = "0.10.15" +plist = "0.3.0" +serde = "1.0.80" +serde_derive = "1.0.80" diff --git a/license-generator/aquatic-prime/src/lib.rs b/license-generator/aquatic-prime/src/lib.rs index c7f43a4..7aea16f 100644 --- a/license-generator/aquatic-prime/src/lib.rs +++ b/license-generator/aquatic-prime/src/lib.rs @@ -3,6 +3,11 @@ extern crate base64;  #[macro_use]  extern crate error_chain;  extern crate openssl; +extern crate plist; +extern crate serde; + +#[macro_use] +extern crate serde_derive;  mod errors {      error_chain! { @@ -15,12 +20,15 @@ mod errors {      }  } -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; +use std::io::Cursor;  use openssl::bn::BigNum;  use openssl::rsa::Padding;  use openssl::rsa::RsaPrivateKeyBuilder;  use openssl::sha::sha1; +use plist::Plist; +use serde::ser::Serialize;  use errors::*; @@ -78,6 +86,81 @@ impl<'a> AquaticPrime<'a> {          Ok(base64::encode(&signature[..]))      } + +    // TODO: Should take a plistable object as input +    // Serialize input_data to a Plist (input_data doesn't include signature field?) +    // Get the BTreeMap out and send it to sign() +    // Insert signature into Plist BTreeMap +    // Output plist string +    // +    // fn plist(&self, input_data: HashMap<&str, &str>) -> Result<String> { +    fn plist<T: Serialize>(&self, input_data: T) -> Result<String> { +        // let signature = self.sign(input_data.clone()); +        // let mut data: BTreeMap<&str, &str> = input_data +        //     .into_iter() +        //     .collect(); +        // +        // data.insert(); +        // let mut tmp = String::with_capacity(600); +        let mut tmp = Vec::with_capacity(600); + +        plist::serde::serialize_to_xml(&mut tmp, &input_data).unwrap(); +        // let xml = String::from_utf8(tmp).unwrap(); + +        // println!("Serialized: {}", xml); + +        // let le_plist: Plist = plist::serde::deserialize(Cursor::new(&tmp[..])).unwrap(); +        let tmp2 = tmp.clone(); +        let plist_data = Plist::read(Cursor::new(&tmp)).unwrap(); +        println!("{:?}", plist_data); + +        let mut plist_dict = plist_data.as_dictionary().unwrap().to_owned(); + +        // let hash_data: BTreeMap<String, String> = data +        //     .into_iter() +        //     .map(|(k, v)| (k, String::from(v))) +        //     .collect(); + +        // let hash_data: BTreeMap<&str, &str> = data.into_iter().collect(); +        // self.sign(data); +        // data.insert(); + +        // let data_a = BTreeMap::new(); +        // for (k, v) in data.iter() { +        //     data_a.insert(k, String::from(v)); +        // } + +        let data: HashMap<String, String> = plist::serde::deserialize(Cursor::new(&tmp2)).unwrap(); +        println!("{:?}", data); +        let mut data_a = HashMap::new(); +        for (k, v) in data.iter() { +            data_a.insert(k.as_ref(), v.as_ref()); +        } + +        let signature = self.sign(data_a).unwrap(); +        println!("Signature: {}", signature); + +        // Re-serialise to Plist +        // Add signature as Data type + +        plist_dict.insert("Signature".to_owned(), Plist::Data(signature.into_bytes())); + +        let mut tmp_return = Cursor::new(Vec::with_capacity(600)); +        // plist::serde::serialize_to_xml(&mut tmp_return, &plist_data).unwrap(); +        // println!("Output: {}", tmp_return); + +        { +        let mut writer = plist::xml::EventWriter::new(&mut tmp_return); +        // let plist_plist = Plist::Dictionary(plist_data); +        for item in Plist::Dictionary(plist_dict).into_events() { +            writer.write(&item).unwrap(); +        } +        } + +        println!("Output: {}", String::from_utf8(tmp_return.into_inner()).unwrap()); + +        Ok(String::new()) +    }  } @@ -121,4 +204,67 @@ mod tests {          assert_eq!(signature.unwrap(), expected);      } + +    #[test] +    fn plist_produces_a_license_plist_string() { +        let public_key = "0xAAD0DC5705017D4AA1CD3FA194771E97B263E68308DC09D3D9297247D175CCD05DFE410B9426D3C8019BA6B92D34F21B454D8D8AC8CAD2FB37850987C02592012D658911442C27F4D9B050CFA3F7C07FF81CFEEBE33E1E43595B2ACCC2019DC7247829017A91D40020F9D8BF67300CE744263B4F34FF42E3A7BE3CF37C4004EB"; +        let private_key = "0x71E092E4AE00FE31C1337FC10DA4BF0FCC4299ACB092B137E61BA185364E888AE9542B5D0D6F37DAABBD19D0C8CDF6BCD8DE5E5C85DC8CA77A58B1052AC3B6AA5C7EA2E58BD484050184D2E241CFCB1D6AB4AC8617499056060833D8F6699B9C54E3BAA36123AFD5B4DDE6F2ADFC08F6970C3BA5C80B9A0A04CB6C6B73DD512B"; + +        let aquatic_prime = AquaticPrime { +            public_key: public_key, +            private_key: private_key, +        }; + +        let mut license_data = HashMap::new(); +        license_data.insert("Email", "user@email.com"); +        license_data.insert("Name", "Üsér Diacriticà"); +        license_data.insert("lowercase key", "Keys should be sorted case-insensitive"); + +        aquatic_prime.plist(license_data); + +r#"<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> +	<key>Email</key> +	<string>user@email.com</string> +	<key>Name</key> +	<string>Üsér Diacriticà</string> +	<key>Signature</key> +	<data> +	RIhF/3CgyXzPg2wCQ5LShf6W9khtqPcqUDLAHcAZdOIcoeR7PoOHi15423kxq5jOh1lm +	cztBoUJFu8mB45MHE0jmmbRw3qK6FJz9Py2gi1XvGOgH3GW713OCvQBE7vfBj4ZriP0+ +	FS18nLfrtM6Xp0mAd1la4DD4oh7d35dlYTY= +	</data> +	<key>lowercase key</key> +	<string>Keys should be sorted case-insensitive</string> +</dict> +</plist>"#; +    } + +    #[test] +    fn plist_takes_a_generic_struct() { +        let public_key = "0xAAD0DC5705017D4AA1CD3FA194771E97B263E68308DC09D3D9297247D175CCD05DFE410B9426D3C8019BA6B92D34F21B454D8D8AC8CAD2FB37850987C02592012D658911442C27F4D9B050CFA3F7C07FF81CFEEBE33E1E43595B2ACCC2019DC7247829017A91D40020F9D8BF67300CE744263B4F34FF42E3A7BE3CF37C4004EB"; +        let private_key = "0x71E092E4AE00FE31C1337FC10DA4BF0FCC4299ACB092B137E61BA185364E888AE9542B5D0D6F37DAABBD19D0C8CDF6BCD8DE5E5C85DC8CA77A58B1052AC3B6AA5C7EA2E58BD484050184D2E241CFCB1D6AB4AC8617499056060833D8F6699B9C54E3BAA36123AFD5B4DDE6F2ADFC08F6970C3BA5C80B9A0A04CB6C6B73DD512B"; + +        let aquatic_prime = AquaticPrime { +            public_key: public_key, +            private_key: private_key, +        }; + +        #[derive(Serialize)] +        struct LicenseData<'a> { +            name: &'a str, +            email: &'a str, +            // signature: Vec<u8>, +        }; + +        let license_data = LicenseData { +            name: "User", +            email: "user@example.com", +            // signature: vec![], +        }; + +        aquatic_prime.plist(license_data); +    }  }  | 
