use crate::card::Card;
use crate::client::{run_task, API_BASE};
use anyhow::{Context, Result};
use reqwest::blocking::multipart::{Form, Part};
use reqwest::blocking::Client;
pub fn request(client: &Client, token: &str, card: &Card, sha256: &[u8; 32]) -> Result<Vec<u8>> {
let digest_hex = hex::encode(sha256);
let req_json = format!(r#"{{"digests":["{digest_hex}"],"digesttype":"SHA256"}}"#);
let form = Form::new()
.part(
"req",
Part::text(req_json)
.mime_str("application/json")
.context("req part mime")?,
)
.part(
"certificate",
Part::bytes(card.certificate_pem.clone())
.file_name("blob")
.mime_str("application/octet-stream")
.context("certificate part mime")?,
);
let resp = run_task(
client,
token,
client
.post(format!(
"{API_BASE}/card/v1/cards/{}/certificates/signature",
card.serial
))
.bearer_auth(token)
.multipart(form),
)
.context("signature task")?
.1;
let arr: serde_json::Value =
serde_json::from_slice(&resp).context("signature result was not JSON")?;
let sig_hex = arr
.as_array()
.and_then(|a| a.first())
.and_then(|o| o.as_object())
.and_then(|m| m.values().next())
.and_then(|v| v.as_str())
.with_context(|| {
let snip: String = String::from_utf8_lossy(&resp).chars().take(300).collect();
format!("no signature in the result; got: {snip}")
})?;
hex::decode(sig_hex).context("signature was not valid hex")
}