aboutsummaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)Author
2018-11-08Add 'paddle' crateTeddy Wing
Should verify a Paddle webhook. This ensures that the request really does come from Paddle. In order to verify the request, we need to sign the serialized POST parameters. And, weirdly, Paddle requires you to serialize parameters in PHP's serialization format. Using this Gist by 'drewmccormack' as a reference for the format: https://gist.github.com/drewmccormack/a51b18ffeda8f596a11a8623481344d8
2018-11-07aquatic-prime: Remove unused importsTeddy Wing
2018-11-07aquatic-prime: Use capitalised field names in testTeddy Wing
I prefer the capitalised key names, since this is a plist. Had gone with lowercase before because it was the default.
2018-11-07AquaticPrime::plist(): Fix signatureTeddy Wing
When I updated the plist function tests, I discovered that the `data` field for "Signature" was incorrect. Turns out that the 'plist' crate takes it upon itself to base64 encode the input Vec it gets: https://github.com/ebarnard/rust-plist/blob/v0.3.0/src/xml/writer.rs#L171-L174 This meant I was double-base64 encoding the signature. To fix this, I removed base64 encoding from the `sign()` method, and return the `[u8]` array directly. I thought this would be the end of it, but I ran into another problem where my tests failed. It turns out that the 'plist' crate base64 encodes using the `base64::MIME` config, which wraps the base64-encoded string to 76 characters and uses CRLF line endings. But my XML string uses plain LF line endings, so I ended up with useless CRs in the `<data>` tag. To solve this, I ended up having to fork the 'plist' crate and change it to use the `base64::STANDARD` config, which doesn't line wrap the base64 string. For now the fork is a local copy. I'll publish it when I'm ready to publish the rest.
2018-11-07aquatic_prime::tests: Move `AquaticPrime` initialisation to a functionTeddy Wing
Extract this, which is the same in all the tests, to a function. Also line wrap the public key strings.
2018-11-07AquaticPrime::plist(): Remove `unwrap`sTeddy Wing
Return an `Err` instead of unwrapping `Result`s. * Add `std::string::FromUtf8Error` to `foreign_links` to support `String::from_utf8` error result * Add `InvalidLicenseData` when unwrapping the dictionary from `plist_data`. The `as_dictionary()` method returns an `Option`, and if we get `None` from that, our `plist()` function should consider that an error because without this input data, it can't proceed.
2018-11-07AquaticPrime: Clean up `plist()`Teddy Wing
Clean up the code from 70dcef3a47c11f921d8d742b2e1667e178a90b8f. * Remove commented code * Remove debug print statements * Rename variables to make more sense * Return the plist XML from the function * Change `sign()` to take a `HashMap<String, String>` instead of `HashMap<&str, &str>` so we don't have to convert the deserialized `HashMap<String, String>` in `plist()`
2018-11-07AquaticPrime: Add `plist` methodTeddy Wing
Working version of a function that generates a license plist XML string from input data. Made a complete and utter mess of the code, and the two tests in this commit aren't really tests, they're just a way of executing the function. The function takes a serializable data type, sends the data to the `sign` function, and produces an XML plist string of the input data plus a field for the signature. In order to accomplish this, I ended up with a kind of roundabout data manipulation. 1. We start with the user data type. 2. That then gets serialised to an XML plist using the 'plist' crate's 'serde' serializer. 3. The serialized XML is then deserialized to a `Plist` instance. 4. The dict is extracted from the `Plist` and fed to `sign()` get a signature from the data. 5. We add the signature to the dict as a `Plist::Data`, in accordance with the Aquatic Prime license file format. 6. The full dict including the signature entry is serialized to XML and returned from the function. I ended up with this circuitous manipulation because I wanted to be able to accept an arbitrary struct as input data, and serializing it seemed to be the easiest way to get a plist dict from it. But we can't just use that serialized result, because it doesn't contain the signature. Getting a `Plist` from the data seemed to be the right way to go, as the signature entry needs to be a plist `data` type, so we can't just insert it into a `<String, String>` `HashMap`. Now that it works, I'll be cleaning all of this up in further commits.
2018-11-06AquaticPrime::sign(): Return an error if public key != 1024 bitsTeddy Wing
This check was reproduced from Aquatic Prime's C signature generator: https://github.com/bdrister/AquaticPrime/blob/master/Source/PHP/AquaticPrimeCLI.c#L46-L49 In the case of this library, we should return an error to take advantage of being able to return a `Result`.
2018-11-06AquaticPrime::sign(): Remove `unwrap`s from key "0x" removalTeddy Wing
Gets rid of `unwrap`s and allows us to explicitly remove only "0x". Still on Rust 1.28 for now. Will need to change this to `trim_start_matches` for Rust v1.30.
2018-11-06AquaticPrime::sign(): Return `Result`Teddy Wing
Remove most `unwrap`s in the function and replace them with tries.
2018-11-06aquatic-prime: Add 'error-chain' crateTeddy Wing
2018-11-06aquatic-prime: Remove unused codeTeddy Wing
2018-11-06aquatic-prime: Sort input keys alphabetically case insensitiveTeddy Wing
Keys in the input hash must be sorted alphabetically without considering case in order to produce the correct signature. Learned this from the Ruby library: total = information.sort{|a,b| a[0].downcase <=> b[0].downcase || a[0] <=> b[0]}.map{|key,value| value}.join('')
2018-11-06aquatic-prime: Base64 encode the signatureTeddy Wing
2018-11-06aquatic-prime: Remove spaces in test signaturesTeddy Wing
The spaces at the ends of the lines are included in the string, but they shouldn't be.
2018-11-06aquatic-prime: Strip `0x` from public & private keysTeddy Wing
Learned from: https://github.com/bdrister/AquaticPrime/blob/57c6f70/Source/Cocoa/AquaticPrime.m#L111-L114 that the "0x" prefix on the hex keys needs to be removed before using the RSA library functions on it. Otherwise it doesn't work. Couldn't figure that out from the other implementations because they use custom conversion functions instead of OpenSSL's functions. Previously, calling `BigNum::from_hex_str()` on the strings would yield `0`, but now we get proper BigNums.
2018-11-05aquatic-prime: Try to encrypt input data stringTeddy Wing
Take the data string we created and feed it through RSA encryption. Basically following the steps used by the Aquatic Prime CLI program written in C: https://github.com/bdrister/AquaticPrime/blob/4f86666/Source/PHP/AquaticPrimeCLI.c At first I tried using a `Signer`, but it looks like I'm supposed to be encrypting the data instead. Unfortunately, I'm now getting this error when calling `private_encrypt()`: 'failed to encrypt: ErrorStack([Error { code: 67526721, library: "rsa routines", function: "RSA_EAY_PRIVATE_ENCRYPT", reason: "malloc failure", file: "rsa_eay.c", line: 368 }])', libcore/result.rs:945:5 Not sure what the problem is yet.
2018-11-05AquaticPrime::sign(): Collect input data values into a stringTeddy Wing
Collect values from the `HashMap` into a single string. Following the example of the Aquatic Prime PHP and Ruby scripts. Thanks to these Stack Overflow answers for explaining `into_iter()`: https://stackoverflow.com/questions/32354947/type-issue-with-iterator-collect/32355408#32355408 https://stackoverflow.com/questions/32354947/type-issue-with-iterator-collect/32355169#32355169 Otherwise I was getting double string references (`(&&str, &&str)`) from `iter()`. In order to get the `&str` and `iter` references right, take an owned `HashMap` argument instead of a reference as planned earlier. Makes it simpler to manipulate the `&str`s inside.
2018-11-05aquatic-prime: Add an rough interface and a test for `sign()`Teddy Wing
The `sign()` method will take a `HashMap` and return a signed digest of the map. Replicated the test from the Ruby edition of Aquatic Prime: https://github.com/bdrister/AquaticPrime/blob/ce892dc/Source/Ruby/lib/aquaticprime.rb Copied the expected values in after running the script.
2018-11-05Add 'aquatic-prime' sub-crateTeddy Wing
We'll use this new library crate to generate licenses in the Aquatic Prime format. Planning on just porting the C code directly to Rust.
2018-11-04Make a simple FastCGI echo serverTeddy Wing
Building on the example from the 'fastcgi' crate: https://docs.rs/fastcgi/1.0.0/fastcgi/index.html prints all request parameters and the request `Stdin`. Post parameters are included in the stdin buffer.
2018-11-03Cargo.toml: Add 'fastcgi' crateTeddy Wing
2018-11-03Add 'license-generator' Rust projectTeddy Wing
Generated with: $ cargo new --bin license-generator using $ rustc --version rustc 1.28.0 (9634041f0 2018-07-30) This will be a FastCGI program to respond to a webhook from Paddle, and respond with a generated license key file.