Skip to content

Commit

Permalink
c: adjust for new creds module
Browse files Browse the repository at this point in the history
  • Loading branch information
geonnave committed Aug 2, 2024
1 parent e6cc988 commit 754a866
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 28 deletions.
15 changes: 8 additions & 7 deletions examples/lakers-c-native/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ int main(void)

// lakers init
puts("loading credentials.");
CredentialRPK cred_i = {0}, cred_r = {0};
credential_rpk_new(&cred_i, CRED_I, 107);
credential_rpk_new(&cred_r, CRED_R, 84);
CredentialC cred_i = {0}, cred_r = {0};
credential_new(&cred_i, CRED_I, 107);
credential_new(&cred_r, CRED_R, 84);
puts("creating edhoc initiator.");
EdhocInitiator initiator = {0};
initiator_new(&initiator);
Expand Down Expand Up @@ -153,7 +153,7 @@ int main(void)
memcpy(message_2.content, coap_response_payload, coap_response_payload_len);
EADItemC ead_2 = {0};
uint8_t c_r;
CredentialRPK id_cred_r = {0};
CredentialC id_cred_r = {0};
#ifdef LAKERS_EAD_AUTHZ
// res = initiator_parse_message_2(&initiator, &message_2, &cred_r, &c_r, &id_cred_r, &ead_2);
res = initiator_parse_message_2(&initiator, &message_2, &c_r, &id_cred_r, &ead_2);
Expand All @@ -166,22 +166,23 @@ int main(void)
return 1;
}
// FIXME: failing on native when cred_expected is NULL (memory allocation of 48 bytes failed)
res = credential_check_or_fetch(&cred_r, &id_cred_r);
CredentialC fetched_cred_r = {0};
res = credential_check_or_fetch(&cred_r, &id_cred_r, &fetched_cred_r);
if (res != 0) {
printf("Error handling credential: %d\n", res);
return 1;
}
#ifdef LAKERS_EAD_AUTHZ
puts("processing ead2");
res = authz_device_process_ead_2(&device, &ead_2, &id_cred_r);
res = authz_device_process_ead_2(&device, &ead_2, &fetched_cred_r);
if (res != 0) {
printf("Error process ead2 (authz): %d\n", res);
return 1;
} else {
puts("ead-authz voucher received and validated");
}
#endif
res = initiator_verify_message_2(&initiator, &I, &cred_i, &id_cred_r);
res = initiator_verify_message_2(&initiator, &I, &cred_i, &fetched_cred_r);
if (res != 0) {
printf("Error verify msg2: %d\n", res);
return 1;
Expand Down
5 changes: 5 additions & 0 deletions lakers-c/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ cpp_compat = true

[parse.expand]
all_features = true

[export]
include = [
"CredentialC"
]
5 changes: 3 additions & 2 deletions lakers-c/src/ead_authz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ pub unsafe extern "C" fn authz_device_process_ead_2(
// input parans
device_c: *mut EadAuthzDevice,
ead_2_c: *mut EADItemC,
cred_v: *mut CredentialRPK,
cred_v: *mut CredentialC,
) -> i8 {
let crypto = &mut default_crypto();
let device = &(*device_c);
let ead_2 = (*ead_2_c).to_rust();
let cred_v = (*cred_v).value.as_slice();
let cred_v = (*cred_v).to_rust();
let cred_v = cred_v.bytes.as_slice();
match device.wait_ead2.process_ead_2(crypto, ead_2, cred_v) {
Ok(device) => {
(*device_c).done = device;
Expand Down
14 changes: 7 additions & 7 deletions lakers-c/src/initiator.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use lakers::{
EdhocInitiator as EdhocInitiatorRust, // alias to conflict with the C-compatible struct
// EdhocInitiator as EdhocInitiatorRust, // alias to conflict with the C-compatible struct
*,
};
use lakers_crypto::{default_crypto, CryptoTrait};
Expand All @@ -15,7 +15,7 @@ pub struct EdhocInitiator {
pub wait_m2: WaitM2,
pub processing_m2: ProcessingM2C,
pub processed_m2: ProcessedM2,
pub cred_i: *mut CredentialRPK,
pub cred_i: *mut CredentialC,
pub completed: Completed,
}

Expand Down Expand Up @@ -86,7 +86,7 @@ pub unsafe extern "C" fn initiator_parse_message_2(
message_2: *const EdhocMessageBuffer,
// output params
c_r_out: *mut u8,
id_cred_r_out: *mut CredentialRPK,
id_cred_r_out: *mut IdCred,
ead_2_c_out: *mut EADItemC,
) -> i8 {
// this is a parsing function, so all output parameters are mandatory
Expand Down Expand Up @@ -129,8 +129,8 @@ pub unsafe extern "C" fn initiator_verify_message_2(
// input params
initiator_c: *mut EdhocInitiator,
i: *const BytesP256ElemLen,
mut cred_i: *mut CredentialRPK,
valid_cred_r: *mut CredentialRPK,
cred_i: *mut CredentialC,
valid_cred_r: *mut CredentialC,
) -> i8 {
if initiator_c.is_null() || i.is_null() {
return -1;
Expand All @@ -139,7 +139,7 @@ pub unsafe extern "C" fn initiator_verify_message_2(

let state = core::ptr::read(&(*initiator_c).processing_m2).to_rust();

match i_verify_message_2(&state, crypto, *valid_cred_r, &(*i)) {
match i_verify_message_2(&state, crypto, (*valid_cred_r).to_rust(), &(*i)) {
Ok(state) => {
(*initiator_c).processed_m2 = state;
(*initiator_c).cred_i = cred_i;
Expand Down Expand Up @@ -176,7 +176,7 @@ pub unsafe extern "C" fn initiator_prepare_message_3(
match i_prepare_message_3(
&state,
crypto,
*(*initiator_c).cred_i,
(*(*initiator_c).cred_i).to_rust(),
cred_transfer,
&ead_3,
) {
Expand Down
53 changes: 44 additions & 9 deletions lakers-c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub struct ProcessingM2C {
pub g_y: BytesP256ElemLen,
pub plaintext_2: EdhocMessageBuffer,
pub c_r: u8,
pub id_cred_r: IdCred,
pub ead_2: *mut EADItemC,
}

Expand All @@ -72,6 +73,7 @@ impl Default for ProcessingM2C {
g_y: Default::default(),
plaintext_2: Default::default(),
c_r: Default::default(),
id_cred_r: Default::default(),
ead_2: core::ptr::null_mut(),
}
}
Expand All @@ -87,6 +89,7 @@ impl ProcessingM2C {
g_y: self.g_y,
plaintext_2: self.plaintext_2,
c_r: ConnId::from_int_raw(self.c_r),
id_cred_r: self.id_cred_r.clone(),
ead_2: if self.ead_2.is_null() {
None
} else {
Expand All @@ -110,19 +113,50 @@ impl ProcessingM2C {
let c_r = processing_m2.c_r.as_slice();
assert_eq!(c_r.len(), 1, "C API only supports short C_R");
(*processing_m2_c).c_r = c_r[0];
(*processing_m2_c).id_cred_r = processing_m2.id_cred_r;
}
}

#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub struct CredentialC {
pub bytes: BufferCred,
pub key: CredentialKey,
/// differs from Rust: here we assume the kid is always present
/// this is to simplify the C API, since C doesn't support Option<T>
/// the alternative would be to use a pointer, but then we need to care about memory management
pub kid: BufferKid,
pub cred_type: CredentialType,
}

impl CredentialC {
pub fn to_rust(&self) -> Credential {
Credential {
bytes: self.bytes,
key: self.key,
kid: Some(self.kid),
cred_type: self.cred_type,
}
}

pub unsafe fn copy_into_c(cred: Credential, cred_c: *mut CredentialC) {
(*cred_c).bytes = cred.bytes;
(*cred_c).key = cred.key;
(*cred_c).kid = cred.kid.unwrap();
(*cred_c).cred_type = cred.cred_type;
}
}

#[no_mangle]
pub unsafe extern "C" fn credential_rpk_new(
cred: *mut CredentialRPK,
pub unsafe extern "C" fn credential_new(
cred: *mut CredentialC,
value: *const u8,
value_len: usize,
) -> i8 {
let value = core::slice::from_raw_parts(value, value_len);
match CredentialRPK::new(EdhocMessageBuffer::new_from_slice(value).unwrap()) {
Ok(cred_rpk) => {
*cred = cred_rpk;
match Credential::parse_ccs(value) {
Ok(cred_parsed) => {
CredentialC::copy_into_c(cred_parsed, cred);
0
}
Err(_) => -1,
Expand All @@ -131,19 +165,20 @@ pub unsafe extern "C" fn credential_rpk_new(

#[no_mangle]
pub unsafe extern "C" fn credential_check_or_fetch(
cred_expected: *mut CredentialRPK,
id_cred_received: *mut CredentialRPK,
cred_expected: *mut CredentialC,
id_cred_received: *mut IdCred,
cred_out: *mut CredentialC,
) -> i8 {
let cred_expected = if cred_expected.is_null() {
None
} else {
Some(*cred_expected)
Some((*cred_expected).to_rust())
};

let id_cred_received_value = *id_cred_received;
match credential_check_or_fetch_rust(cred_expected, id_cred_received_value) {
Ok(valid_cred) => {
*id_cred_received = valid_cred;
CredentialC::copy_into_c(valid_cred, cred_out);
0
}
Err(err) => err as i8,
Expand Down
5 changes: 4 additions & 1 deletion shared/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ cpp_compat = true
[export]
include = [
"EdhocMessageBuffer", "BytesMac", "BytesMac2",
"EADItemC", "CredentialRPK", "CredentialTransfer",
"EADItemC",
"EdhocBuffer", "BufferKid", "BufferCred", "BufferIdCred",
"CredentialKey", "CredentialType", "IdCred",
"CredentialTransfer",
"InitiatorStart", "WaitM2", "Completed", "ProcessedM2",
"EdhocInitiatorC", "EdhocInitiatorWaitM2C", "EdhocInitiatorProcessingM2C", "EdhocInitiatorProcessedM2C", "EdhocInitiatorDoneC",
]
2 changes: 1 addition & 1 deletion shared/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ pub enum EdhocBufferError {
/// so that in the future it can be hot-swappable by the application.
// TODO: replace EdhocMessageBuffer with EdhocBuffer all over the library
// NOTE: how would this const generic thing work across the C and Python bindings?
#[repr(C)]
#[derive(PartialEq, Debug, Copy, Clone)]
#[repr(C)]
pub struct EdhocBuffer<const N: usize> {
pub content: [u8; N],
pub len: usize,
Expand Down
5 changes: 4 additions & 1 deletion shared/src/cred.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ pub type BytesKeyAES128 = [u8; 16];
pub type BytesKeyEC2 = [u8; 32];

#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub enum CredentialKey {
Symmetric(BytesKeyAES128),
EC2Compact(BytesKeyEC2),
// Add other key types as needed
}

#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub enum CredentialType {
CCS,
#[allow(non_camel_case_types)]
Expand Down Expand Up @@ -41,6 +43,7 @@ impl From<u8> for IdCredType {
///
/// Possible values include key IDs, credentials by value and others.
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[repr(C)]
pub struct IdCred {
/// The value is always stored in the ID_CRED_x form as a serialized one-element dictionary;
/// while this technically wastes two bytes, it has the convenient property of having the full
Expand Down Expand Up @@ -137,8 +140,8 @@ impl IdCred {
/// Experimental support for CCS_PSK credentials is also available.
// TODO: add back support for C and Python bindings
#[cfg_attr(feature = "python-bindings", pyclass)]
// #[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub struct Credential {
/// Original bytes of the credential, CBOR-encoded
///
Expand Down

0 comments on commit 754a866

Please sign in to comment.