use std::convert::{TryFrom, TryInto};
use derive_builder::Builder;
use crate::{
error::Error,
tls::{Certificate, Identity},
};
#[derive(Debug, Clone)]
pub enum Pkcs12 {
File { path: String, password: String },
Der { der: Vec<u8>, password: String },
}
impl TryFrom<Pkcs12> for reqwest::Identity {
type Error = Error;
fn try_from(pkcs12: Pkcs12) -> Result<Self, Self::Error> {
match pkcs12 {
Pkcs12::File { path, password } => Ok(Identity::from_pkcs12_file(path.as_str(), password.as_str())?),
Pkcs12::Der { der, password } => Ok(Identity::from_vec(der, password.as_str())?),
}
}
}
#[derive(Builder, Debug, Clone)]
pub struct Config {
pub pkcs12: Pkcs12,
#[builder(default = "String::from(API_URL_PROD)")]
pub url: String,
#[builder(default = "String::from(CA_PROD)")]
pub ca: String,
}
impl TryFrom<Config> for reqwest::ClientBuilder {
type Error = Error;
fn try_from(config: Config) -> Result<Self, Self::Error> {
let certificates = Certificate::from_string(config.ca.as_str())?;
let mut builder = Self::new();
builder = builder.identity(config.pkcs12.try_into()?);
for cert in certificates {
builder = builder.add_root_certificate(cert);
}
Ok(builder)
}
}
impl TryFrom<Config> for reqwest::blocking::ClientBuilder {
type Error = Error;
fn try_from(config: Config) -> Result<Self, Self::Error> {
let certificates = Certificate::from_string(config.ca.as_str())?;
let mut builder = Self::new();
builder = builder.identity(config.pkcs12.try_into()?);
for cert in certificates {
builder = builder.add_root_certificate(cert);
}
Ok(builder)
}
}
#[allow(dead_code)]
pub const API_URL_TEST: &str = "https://appapi2.test.bankid.com/rp/v6.0";
#[allow(dead_code)]
pub const API_URL_PROD: &str = "https://appapi2.bankid.com/rp/v6.0";
#[allow(dead_code)]
pub const CA_TEST: &str = include_str!("../../resources/test.ca");
#[allow(dead_code)]
pub const CA_PROD: &str = include_str!("../../resources/production.ca");