Skip to content

Commit

Permalink
Support compiling to wasm32 architectures
Browse files Browse the repository at this point in the history
Enable support for compiling sigstore-rs to WASM, making it usable from
browser applications and on wasm32 VMs.

Signed-off-by: Ulf Lilleengen <lulf@redhat.com>
  • Loading branch information
Ulf Lilleengen committed Mar 2, 2023
1 parent 96e039c commit d9b198a
Show file tree
Hide file tree
Showing 13 changed files with 52 additions and 15 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ jobs:
with:
command: check

check-wasm:
name: Check WASM
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
- uses: actions-rs/toolchain@16499b5e05bf2e26879000db0c1d13f7e13fa3af # v1.0.7
with:
profile: minimal
toolchain: stable
target: wasm32-unknown-unknown
override: true
- uses: actions-rs/cargo@844f36862e911db73fe0815f00a4a2602c279505 # v1.0.3
with:
command: check
args: --no-default-features --features wasm

test:
name: Test Suite
runs-on: ubuntu-latest
Expand Down
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ readme = "README.md"

[features]
default = ["full-native-tls", "cached-client", "tuf"]
wasm = ["getrandom/js"]

full-native-tls = ["fulcio-native-tls", "rekor-native-tls", "cosign-native-tls", "mock-client-native-tls"]
full-rustls-tls = ["fulcio-rustls-tls", "rekor-rustls-tls", "cosign-rustls-tls", "mock-client-rustls-tls"]
Expand All @@ -28,7 +29,7 @@ oauth = []

rekor-native-tls = [ "reqwest/native-tls", "rekor"]
rekor-rustls-tls = [ "reqwest/rustls-tls", "rekor" ]
rekor = []
rekor = ["reqwest"]

tuf = [ "tough", "regex" ]

Expand All @@ -55,23 +56,24 @@ cfg-if = "1.0.0"
chrono = { version = "0.4.23", feature = "clock" }
const-oid = "0.9.1"
der = "0.6.1"
digest = "0.10.3"
digest = { version = "0.10.3", default-features = false }
ecdsa = { version = "0.15", features = [ "pkcs8", "digest", "der" ] }
ed25519 = { version = "=2.1", features = [ "alloc" ] }
ed25519-dalek = { version = "2.0.0-pre.0", features = [ "pkcs8", "rand_core" ] }
elliptic-curve = { version = "0.12.2", features = [ "arithmetic", "pem" ] }
lazy_static = "1.4.0"
oci-distribution = { version = "0.9", default-features = false, optional = true }
olpc-cjson = "0.1"
open = "3.0.1"
openidconnect = { version = "2.3", default-features = false, features = [ "reqwest" ], optional = true}
p256 = "0.12"
p384 = "0.12"
webbrowser = "0.8.4"
pem = "1.0.2"
picky = { version = "7.0.0-rc.3", default-features = false, features = [ "x509", "ec" ] }
pkcs1 = "0.4.0"
pkcs8 = { version = "0.9.0", features = ["pem", "alloc", "pkcs5", "encryption"] }
rand = { version = "0.8.5", features = [ "getrandom", "std" ] }
getrandom = "0.2.8"
regex = { version = "1.5.5", optional = true }
reqwest = { version = "0.11", default-features = false, features = ["json", "multipart"], optional = true}
rsa = "0.8.0"
Expand All @@ -81,7 +83,7 @@ serde_json = "1.0.79"
sha2 = { version = "0.10.6", features = ["oid"] }
signature = { version = "2.0" }
thiserror = "1.0.30"
tokio = { version = "1.17.0", features = ["full"] }
tokio = { version = "1.17.0", features = ["rt"] }
tough = { version = "0.12", features = [ "http" ], optional = true }
tracing = "0.1.31"
url = "2.2.2"
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ For example, `openidconnect` can be run with the following command:
cargo run --example openidconnect
```

## WebAssembly/WASM support

To embedded this crate in WASM modules, build it using the `wasm` cargo feature:

```bash
cargo build --no-default-features --features wasm --target wasm32-unknown-unknown
```

NOTE: The wasm32-wasi target architecture is not yet supported.

## Contributing

Contributions are welcome! Please see the [contributing guidelines](CONTRIBUTING.md).
Expand Down
2 changes: 1 addition & 1 deletion examples/openidflow/openidconnect/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn main() -> Result<(), anyhow::Error> {

match oidc_url.as_ref() {
Ok(url) => {
open::that(url.0.to_string())?;
webbrowser::open(url.0.as_ref())?;
println!(
"Open this URL in a browser if it does not automatically open for you:\n{}\n",
url.0
Expand Down
2 changes: 1 addition & 1 deletion src/cosign/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub struct Client {
pub(crate) fulcio_cert_pool: Option<CertificatePool>,
}

#[async_trait]
#[async_trait(?Send)]
impl CosignCapabilities for Client {
async fn triangulate(&mut self, image: &str, auth: &Auth) -> Result<(String, String)> {
let image_reference: oci_distribution::Reference =
Expand Down
2 changes: 1 addition & 1 deletion src/cosign/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub mod payload;
pub use payload::simple_signing;

pub mod constraint;
#[async_trait]
#[async_trait(?Send)]
/// Cosign Abilities that have to be implemented by a
/// Cosign client
pub trait CosignCapabilities {
Expand Down
6 changes: 5 additions & 1 deletion src/crypto/verification_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ use super::{
Signature, SigningScheme,
};

use crate::{cosign::constants::ED25519, errors::*};
use crate::errors::*;

#[cfg(feature = "cosign")]
use crate::cosign::constants::ED25519;

/// A key that can be used to verify signatures.
///
Expand Down Expand Up @@ -101,6 +104,7 @@ impl<'a> TryFrom<&SubjectPublicKeyInfo<'a>> for CosignVerificationKey {
))
}
//
#[cfg(feature = "cosign")]
ED25519 => Ok(CosignVerificationKey::ED25519(
ed25519_dalek::VerifyingKey::try_from(*subject_pub_key_info)?,
)),
Expand Down
2 changes: 1 addition & 1 deletion src/fulcio/oauth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl OauthTokenProvider {

match oidc_url.as_ref() {
Ok(url) => {
open::that(url.0.to_string())?;
webbrowser::open(url.0.as_ref())?;
println!(
"Open this URL in a browser if it does not automatically open for you:\n{}\n",
url.0,
Expand Down
2 changes: 1 addition & 1 deletion src/mock_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub(crate) mod test {
pub push_response: Option<anyhow::Result<PushResponse>>,
}

#[async_trait]
#[async_trait(?Send)]
impl crate::registry::ClientCapabilities for MockOciClient {
async fn fetch_manifest_digest(
&mut self,
Expand Down
7 changes: 6 additions & 1 deletion src/oauth/openidflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,15 @@ use openidconnect::core::{
CoreClient, CoreIdToken, CoreIdTokenClaims, CoreIdTokenVerifier, CoreProviderMetadata,
CoreResponseType, CoreTokenResponse,
};
use openidconnect::reqwest::{async_http_client, http_client};
use openidconnect::reqwest::async_http_client;
use openidconnect::{
AuthenticationFlow, AuthorizationCode, ClientId, ClientSecret, CsrfToken, IssuerUrl, Nonce,
PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, Scope,
};

#[cfg(not(target_arch = "wasm32"))]
use openidconnect::reqwest::http_client;

use std::io::{BufRead, BufReader, Write};
use std::net::TcpListener;
use url::Url;
Expand Down Expand Up @@ -157,6 +160,7 @@ impl OpenIDAuthorize {
Ok((authorize_url, client, nonce, pkce_verifier))
}

#[cfg(not(target_arch = "wasm32"))]
pub fn auth_url(&self) -> Result<(Url, CoreClient, Nonce, PkceCodeVerifier)> {
let issuer = IssuerUrl::new(self.oidc_issuer.to_owned()).expect("Missing the OIDC_ISSUER.");

Expand Down Expand Up @@ -268,6 +272,7 @@ impl RedirectListener {
Err(SigstoreError::CodePairError)
}

#[cfg(not(target_arch = "wasm32"))]
pub fn redirect_listener(self) -> Result<(CoreIdTokenClaims, CoreIdToken)> {
let code = self.redirect_listener_internal()?;

Expand Down
4 changes: 2 additions & 2 deletions src/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ use crate::errors::Result;

use async_trait::async_trait;

#[async_trait]
#[async_trait(?Send)]
/// Capabilities that are expected to be provided by a registry client
pub(crate) trait ClientCapabilities: Send + Sync {
pub(crate) trait ClientCapabilities {
async fn fetch_manifest_digest(
&mut self,
image: &oci_distribution::Reference,
Expand Down
2 changes: 1 addition & 1 deletion src/registry/oci_caching_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ async fn pull_manifest_cached(
.map(cached::Return::new)
}

#[async_trait]
#[async_trait(?Send)]
impl ClientCapabilities for OciCachingClient {
async fn fetch_manifest_digest(
&mut self,
Expand Down
2 changes: 1 addition & 1 deletion src/registry/oci_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub(crate) struct OciClient {
pub registry_client: oci_distribution::Client,
}

#[async_trait]
#[async_trait(?Send)]
impl ClientCapabilities for OciClient {
async fn fetch_manifest_digest(
&mut self,
Expand Down

0 comments on commit d9b198a

Please sign in to comment.