Skip to content

Instantly share code, notes, and snippets.

@leplatrem
Created November 29, 2019 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leplatrem/b0c0d57fb6e8f4c445db3b0961d68b3c to your computer and use it in GitHub Desktop.
Save leplatrem/b0c0d57fb6e8f4c445db3b0961d68b3c to your computer and use it in GitHub Desktop.
[package]
name = "contentsig"
version = "0.1.0"
authors = ["Mathieu Leplatre <mathieu@mozilla.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
base64 = "0.11.0"
futures = "0.3"
openssl = "0.10"
reqwest = "0.10.0-alpha.2"
tokio = "0.2.0-alpha.6"
signatory = { version = "0.11", features = ["ecdsa"]}
signatory-ring = "0.11"
use base64;
use reqwest;
use reqwest::Error as ReqwestError;
use openssl::x509::X509;
use signatory::{
encoding,
ecdsa::{curve::NistP384, FixedSignature},
verify_sha384, EcdsaPublicKey, Signature,
generic_array::GenericArray,
};
use signatory_ring::ecdsa::P384Verifier;
#[derive(Debug)]
pub enum SignatureError {}
impl From<ReqwestError> for SignatureError {
fn from(err: ReqwestError) -> Self {
err.into()
}
}
impl From<openssl::error::ErrorStack> for SignatureError {
fn from(err: openssl::error::ErrorStack) -> Self {
err.into()
}
}
// https://github.com/str4d/ire/blob/87a8068c3a92044dc890045b2621e851bdfe8ff7/src/crypto/mod.rs
async fn verify() -> Result<(), SignatureError> {
let x5u = "https://content-signature-2.cdn.mozilla.net/chains/pinning-preload.content-signature.mozilla.org-2019-12-24-21-43-28.chain";
let signature_b64 = "80aDcD0HGWOoFHzKv3wMnfxMqgrb24Bz9G0w-87yDWaAIuj6vyCtybIl8lhE8gqmNPqSxPGCTpGqNiuW_J6_pZ2AyMRy_WN2l7asraSh5giBwKCXn6anOF8M2PsjNSi4";
let data = r#"Content-Signature:\x00{"data":[],"last_modified":"1485794868067"}"#;
// Fetch PEM
let resp = reqwest::get(&x5u.to_string()).await?;
let pem = resp.bytes().await?;
// Parse PEM (OpenSSL)
let cert = X509::from_pem(&pem)?;
let public_key = cert.public_key().unwrap();
let der = public_key.public_key_to_der()?;
let pk: EcdsaPublicKey<NistP384> = EcdsaPublicKey::from_untagged_point(GenericArray::from_slice(&der));
// Instantiate signature
let signature_bytes = base64::decode_config(&signature_b64, base64::URL_SAFE).unwrap();
let signature = FixedSignature::<NistP384>::from_bytes(&signature_bytes).unwrap();
// Verify
let result = verify_sha384(&P384Verifier::from(&pk), &data.as_bytes(), &signature);
Ok(())
}
#[tokio::main]
async fn main() {
println!("{:?}", verify().await);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment