sbb-api 0.1.0

A library to interact with sbb.ch's unofficial API
Documentation
use openssl::x509::X509;
use openssl::hash::{MessageDigest, DigestBytes, Hasher};
use openssl::sign::Signer;
use openssl::pkey::PKey;
static KEY : &str = "c3eAd3eC3a7845dE98f73942b3d5f9c0";


pub fn get_authorization<'a>(path: &str, date: &str) -> String {
    let hmac_key = get_key();
    let key = PKey::hmac(hmac_key.as_bytes()).unwrap();
    let mut signer = Signer::new(MessageDigest::sha1(), &key).unwrap();

    let digest = format!("{}{}", path, date);
    let _ = signer.update(digest.as_bytes());

    base64::encode(&signer.sign_to_vec().expect("Unable to sign"))
}

pub fn get_certificate_hash() -> String {
    let cert = X509::from_der(
        include_bytes!("../resources/ca_cert.crt")
    ).expect("Invalid CA certificate");

    let r : DigestBytes = cert.digest(MessageDigest::sha1()).expect("Digest");
    base64::encode(&r)
}

pub fn retrieve_key(cert_hash: &str, key: &str) -> String {
    let mut hasher : Hasher = Hasher::new(MessageDigest::sha256()).expect("Unable to initialize hasher");

    let cleartext = format!("{}{}", cert_hash, key);
    hasher.update(cleartext.as_bytes()).expect("Failed to update hasher");
    let bytes = hasher.finish().expect("Unable to hash!");
    hex::encode(bytes)
}

pub fn get_key() -> String {
    retrieve_key(&get_certificate_hash(), KEY)
}

#[cfg(test)]
mod test {
    use crate::authenticator::{get_authorization, get_certificate_hash};

    #[test]
    fn url_1(){
        let date = "2020-06-28";
        let auth = "hL89gUidDebOUNUCP/+5vbj+0Iw=";
        let path = "/unauth/fahrplanservice/v1/verbindungen/s/Z%25C3%25BCrich%2520HB/s/Bern/ab/2019-09-20/21-14/";

        assert_eq!(get_authorization(path, date), auth);
    }

    #[test]
    fn test_certificate_hash(){
        assert_eq!("WdfnzdQugRFUF5b812hZl3lAahM=", get_certificate_hash());
    }

}