1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! WASM binding wrapper for the C509 certificate crate.

use std::str::FromStr;

use minicbor::Decode;
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};

use crate::{
    signing::{PrivateKey, PublicKey},
    tbs_cert::TbsCert,
};

/// Wrapper for generate function.
///
/// # Errors
/// Returns an error if the provided TbsCert JSValue cannot be converted `TbsCert` or C509
/// cannot be generated.
#[wasm_bindgen]
// wasm_bindgen does not allowed ref passing unless it implement `RefFromWasmAbi`.
#[allow(clippy::needless_pass_by_value)]
pub fn generate(tbs_cert: JsValue, private_key: Option<PrivateKey>) -> Result<JsValue, JsValue> {
    let tbs_cert: TbsCert = serde_wasm_bindgen::from_value(tbs_cert)?;
    let c509 = crate::generate(&tbs_cert, private_key.as_ref())
        .map_err(|e| JsValue::from(e.to_string()))?;
    Ok(serde_wasm_bindgen::to_value(&c509)?)
}

/// Wrapper for verify function.
///
/// # Errors
/// Returns an error if the signature is invalid or the signature cannot be verified.
#[wasm_bindgen]
pub fn verify(c509: &[u8], public_key: &PublicKey) -> Result<JsValue, JsValue> {
    match crate::verify(c509, public_key) {
        Ok(()) => Ok(JsValue::from("Signature verified")),
        Err(e) => Err(JsValue::from(e.to_string())),
    }
}

/// Wrapper for decoding vector of C509 back to readable object.
///
/// # Errors
/// Returns an error if the provided vector is not a valid C509 certificate.
#[wasm_bindgen]
pub fn decode(c509: &[u8]) -> Result<JsValue, JsValue> {
    let mut d = minicbor::Decoder::new(c509);
    let c509 = crate::C509::decode(&mut d, &mut ()).map_err(|e| JsValue::from(e.to_string()))?;
    Ok(serde_wasm_bindgen::to_value(&c509)?)
}

#[wasm_bindgen]
impl PrivateKey {
    /// Convert string to private key.
    ///
    /// # Errors
    /// Returns an error if the provided string is not a valid private key.
    #[wasm_bindgen]
    pub fn str_to_sk(str: &str) -> Result<PrivateKey, JsValue> {
        FromStr::from_str(str).map_err(|_| {
            JsValue::from("Cannot decode private key from string. Invalid PEM format.")
        })
    }
}

#[wasm_bindgen]
impl PublicKey {
    /// Convert string to public key.
    ///
    /// # Errors
    /// Returns an error if the provided string is not a valid public key.
    #[wasm_bindgen]
    pub fn str_to_pk(str: &str) -> Result<PublicKey, JsValue> {
        FromStr::from_str(str)
            .map_err(|_| JsValue::from("Cannot decode public key from string. Invalid PEM format."))
    }
}