]> git.proxmox.com Git - proxmox.git/blame - src/eab.rs
expand helper function by eab credentials
[proxmox.git] / src / eab.rs
CommitLineData
88f7e190
FG
1use openssl::hash::MessageDigest;
2use openssl::pkey::{HasPrivate, PKeyRef};
3use openssl::sign::Signer;
4use serde::{Deserialize, Serialize};
5
6use crate::key::Jwk;
7use crate::{b64u, Error};
8
9#[derive(Debug, Serialize)]
10#[serde(rename_all = "camelCase")]
11struct Protected {
12 alg: &'static str,
13 url: String,
14 kid: String,
15}
16
17#[derive(Debug, Serialize, Deserialize, Clone)]
18#[serde(rename_all = "camelCase")]
19pub struct ExternalAccountBinding {
20 protected: String,
21 payload: String,
22 signature: String,
23}
24
25impl ExternalAccountBinding {
26 pub fn new<P>(
27 eab_kid: &str,
28 eab_hmac_key: &PKeyRef<P>,
29 jwk: Jwk,
30 url: String,
31 ) -> Result<Self, Error>
32 where
33 P: HasPrivate,
34 {
35 let protected = Protected {
36 alg: "HS256",
37 kid: eab_kid.to_string(),
38 url,
39 };
40 let payload = b64u::encode(serde_json::to_string(&jwk)?.as_bytes());
41 let protected_data = b64u::encode(serde_json::to_string(&protected)?.as_bytes());
42 let signature = {
43 let protected = protected_data.as_bytes();
44 let payload = payload.as_bytes();
45 Self::sign_hmac(eab_hmac_key, protected, payload)?
46 };
47
48 let signature = b64u::encode(&signature);
49 Ok(ExternalAccountBinding {
50 protected: protected_data,
51 payload,
52 signature,
53 })
54 }
55
56 fn sign_hmac<P>(key: &PKeyRef<P>, protected: &[u8], payload: &[u8]) -> Result<Vec<u8>, Error>
57 where
58 P: HasPrivate,
59 {
60 let mut signer = Signer::new(MessageDigest::sha256(), key)?;
61 signer.update(protected)?;
62 signer.update(b".")?;
63 signer.update(payload)?;
64 Ok(signer.sign_to_vec()?)
65 }
66}