@@ -8,6 +8,9 @@ use crate::{
8
8
} ;
9
9
use parsec_openssl2:: types:: VOID_PTR ;
10
10
use parsec_openssl2:: * ;
11
+ use picky_asn1;
12
+ use picky_asn1_x509:: RsaPublicKey ;
13
+ use std:: slice;
11
14
use std:: sync:: { Arc , RwLock } ;
12
15
13
16
pub struct ParsecProviderKeyObject {
@@ -165,6 +168,46 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_has(
165
168
}
166
169
}
167
170
171
+ /*
172
+ Reads the modulus and exponent components of the RSA key from the parameters and
173
+ returns a public key of type RsaPublicKey
174
+ */
175
+ unsafe fn parsec_rsa_set_public_params ( params : * mut OSSL_PARAM ) -> Result < RsaPublicKey , String > {
176
+ // Read the modulus
177
+ let mod_param: openssl_bindings:: OSSL_PARAM =
178
+ * openssl_returns_nonnull ( openssl_bindings:: OSSL_PARAM_locate (
179
+ params,
180
+ OSSL_PKEY_PARAM_RSA_N . as_ptr ( ) as * const std:: os:: raw:: c_char ,
181
+ ) )
182
+ . map_err ( |_| "OSSL_PKEY_PARAM_RSA_N not found" . to_string ( ) ) ?;
183
+
184
+ let mut modulus =
185
+ slice:: from_raw_parts ( mod_param. data as * const u8 , mod_param. data_size ) . to_vec ( ) ;
186
+ //ToDo: endianess
187
+ modulus. reverse ( ) ;
188
+ let modulus = picky_asn1:: wrapper:: IntegerAsn1 :: from_bytes_be_unsigned ( modulus) ;
189
+
190
+ // Read the exponent
191
+ let exp_param: openssl_bindings:: OSSL_PARAM =
192
+ * openssl_returns_nonnull ( openssl_bindings:: OSSL_PARAM_locate (
193
+ params,
194
+ OSSL_PKEY_PARAM_RSA_E . as_ptr ( ) as * const std:: os:: raw:: c_char ,
195
+ ) )
196
+ . map_err ( |_| "OSSL_PKEY_PARAM_RSA_E not found" . to_string ( ) ) ?;
197
+
198
+ let mut exp = slice:: from_raw_parts ( exp_param. data as * const u8 , exp_param. data_size ) . to_vec ( ) ;
199
+ //ToDo: endianess
200
+ exp. reverse ( ) ;
201
+ let exp = picky_asn1:: wrapper:: IntegerAsn1 :: from_bytes_be_unsigned ( exp) ;
202
+
203
+ // Create a public key and return
204
+ let public_key = RsaPublicKey {
205
+ modulus : modulus,
206
+ public_exponent : exp,
207
+ } ;
208
+ Ok ( public_key)
209
+ }
210
+
168
211
/*
169
212
should import data indicated by selection into keydata with values taken from the OSSL_PARAM array params
170
213
*/
@@ -173,42 +216,63 @@ pub unsafe extern "C" fn parsec_provider_kmgmt_import(
173
216
selection : std:: os:: raw:: c_int ,
174
217
params : * mut OSSL_PARAM ,
175
218
) -> std:: os:: raw:: c_int {
176
- if selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as std:: os:: raw:: c_int != 0 {
177
- let result = super :: r#catch ( Some ( || super :: Error :: PROVIDER_KEYMGMT_IMPORT ) , || {
178
- Arc :: increment_strong_count ( keydata as * const RwLock < ParsecProviderKeyObject > ) ;
179
- let key_data = Arc :: from_raw ( keydata as * const RwLock < ParsecProviderKeyObject > ) ;
180
- let param: openssl_bindings:: OSSL_PARAM =
181
- * openssl_returns_nonnull ( openssl_bindings:: OSSL_PARAM_locate (
182
- params,
183
- PARSEC_PROVIDER_KEY_NAME . as_ptr ( ) as * const std:: os:: raw:: c_char ,
184
- ) ) ?;
185
-
219
+ let result = super :: r#catch ( Some ( || super :: Error :: PROVIDER_KEYMGMT_IMPORT ) , || {
220
+ Arc :: increment_strong_count ( keydata as * const RwLock < ParsecProviderKeyObject > ) ;
221
+ let key_data = Arc :: from_raw ( keydata as * const RwLock < ParsecProviderKeyObject > ) ;
222
+ let mut writer_key_data = key_data. write ( ) . unwrap ( ) ;
223
+
224
+ let provider_key_name = openssl_returns_nonnull ( openssl_bindings:: OSSL_PARAM_locate (
225
+ params,
226
+ PARSEC_PROVIDER_KEY_NAME . as_ptr ( ) as * const std:: os:: raw:: c_char ,
227
+ ) ) ;
228
+
229
+ if ( selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS as std:: os:: raw:: c_int != 0 )
230
+ && provider_key_name. is_ok ( )
231
+ {
232
+ let name_param = * provider_key_name. unwrap ( ) ;
186
233
let key_name = std:: str:: from_utf8_unchecked ( core:: slice:: from_raw_parts (
187
- param . data as * mut u8 ,
188
- param . data_size ,
234
+ name_param . data as * mut u8 ,
235
+ name_param . data_size ,
189
236
) ) ;
190
237
191
- let reader_key_data = key_data. read ( ) . unwrap ( ) ;
192
- let keys = reader_key_data
238
+ let keys = writer_key_data
193
239
. provctx
194
240
. get_client ( )
195
241
. list_keys ( )
196
242
. map_err ( |_| "Failed to list Parsec Provider's Keys" . to_string ( ) ) ?;
197
243
198
244
if keys. iter ( ) . any ( |kinfo| kinfo. name == key_name) {
199
- Ok ( OPENSSL_SUCCESS )
245
+ let key_name: & mut [ u8 ] = core:: slice:: from_raw_parts_mut (
246
+ name_param. data as * mut u8 ,
247
+ name_param. data_size ,
248
+ ) ;
249
+ let key_name = std:: str:: from_utf8 ( key_name) ?;
250
+ writer_key_data. key_name = Some ( key_name. to_string ( ) ) ;
251
+
252
+ let rsa_bytes = writer_key_data
253
+ . provctx
254
+ . get_client ( )
255
+ . psa_export_public_key ( key_name)
256
+ . map_err ( |e| format ! ( "Parsec Client failed to sign: {:?}" , e) ) ?;
257
+ let public_key: RsaPublicKey = picky_asn1_der:: from_bytes ( & rsa_bytes)
258
+ . map_err ( |_| "Failed to parse RsaPublicKey data" . to_string ( ) ) ?;
259
+ writer_key_data. rsa_key = Some ( public_key) ;
200
260
} else {
201
- Err ( "Specified Key not found in the Parsec Provider" . into ( ) )
261
+ return Err ( "Invalid key name" . to_string ( ) . into ( ) ) ;
202
262
}
203
- } ) ;
204
- match result {
205
- // Right now, settable params are the same as the import types, so it's ok to use this
206
- // function
207
- Ok ( _) => parsec_provider_kmgmt_set_params ( keydata, params) ,
208
- Err ( ( ) ) => OPENSSL_ERROR ,
263
+ return Ok ( OPENSSL_SUCCESS ) ;
209
264
}
210
- } else {
211
- OPENSSL_SUCCESS
265
+
266
+ if selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY as std:: os:: raw:: c_int != 0 {
267
+ let rsa_key = parsec_rsa_set_public_params ( params)
268
+ . map_err ( |_| "Failed to set RSA public keys" . to_string ( ) ) ?;
269
+ writer_key_data. rsa_key = Some ( rsa_key) ;
270
+ }
271
+ Ok ( OPENSSL_SUCCESS )
272
+ } ) ;
273
+ match result {
274
+ Ok ( _) => OPENSSL_SUCCESS ,
275
+ Err ( ( ) ) => OPENSSL_ERROR ,
212
276
}
213
277
}
214
278
0 commit comments