Skip to content

Commit

Permalink
Create minimal web attestation explaination library with the wasm-pac…
Browse files Browse the repository at this point in the history
…k CLI. (We'll later use wasm-pack for a web client).

Due to persistent issues with wasm-pack and bazel, we're just using the cargo version for now.

Bug: 354737767
Change-Id: I562cbc3360d1c6b14a368c3505671c1c532f8ed5
  • Loading branch information
jul-sh committed Jul 26, 2024
1 parent df0cfab commit e8bd4b6
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 103 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ members = [
"oak_attestation",
"oak_attestation_explain",
"oak_attestation_explain_cli",
"oak_attestation_explain_wasm",
"oak_attestation_integration_tests",
"oak_attestation_verification",
"oak_attestation_verification_test_utils",
Expand Down
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
systemd
qemu_kvm
python312
wasm-pack
];
};
# For some reason node does not know how to find the prettier plugin, so we need to
Expand Down
7 changes: 7 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,13 @@ ensure_no_std package:

all_ensure_no_std: (ensure_no_std "micro_rpc") (ensure_no_std "oak_attestation_verification") (ensure_no_std "oak_restricted_kernel_sdk")

oak_attestation_explain_wasm:
env --chdir=oak_attestation_explain_wasm \
wasm-pack build \
--target web # "web" bundles for native web use \
--release \
--no-pack # prevents generating a package.json, we don't need it since we don't use a web bundler

# Entry points for Kokoro CI.

kokoro_build_binaries_rust: all_enclave_apps oak_restricted_kernel_bin \
Expand Down
28 changes: 0 additions & 28 deletions oak_attestation_explain_wasm/BUILD

This file was deleted.

20 changes: 20 additions & 0 deletions oak_attestation_explain_wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "oak_attestation_explain_wasm"
version = "0.1.0"
authors = ["Juliette Pretot <[email protected]>"]
edition = "2018"

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

[features]
default = ["js"]
js = ["getrandom/js"]

[dependencies]
wasm-bindgen = "*"
getrandom = "*"
oak_attestation_explain = { workspace = true }
oak_proto_rust = { workspace = true }
prost = { workspace = true, default-features = false }
oak_attestation_verification = { workspace = true }
43 changes: 31 additions & 12 deletions oak_attestation_explain_wasm/index.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
<!doctype html>
<html>
<head>
<title>WASM Test</title>
<title>Oak Attestation Explanation</title>
<meta charset="UTF-8" />
<script type="module">
// For now we're just hardcoding the evidence.
const ENCODED_EVIDENCE =
'Co0KCAESoAkCAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAMAAAAAABTRAQAAAAAAAAAAAAAAAAAAAI/GdBW4EgHxifLRnL5Xqmb3KCkWtbnmzKg6uGiPRJnTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsCQ5FlP1A7hhskNQ/etjZBIOLqpZDpL4dnU/w/dZwpiVl4kF2YACOBYzC8gKerIoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJOH58KqtA5m+Yoa65PFh51fAe9E57qR3Qs9LeRbfH+v//////////////////////////////////////////8DAAAAAAAU0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAELh+SZgzCv32Zak216+r+gzYerG+W2zUKcMfgcRX61gqF9a6YuPuH7HbOKj+BrXDfiuu94cPCF5eJegS2FiNe8DAAAAAAAU0RA3AQAQNwEAAwAAAAAAFNEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACyRezDOZVCOuEtZ7eE7nzrH14TlglDRspqs8xlBTZPBsYxkniDhxLDA/8scMUKjE0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADeZW43mYVHZaQZO+RTkiT/xaDhnm8dAl5m9MJE2uo25Er5ZDBZfjrRb/FvE7JhnXwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpmpwECAlRUoMw21VOnemZEfr4KzwHRkJfZMQMmBIECIAEhWCAXm6xL/a/gsiu0G7YKea+kuUBRH6Tc+99yMNZe6q5pdyJYIMqaoVPTOUFMHpOHJErbZPXJFyQDDu/xEXVvFMiHvTUIEtUECtIEhEOhASahBFJBc3ltbWV0cmljRUNEU0EyNTZZAfOlAXgoNTRhMGNjMzZkNTUzYTc3YTY2NDQ3ZWJlMGFjZjAxZDE5MDk3ZDkzMQJ4KGEzMWU0MmFkM2ZhNzczY2VjODkwNThhMjFiZmExNzY4MDU1NmQxMTI6AEdEV1hmpwECAlSjHkKtP6dzzsiQWKIb+hdoBVbREgMmBIECIAEhWCAYxAWGKTsqGnj+0V+Vs+ukTRNm5ujilTrO8yQV7RAfqiJYIPF/5lh9geEZAoRESkiLa0zj++x9xxmN7nWgMneLWb1MOgBHRFhCIAA6AEdEWqc6AEdEYKE6AEdEa1gg7HUsZgSBQy9SX0nQvhUhx+pC678s5wWq0ngaMp4QAdg6AEdEYaE6AEdEa1ggK5hYbZkFpgXCldd8YejP0gJ65bigTu+pAYQ29q0RQpc6AEdEbG1jb25zb2xlPXR0eVMwOgBHRGKhOgBHRGtYIEzQIIINpmMGP0GFyhSn6APNfJyhSDxk6DbbhAYEtvrBOgBHRGOhOgBHRGtYINr3nyS1dENArBjCtGjn4KeRVoTF39okUKz6ciW9x1u4OgBHRGShOgBHRGtYIBp9VeH0s9E7X1N7K1D9XNjpT93N6AsVUkq5NSicLjoIOgBHRGWhOgBHRGtYIGT1VTJyh6IUFHZoHk5N2A1fdaucJ29tuO/8VSNtuplTWEAZhgvIG9fw4jJfMNf26XxM1/KyOtcSSBuwzjaC0aF1Cgmngz5l0XvRF+dSkxoBTfPnFUSJKpH1SDbdHk2p0kYsGrcFCscChEOhASahBFJBc3ltbWV0cmljRUNEU0EyNTZY6aUBeChhMzFlNDJhZDNmYTc3M2NlYzg5MDU4YTIxYmZhMTc2ODA1NTZkMTEyAngoN2JjODQzMzIwZjcyOTdiMjQ3ZjAxOTZkNDZiYzhmNGMzZDhlNmJmZjoAR0RXWESmAQECVHvIQzIPcpeyR/AZbUa8j0w9jmv/AzgeBIEFIAQhWCBAje12TlA7Sawk9XV0dJ6emupkOqsD0KO04TBvidtYfDoAR0RYQiAAOgBHRFuiOgBHRGahOgBHRGtYIH1Ggqmg+XreD62aR/JH4ctu0yboC6Beo5/ISy/mvKz7OgBHRGmhOgBHRGtAWEAESfIfZcqIrA2ZfAfsn7UXaJcRkk428UoQu3HH7K9+bJnMkfVMLQ3sZINTk1/5U9t8pk6FUPwL3at7AdZwsc9qEuoChEOhASahBFJBc3ltbWV0cmljRUNEU0EyNTZZAQulAXgoYTMxZTQyYWQzZmE3NzNjZWM4OTA1OGEyMWJmYTE3NjgwNTU2ZDExMgJ4KDc3NjY3MWVkMDUyNWQ2ZGViMDQyNGYwNjY4Yzc4OTkwYzliYmU5MmM6AEdEV1hmpwECAlR3ZnHtBSXW3rBCTwZox4mQybvpLAMmBIECIAEhWCBhf/ZC0txzHodUydtnhEbQtgiUPowmjUBNzbfsk6rqZiJYIFPkHIY/dtu7nh9sw25yuPDl5MJg8ihMcXoXT5hI+TLHOgBHRFhCIAA6AEdEW6I6AEdEZqE6AEdEa1ggfUaCqaD5et4PrZpH8kfhy27TJugLoF6jn8hLL+a8rPs6AEdEaaE6AEdEa0BYQMw83xBhzxnkCvILq9UkvjNF2CRh0b4xZI1/t/bVzihuSdCfBllSwbG/koyeUNqxb+roLfyj++z+Hasz2XbLP/U=';

import init, { explain } from './oak_attestation_explain_wasm.js';

// Function to decode Base64 to bytes
function decodeBase64(base64) {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes;
}

// Function to explain attestation
async function explainAttestation(attestationBytes) {
await init();
const explanation = explain(decodeBase64(attestationBytes));
document.getElementById('explanation').textContent = explanation;
}

window.onload = () => {
explainAttestation(ENCODED_EVIDENCE);
};
</script>
</head>

<body>
<script>
const importObj = {};
(async () => {
const response = await fetch('./oak_attestation_explain_wasm.wasm');
const { instance } = await WebAssembly.instantiateStreaming(
response,
importObj,
);
console.log(instance.exports.nth_prime(10));
})();
</script>
<pre id="explanation">verifying attestation evidence...</pre>
</body>
</html>
19 changes: 19 additions & 0 deletions oak_attestation_explain_wasm/serve.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

# Exit immediately if a command exits with a non-zero status
set -e

readonly WORKSPACE_ROOT=$(bazel info workspace)
readonly OUTPUT_DIR=oak_attestation_explain_wasm/pkg

# Navigating to the Bazel workspace root
cd "$WORKSPACE_ROOT"

echo "INFO: Building the project using wasm-pack"
just oak_attestation_explain_wasm

echo "INFO: Copying index.html to the output directory: ${OUTPUT_DIR}"
cp oak_attestation_explain_wasm/index.html "${OUTPUT_DIR}"

echo "INFO: Starting a HTTP server in the output directory: ${OUTPUT_DIR}"
python3 -m http.server --directory "${OUTPUT_DIR}" 0
77 changes: 14 additions & 63 deletions oak_attestation_explain_wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2022 The Project Oak Authors
// Copyright 2024 The Project Oak Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -14,66 +14,17 @@
// limitations under the License.
//

// TODO: b/351012006 - Load the attestation library.
// Right now this is just a placeholder for WASM logic without generated
// bindings. From: https://surma.dev/things/rust-to-webassembly/

#![no_std]
extern crate alloc;
use alloc::{alloc::Layout, vec::Vec};
use core::{alloc::GlobalAlloc, cell::UnsafeCell};

const ARENA_SIZE: usize = 128 * 1024;

#[repr(C, align(32))]
struct SimpleAllocator {
arena: UnsafeCell<[u8; ARENA_SIZE]>,
head: UnsafeCell<usize>,
}

impl SimpleAllocator {
const fn new() -> Self {
SimpleAllocator { arena: UnsafeCell::new([0; ARENA_SIZE]), head: UnsafeCell::new(0) }
}
}

unsafe impl Sync for SimpleAllocator {}

#[global_allocator]
static ALLOCATOR: SimpleAllocator = SimpleAllocator::new();

unsafe impl GlobalAlloc for SimpleAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let size = layout.size();
let align = layout.align();
let idx = (*self.head.get()).next_multiple_of(align);
*self.head.get() = idx + size;
let arena: &mut [u8; ARENA_SIZE] = &mut (*self.arena.get());
match arena.get_mut(idx) {
Some(item) => item as *mut u8,
_ => core::ptr::null_mut(),
}
}

unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {
/* lol */
}
}

#[panic_handler]
fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! {
core::arch::wasm32::unreachable()
}

#[no_mangle]
pub extern "C" fn nth_prime(n: usize) -> usize {
let mut primes: Vec<usize> = Vec::new();
let mut current = 2;
while primes.len() < n {
if !primes.iter().any(|prime| current % prime == 0) {
primes.push(current);
}
current += 1;
}
primes.into_iter().last().unwrap_or(0)
use oak_attestation_explain::HumanReadableExplanation;
use oak_proto_rust::oak::attestation::v1::Evidence;
use prost::Message;

#[wasm_bindgen::prelude::wasm_bindgen]
pub fn explain(bytes: &[u8]) -> String {
let extracted_evidence = {
// TODO: b/334900893 - Generate extracted evidence programatically.
let evidence = Evidence::decode(bytes).expect("could not decode evidence");
oak_attestation_verification::verifier::extract_evidence(&evidence)
.expect("could not extract evidence")
};
extracted_evidence.description().unwrap()
}

0 comments on commit e8bd4b6

Please sign in to comment.