Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: c509 wasm binding js #628

Merged
merged 45 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
bc8d496
feat: implement cli example for c509
bkioshn Jul 17, 2024
3e7632e
fix: c509 file
bkioshn Jul 17, 2024
305149a
fix: add handle PEM file and cleanup
bkioshn Jul 17, 2024
f41f8b2
fix: lib generate and verify functionality and docs
bkioshn Jul 17, 2024
a1eafe9
fix: Cargo toml
bkioshn Jul 17, 2024
b969dcd
fix: add deserialize, serialize, other helper function
bkioshn Jul 17, 2024
bd8f8c0
test: earthly rust cli no cache
bkioshn Jul 18, 2024
c81c5b5
test: earthly rust cli no cache
bkioshn Jul 18, 2024
137e5b2
fix: add examples to earthly
bkioshn Jul 18, 2024
8609c69
fix: update crates
bkioshn Jul 18, 2024
dd7701f
fix: cargo toml and add dependencies
bkioshn Jul 18, 2024
4daea02
feat(wip): add wasm bindgen
bkioshn Jul 18, 2024
2e57bb6
feat(wip): add file for handling wasm binding
bkioshn Jul 18, 2024
6a8604b
test: wasm binding in js
bkioshn Jul 18, 2024
54ba623
Merge branch 'main' into feat/c509_cli
bkioshn Jul 19, 2024
386ec91
fix: remove bindgen
bkioshn Jul 19, 2024
8239ece
fix: add wasm bindgen function
bkioshn Jul 19, 2024
ba8197f
fix: error wording
bkioshn Jul 19, 2024
8989f15
test: add js file to test the binding
bkioshn Jul 19, 2024
2eeae92
chore: add word dictionary
bkioshn Jul 19, 2024
d9cc4e3
fix: update earthfile
bkioshn Jul 19, 2024
681f975
fix: move files
bkioshn Jul 19, 2024
7064727
fix: format and err msg
bkioshn Jul 19, 2024
b1fe4e5
Merge branch 'feat/c509_cli' into feat/c509-wasm-bind-js
bkioshn Jul 19, 2024
c51f3d2
fix: move files to examples
bkioshn Jul 19, 2024
c315303
fix: cli name
bkioshn Jul 19, 2024
b1d0d69
fix: cleanup
bkioshn Jul 20, 2024
35d3366
fix: typo
bkioshn Jul 20, 2024
4982398
Merge branch 'main' into feat/c509_cli
bkioshn Jul 20, 2024
3257d00
Merge branch 'main' into feat/c509_cli
bkioshn Jul 23, 2024
933c867
fix: rename attribute to snake case
bkioshn Jul 23, 2024
ab40bef
fix: update c509 encode decode
bkioshn Jul 23, 2024
3a88d5c
chore: format
bkioshn Jul 23, 2024
ec2ef8a
fix: issuer sig value
bkioshn Jul 23, 2024
765d04b
fix: format
bkioshn Jul 23, 2024
fe3cefd
fix: pubkey parse and cli command
bkioshn Jul 23, 2024
b04c5f7
Merge branch 'main' into feat/c509_cli
bkioshn Jul 23, 2024
2423c82
chore: grammar fix
bkioshn Jul 24, 2024
b7d76d6
Merge branch 'main' into feat/c509_cli
bkioshn Jul 24, 2024
1c59fcd
Merge branch 'feat/c509_cli' into feat/c509-wasm-bind-js
bkioshn Jul 26, 2024
82d92a0
fix: update index.js
bkioshn Jul 27, 2024
3a06e2b
Merge branch 'main' into feat/c509-wasm-bind-js
bkioshn Jul 27, 2024
5a6e282
chore: fix error message
bkioshn Jul 27, 2024
bf38831
fix: format
bkioshn Jul 27, 2024
bfb30bd
Merge branch 'main' into feat/c509-wasm-bind-js
bkioshn Jul 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .config/dictionaries/project.dic
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ reqwest
rfwtxt
rgloader
ripgrep
rlib
RPATH
rustc
rustdoc
Expand Down
5 changes: 5 additions & 0 deletions catalyst-gateway-crates/c509-certificate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ repository = "https://github.com/input-output-hk/catalyst-voices"
license = "MIT OR Apache-2.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[lints.rust]
warnings = "deny"
missing_docs = "deny"
Expand Down Expand Up @@ -60,6 +63,8 @@ regex = "1.10.5"
ed25519-dalek = { version = "2.1.1", features = ["pem"] }
thiserror = "1.0.56"
serde = { version = "1.0.204", features = ["derive"] }
wasm-bindgen = "0.2.92"
serde-wasm-bindgen = "0.6.5"

[package.metadata.cargo-machete]
ignored = ["strum"]
Expand Down
20 changes: 8 additions & 12 deletions catalyst-gateway-crates/c509-certificate/Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,24 @@ builder:

COPY --dir .cargo .config Cargo.* clippy.toml deny.toml rustfmt.toml src examples .


# check : Run basic check.
check:
FROM +builder

DO rust-ci+EXECUTE --cmd="/scripts/std_checks.py"

# build : Build the C509 library
build:
FROM +builder

DO rust-ci+EXECUTE \
--cmd="/scripts/std_build.py" \
--args1="--libs=c509-certificate"

# RUN wasm-pack build --target web

package:
RUN cargo install wasm-pack --version=0.12.1 --locked

# js-wasm-package-locally : Generate the wasm package and save it locally
js-wasm-package-locally:
FROM +build

# AS LOCAL is for local testing only, will be removed in the future
SAVE ARTIFACT ./pkg c509-certificate-binding

# # local-build: Build the service and save it locally
# local-build:
# FROM +build
# SAVE ARTIFACT c509-certificate-binding AS LOCAL ./pkg
RUN wasm-pack build --target web
SAVE ARTIFACT ./pkg AS LOCAL ./pkg
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!-- This file is for testing -->
<!doctype html>
<html lang="en-US">

<head>
<meta charset="utf-8" />
<title>C509 certificate!</title>
</head>

<body>
<script type="module" src="index.js"></script>
</body>

</html>
69 changes: 69 additions & 0 deletions catalyst-gateway-crates/c509-certificate/examples/web/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Testing the wasm binding JS functions.

import init, {
generate,
verify,
decode,
PublicKey,
PrivateKey,
} from "../../pkg/c509_certificate.js";

const pem_sk = `
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIP1iI3LF7h89yY6QZmhDp4Y5FmTQ4oasbz2lEiaqqTzV
-----END PRIVATE KEY-----
`;

const pem_pk = `
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAtFuCleJwHS28jUCT+ulLl5c1+MXhehhDz2SimOhmWaI=
-----END PUBLIC KEY-----
`;

const tbs = {
c509_certificate_type: 0,
certificate_serial_number: 1000000n,
issuer: {
relative_distinguished_name: [
{
oid: "2.5.4.3",
value: [{ text: "RFC test CA" }],
},
],
},
validity_not_before: 1_672_531_200n,
validity_not_after: 1_767_225_600n,
subject: { text: "01-23-45-ff-fe-67-89-AB" },
subject_public_key_algorithm: {
oid: "1.3.101.112",
},
subject_public_key: [],
extensions: [
{
oid: "2.5.29.19",
value: { int: -2n },
critical: false,
},
],
issuer_signature_algorithm: {
oid: "1.3.101.112",
},
};

async function run() {
await init();
dtscalac marked this conversation as resolved.
Show resolved Hide resolved

let sk = PrivateKey.str_to_sk(pem_sk);
let pk = PublicKey.str_to_pk(pem_pk);

// Call the generate with private key to create a signed version
let c509 = generate(tbs, sk);
console.log(c509);
// Verify the generated C509 with the public key
console.log(verify(c509, pk));
// Decode the generated C509 back to readable format
let decoded_c509 = decode(c509);
console.log(decoded_c509.tbs_cert);
}

run();
1 change: 1 addition & 0 deletions catalyst-gateway-crates/c509-certificate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub mod c509_time;
pub mod signing;
mod tables;
pub mod tbs_cert;
pub mod wasm_binding;

/// Generate a signed or unsigned C509 certificate.
///
Expand Down
3 changes: 3 additions & 0 deletions catalyst-gateway-crates/c509-certificate/src/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use ed25519_dalek::{
pkcs8::{DecodePrivateKey, DecodePublicKey},
SigningKey, VerifyingKey,
};
use wasm_bindgen::prelude::wasm_bindgen;

/// Public or private key decoding from string error.
#[derive(thiserror::Error, Debug)]
Expand All @@ -18,6 +19,7 @@ struct KeyPemDecodingError;
/// Ed25519 private key instance.
/// Wrapper over `ed25519_dalek::SigningKey`.
#[allow(dead_code)]
#[wasm_bindgen]
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PrivateKey(SigningKey);

Expand Down Expand Up @@ -95,6 +97,7 @@ impl FromStr for PrivateKey {
/// Ed25519 public key instance.
/// Wrapper over `ed25519_dalek::VerifyingKey`.
#[derive(Clone, Debug, PartialEq, Eq)]
#[wasm_bindgen]
pub struct PublicKey(VerifyingKey);

#[allow(dead_code)]
Expand Down
76 changes: 76 additions & 0 deletions catalyst-gateway-crates/c509-certificate/src/wasm_binding.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,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."))
}
}
Loading