1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
extern crate cose;
use std::slice;
use cose::decoder::decode_signature;
use cose::SignatureAlgorithm;
unsafe fn from_raw(ptr: *const u8, len: usize) -> Vec<u8> {
slice::from_raw_parts(ptr, len).to_vec()
}
type VerifyCallback = extern "C" fn(*const u8,
usize,
*const *const u8,
usize,
*const usize,
*const u8,
usize,
*const u8,
usize,
u8 )
-> bool;
#[no_mangle]
pub extern "C" fn verify_cose_signature_ffi(
payload: *const u8,
payload_len: usize,
cose_signature: *const u8,
cose_signature_len: usize,
verify_callback: VerifyCallback,
) -> bool {
if payload.is_null() || cose_signature.is_null() || payload_len == 0 ||
cose_signature_len == 0
{
return false;
}
let payload = unsafe { from_raw(payload, payload_len) };
let cose_signature = unsafe { from_raw(cose_signature, cose_signature_len) };
let cose_signatures = decode_signature(cose_signature, &payload);
let cose_signatures = match cose_signatures {
Ok(signature) => signature,
Err(_) => Vec::new(),
};
if cose_signatures.len() < 1 {
return false;
}
let mut result = true;
for cose_signature in cose_signatures {
let signature_type = cose_signature.signature_type;
let signature_type = match signature_type {
SignatureAlgorithm::ES256 => 0,
SignatureAlgorithm::ES384 => 1,
SignatureAlgorithm::ES512 => 2,
SignatureAlgorithm::PS256 => 3,
};
let signature_bytes = cose_signature.signature;
let real_payload = cose_signature.to_verify;
let mut cert_lens: Vec<usize> = Vec::new();
let mut certs: Vec<*const u8> = Vec::new();
for cert in &cose_signature.certs {
cert_lens.push(cert.len());
certs.push(cert.as_ptr());
}
result &= verify_callback(
real_payload.as_ptr(),
real_payload.len(),
certs.as_ptr(),
certs.len(),
cert_lens.as_ptr(),
cose_signature.signer_cert.as_ptr(),
cose_signature.signer_cert.len(),
signature_bytes.as_ptr(),
signature_bytes.len(),
signature_type,
);
if !result {
return result;
}
}
result
}