1#![warn(missing_debug_implementations, missing_docs)]
2use clap::Parser;
6use colog::default_builder;
7use log::LevelFilter;
8use twizzler::{
9 marker::BaseType,
10 object::{Object, ObjectBuilder, RawObject, TypedObject},
11};
12use twizzler_abi::{
13 object::Protections,
14 syscall::{ObjectCreate, sys_sctx_attach, sys_thread_set_active_sctx_id},
15};
16use twizzler_rt_abi::object::MapFlags;
17use twizzler_security::{
18 Cap, SecCtx, SecCtxFlags, SecureBuilderExt as _, SigningKey, SigningScheme,
19};
20
21mod args;
22use args::*;
23
24fn main() {
25 let mut builder = default_builder();
26 builder.filter_level(LevelFilter::Trace);
27 builder.init();
28
29 let args = CliArgs::parse();
30
31 match args.command {
32 Commands::Obj(commands) => match commands {
33 ObjCommands::Inspect(args) => {
34 if let Some(sec_ctx_id) = args.sec_ctx_id {
35 let sec_ctx = SecCtx::try_from(sec_ctx_id).unwrap();
36 sec_ctx
37 .set_active()
38 .expect("Failed to set sec_ctx to active");
39 println!("activated SecCtx: {sec_ctx_id:#?}");
40 }
41
42 let target =
43 Object::<MessageStoreObj>::map(args.obj_id, MapFlags::READ | MapFlags::WRITE)
44 .unwrap();
45
46 let base = target.base();
47
48 let meta = target.meta_ptr();
49
50 unsafe {
51 println!("{target:#?}\n{:#?}\n{base:#?}", *meta);
52 }
53 }
54
55 ObjCommands::Sealed(args) => {
56 let spec = ObjectCreate::new(
58 Default::default(),
59 Default::default(),
60 Some(args.verifying_key_id),
61 Default::default(),
62 Protections::empty(),
63 );
64
65 println!("creating target object with spec: {:#?}", spec);
66
67 let builder = ObjectBuilder::new(spec);
68 let base = MessageStoreObj {
69 _message: heapless::String::<256>::try_from(args.message.as_str())
70 .expect("message was longer than 256 characters!!"),
71 };
72
73 let obj = {
74 let s_key = Object::<SigningKey>::map(args.signing_key_id, MapFlags::READ)
75 .expect("failed to map signing key object");
76 builder
77 .build_secure(base, s_key.base())
79 .expect("secure build should succeed")
80 };
81
82 unsafe {
83 println!(
84 "created Object with id: {:#?}\n{:#?}",
85 obj.id(),
86 *obj.base_ptr::<MessageStoreObj>()
88 );
89 }
90 }
91 ObjCommands::New(args) => {
92 let spec = ObjectCreate::new(
94 Default::default(),
95 Default::default(),
96 Some(args.verifying_key_id),
97 Default::default(),
98 Protections::READ | Protections::WRITE,
99 );
100
101 println!("creating target object with spec: {:#?}", spec);
102
103 let base = MessageStoreObj {
104 _message: heapless::String::<256>::try_from(args.message.as_str())
105 .expect("message was longer than 256 characters!!"),
106 };
107
108 let obj = ObjectBuilder::new(spec)
109 .build(base)
110 .expect("build should succeed");
111
112 unsafe {
113 println!(
114 "created Object with id: {:#?}\n{:#?}",
115 obj.id(),
116 *obj.meta_ptr()
118 );
119 }
120 }
121 },
122 Commands::Key(KeyCommands::NewPair) => {
123 let (s_key, v_key) = SigningKey::new_keypair(&SigningScheme::Ecdsa, Default::default())
124 .expect("should have worked");
125
126 println!(
127 "Keypair created!\nSigning Key: {:#?}\nVerifying Key: {:#?}",
128 s_key.id(),
129 v_key.id()
130 );
131 }
132 Commands::Ctx(ctxcommands) => match ctxcommands {
133 CtxCommands::Add(addcommad) => match addcommad {
134 CtxAddCommands::Cap(args) => {
135 if let Some(sec_ctx_id) = args.executing_ctx {
136 let sec_ctx = SecCtx::try_from(sec_ctx_id).unwrap();
137 sys_sctx_attach(sec_ctx.id()).unwrap();
138 sys_thread_set_active_sctx_id(sec_ctx.id()).unwrap();
139 println!("attached to SecCtx: {sec_ctx_id:#?}");
140 }
141 let s_key = Object::<SigningKey>::map(args.signing_key_id, MapFlags::READ)
143 .expect("failed to map signing key object");
144
145 let mut modifying_sec_ctx = SecCtx::try_from(args.modifying_ctx)
146 .expect("failed to map modifying SecCtx");
147
148 let cap = Cap::new(
150 args.target_obj,
151 args.modifying_ctx,
152 Protections::all(),
153 s_key.base(),
154 Default::default(),
155 Default::default(),
156 Default::default(),
157 )
158 .unwrap();
159
160 modifying_sec_ctx
161 .insert_cap(cap.clone())
162 .expect("Failed to insert capability!");
163
164 println!("Inserted\n{cap:?}\ninto {:?}", modifying_sec_ctx.base());
165 }
166 },
167 CtxCommands::New(args) => {
168 let flags = if args.undetachable {
169 SecCtxFlags::UNDETACHABLE
170 } else {
171 SecCtxFlags::empty()
172 };
173
174 let sec_ctx = SecCtx::new(
175 ObjectCreate::new(
176 Default::default(),
177 Default::default(),
178 None,
179 Default::default(),
180 Protections::all(),
181 ),
182 Protections::all(),
183 flags,
184 )
185 .unwrap();
186
187 let id = sec_ctx.id();
188
189 let base = sec_ctx.base();
190
191 println!("Created SecCtx: {id:#?}\n{base:#?}");
192 }
193
194 CtxCommands::Inspect(args) => {
195 let sec_ctx =
196 SecCtx::try_from(args.sec_ctx_id).expect("unable to parse as valid sec_ctx");
197
198 println!("{:#?}", sec_ctx);
199 }
200 },
201 }
202}
203
204#[derive(Debug, Clone)]
205struct MessageStoreObj {
206 _message: heapless::String<256>,
207}
208
209impl BaseType for MessageStoreObj {
210 fn fingerprint() -> u64 {
211 11234
212 }
213}