1
1
// Copyright 2020 Contributors to the Parsec project.
2
2
// SPDX-License-Identifier: Apache-2.0
3
- use log:: info;
3
+ use log:: { error, info, trace} ;
4
+ use prost:: Message ;
5
+ use psa_crypto:: types:: status:: { Error as PsaError , Status } ;
6
+ use std:: convert:: TryInto ;
4
7
use std:: ffi:: { c_void, CString } ;
5
8
use std:: io:: { Error , ErrorKind } ;
6
9
use std:: ptr:: null_mut;
10
+ use std:: slice;
11
+ use std:: sync:: Mutex ;
7
12
use ts_binding:: * ;
13
+ use ts_protobuf:: Opcode ;
8
14
9
15
#[ allow(
10
16
non_snake_case,
@@ -24,6 +30,8 @@ pub mod ts_binding {
24
30
include ! ( concat!( env!( "OUT_DIR" ) , "/ts_bindings.rs" ) ) ;
25
31
}
26
32
33
+ mod key_management;
34
+
27
35
#[ allow(
28
36
non_snake_case,
29
37
non_camel_case_types,
@@ -42,11 +50,17 @@ mod ts_protobuf {
42
50
include ! ( concat!( env!( "OUT_DIR" ) , "/ts_crypto.rs" ) ) ;
43
51
}
44
52
53
+ // TODO:
54
+ // * RPC caller error handling
55
+ // * proper logging
56
+ // * docs
57
+
45
58
#[ derive( Debug ) ]
46
59
pub struct Context {
47
60
rpc_caller : * mut rpc_caller ,
48
61
service_context : * mut service_context ,
49
62
rpc_session_handle : * mut c_void ,
63
+ call_mutex : Mutex < ( ) > ,
50
64
}
51
65
52
66
impl Context {
@@ -82,10 +96,70 @@ impl Context {
82
96
rpc_caller,
83
97
service_context,
84
98
rpc_session_handle,
99
+ call_mutex : Mutex :: new ( ( ) ) ,
85
100
} ;
86
101
87
102
Ok ( ctx)
88
103
}
104
+
105
+ fn send_request < T : Message + Default > (
106
+ & self ,
107
+ req : & impl Message ,
108
+ opcode : Opcode ,
109
+ rpc_cl : * mut rpc_caller ,
110
+ ) -> Result < T , PsaError > {
111
+ let _mutex_guard = self . call_mutex . try_lock ( ) . expect ( "Call mutex poisoned" ) ;
112
+ info ! ( "Beginning call to Trusted Service" ) ;
113
+
114
+ let mut buf_out = null_mut ( ) ;
115
+ let call_handle = unsafe { rpc_caller_begin ( rpc_cl, & mut buf_out, req. encoded_len ( ) ) } ;
116
+ if call_handle == null_mut ( ) {
117
+ error ! ( "Call handle was null" ) ;
118
+ return Err ( PsaError :: CommunicationFailure ) ;
119
+ } else if buf_out == null_mut ( ) {
120
+ error ! ( "Call buffer was null" ) ;
121
+ return Err ( PsaError :: CommunicationFailure ) ;
122
+ }
123
+ let mut buf_out = unsafe { slice:: from_raw_parts_mut ( buf_out, req. encoded_len ( ) ) } ;
124
+ req. encode ( & mut buf_out) . map_err ( |e| {
125
+ unsafe { rpc_caller_end ( rpc_cl, call_handle) } ;
126
+ format_error ! ( "Failed to serialize Protobuf request" , e) ;
127
+ PsaError :: CommunicationFailure
128
+ } ) ?;
129
+
130
+ trace ! ( "Invoking RPC call" ) ;
131
+ let mut opstatus = 0 ;
132
+ let mut resp = T :: default ( ) ;
133
+ let mut resp_buf = null_mut ( ) ;
134
+ let mut resp_buf_size = 0 ;
135
+ let status = unsafe {
136
+ rpc_caller_invoke (
137
+ rpc_cl,
138
+ call_handle,
139
+ i32:: from ( opcode) . try_into ( ) . unwrap ( ) ,
140
+ & mut opstatus,
141
+ & mut resp_buf,
142
+ & mut resp_buf_size,
143
+ )
144
+ } ;
145
+ if status != 0 || opstatus != 0 {
146
+ unsafe { rpc_caller_end ( rpc_cl, call_handle) } ;
147
+ error ! (
148
+ "Error on call invocation: status = {}, opstatus = {}" ,
149
+ status, opstatus as i32
150
+ ) ;
151
+ Status :: from ( opstatus as i32 ) . to_result ( ) ?;
152
+ }
153
+ let resp_buf = unsafe { slice:: from_raw_parts_mut ( resp_buf, resp_buf_size) } ;
154
+ resp. merge ( & * resp_buf) . map_err ( |e| {
155
+ unsafe { rpc_caller_end ( rpc_cl, call_handle) } ;
156
+ format_error ! ( "Failed to serialize Protobuf request" , e) ;
157
+ PsaError :: CommunicationFailure
158
+ } ) ?;
159
+ unsafe { rpc_caller_end ( rpc_cl, call_handle) } ;
160
+
161
+ Ok ( resp)
162
+ }
89
163
}
90
164
91
165
impl Drop for Context {
0 commit comments