binhost/runner/src/main.rs
Ivan Bushchik debff608d2
Remove runner from workspace
Signed-off-by: Ivan Bushchik <ivabus@ivabus.dev>
2024-02-21 20:15:36 +03:00

83 lines
2.5 KiB
Rust

// SPDX-License-Identifier: MIT
// "Runner" is written in no_std Rust for the smaller executable size: ~49KiB (Darwin arm64) vs ~300KiB
#![no_main]
#![no_std]
use core::slice::from_raw_parts;
use ed25519_compact::{PublicKey, Signature};
use libc::{c_char, c_int, c_void, exit, open, printf, read, O_RDONLY};
// 1 KiB seems fine
const BUFFER_SIZE: usize = 1024;
const PUBKEY_LEN: usize = PublicKey::BYTES;
const SIGNATURE_LEN: usize = Signature::BYTES;
#[allow(clippy::missing_safety_doc)]
#[no_mangle]
pub unsafe extern "C" fn main(_argc: i32, _argv: *const *const c_char) -> i32 {
printf("Starting runner\n\0".as_bytes().as_ptr() as *const c_char);
let mut buff_public_key = [0_u8; PUBKEY_LEN];
let a = 0;
read(
open("public_key\0".as_bytes().as_ptr() as *const c_char, O_RDONLY),
buff_public_key.as_mut_ptr() as *mut c_void,
PUBKEY_LEN,
);
let public_key = PublicKey::new(buff_public_key);
let mut signature = [0_u8; SIGNATURE_LEN];
read(
open("signature\0".as_bytes().as_ptr() as *const c_char, O_RDONLY),
signature.as_mut_ptr() as *mut c_void,
SIGNATURE_LEN,
);
let arg = from_raw_parts(_argv, _argc as usize)[1]; // Getting path to binary
let binary_fd = open(arg, O_RDONLY);
let mut buffer = [0u8; BUFFER_SIZE];
let mut state = public_key.verify_incremental(&Signature::new(signature)).unwrap();
loop {
let bytes_read: usize =
read(binary_fd, buffer.as_mut_ptr() as *mut c_void, BUFFER_SIZE) as usize;
state.absorb(&buffer[0..bytes_read]);
if bytes_read != BUFFER_SIZE {
break;
}
}
printf("Signature: \0".as_bytes().as_ptr() as *const c_char);
if state.verify().is_ok() {
printf("OK\n\0".as_bytes().as_ptr() as *const c_char);
} else {
printf("Bad\n\0".as_bytes().as_ptr() as *const c_char);
return 2;
}
0
}
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
use numtoa::NumToA;
let mut buff = [0u8; 8];
unsafe {
printf("Panicked\0".as_bytes().as_ptr() as *const c_char);
if let Some(location) = info.location() {
printf(" at \0".as_bytes().as_ptr() as *const c_char);
location.line().numtoa(10, &mut buff).iter().for_each(|ch| {
libc::putchar(*ch as c_int);
});
printf(":\0".as_bytes().as_ptr() as *const c_char);
location.column().numtoa(10, &mut buff).iter().for_each(|ch| {
libc::putchar(*ch as c_int);
});
printf(" in \0".as_bytes().as_ptr() as *const c_char);
location.file().chars().for_each(|ch| {
libc::putchar(ch as c_int);
});
}
libc::putchar(b'\n' as c_int);
exit(3)
}
}