@@ -344,6 +344,128 @@ pub struct Key {
344
344
id : KeyringSerial ,
345
345
}
346
346
347
+ /// Structure to store results from a query on optional feature support for a key.
348
+ pub struct KeySupportInfo {
349
+ /// Features supported by the key.
350
+ pub supported_ops : KeyctlSupportFlags ,
351
+ /// The size of the key (in bits).
352
+ pub key_size : u32 ,
353
+ /// The maximum size of a data blob which may be signed.
354
+ pub max_data_size : u16 ,
355
+ /// The maximum size of a signature blob.
356
+ pub max_sig_size : u16 ,
357
+ /// The maximum size of a blob to be encrypted.
358
+ pub max_enc_size : u16 ,
359
+ /// The maximum size of a blob to be decrypted.
360
+ pub max_dec_size : u16 ,
361
+ }
362
+
363
+ impl KeySupportInfo {
364
+ fn from_c ( c_info : keyctl_pkey_query ) -> Self {
365
+ KeySupportInfo {
366
+ supported_ops : c_info. supported_ops ,
367
+ key_size : c_info. key_size ,
368
+ max_data_size : c_info. max_data_size ,
369
+ max_sig_size : c_info. max_sig_size ,
370
+ max_enc_size : c_info. max_enc_size ,
371
+ max_dec_size : c_info. max_dec_size ,
372
+ }
373
+ }
374
+ }
375
+
376
+ /// Encodings supported by the kernel.
377
+ pub enum KeyctlEncoding {
378
+ RSASSA_PKCS1_v1_5 ,
379
+ RSAES_PKCS1_v1_5 ,
380
+ RSASSA_PSS ,
381
+ RSAES_OAEP ,
382
+ /// For extensibility.
383
+ OtherEncoding ( String ) ,
384
+ }
385
+
386
+ impl KeyctlEncoding {
387
+ fn encoding ( & self ) -> & str {
388
+ match * self {
389
+ KeyctlEncoding :: RSASSA_PKCS1_v1_5 => "pkcs1" ,
390
+ KeyctlEncoding :: RSAES_PKCS1_v1_5 => "pkcs1" ,
391
+ KeyctlEncoding :: RSASSA_PSS => "pss" ,
392
+ KeyctlEncoding :: RSAES_OAEP => "oaep" ,
393
+ KeyctlEncoding :: OtherEncoding ( ref s) => & s,
394
+ }
395
+ }
396
+ }
397
+
398
+ /// Hashes supported by the kernel.
399
+ pub enum KeyctlHash {
400
+ MD4 ,
401
+ MD5 ,
402
+ SHA1 ,
403
+ SHA224 ,
404
+ SHA256 ,
405
+ SHA384 ,
406
+ SHA512 ,
407
+ RIPE_MD_128 ,
408
+ RIPE_MD_160 ,
409
+ RIPE_MD_256 ,
410
+ RIPE_MD_320 ,
411
+ WP_256 ,
412
+ WP_384 ,
413
+ WP_512 ,
414
+ TGR_128 ,
415
+ TGR_160 ,
416
+ TGR_192 ,
417
+ SM3_256 ,
418
+ /// For extensibility.
419
+ OtherEncoding ( String ) ,
420
+ }
421
+
422
+ impl KeyctlHash {
423
+ fn hash ( & self ) -> & str {
424
+ match * self {
425
+ KeyctlHash :: MD4 => "md4" ,
426
+ KeyctlHash :: MD5 => "md5" ,
427
+ KeyctlHash :: SHA1 => "sha1" ,
428
+ KeyctlHash :: SHA224 => "sha224" ,
429
+ KeyctlHash :: SHA256 => "sha256" ,
430
+ KeyctlHash :: SHA384 => "sha384" ,
431
+ KeyctlHash :: SHA512 => "sha512" ,
432
+ KeyctlHash :: RIPE_MD_128 => "rmd128" ,
433
+ KeyctlHash :: RIPE_MD_160 => "rmd160" ,
434
+ KeyctlHash :: RIPE_MD_256 => "rmd256" ,
435
+ KeyctlHash :: RIPE_MD_320 => "rmd320" ,
436
+ KeyctlHash :: WP_256 => "wp256" ,
437
+ KeyctlHash :: WP_384 => "wp384" ,
438
+ KeyctlHash :: WP_512 => "wp512" ,
439
+ KeyctlHash :: TGR_128 => "tgr128" ,
440
+ KeyctlHash :: TGR_160 => "tgr160" ,
441
+ KeyctlHash :: TGR_192 => "tgr192" ,
442
+ KeyctlHash :: SM3_256 => "sm3-256" ,
443
+ KeyctlHash :: OtherEncoding ( ref s) => & s,
444
+ }
445
+ }
446
+ }
447
+
448
+ /// Options for output from public key functions (encryption, decryption, signing, and verifying).
449
+ pub struct PublicKeyOptions {
450
+ /// The encoding of the encrypted blob or the signature.
451
+ pub encoding : Option < KeyctlEncoding > ,
452
+ /// Hash algorithm to use (if the encoding uses it).
453
+ pub hash : Option < KeyctlHash > ,
454
+ }
455
+
456
+ impl PublicKeyOptions {
457
+ fn info ( & self ) -> String {
458
+ let options = [
459
+ ( "enc" , self . encoding . as_ref ( ) . map ( KeyctlEncoding :: encoding) ) ,
460
+ ( "hash" , self . hash . as_ref ( ) . map ( KeyctlHash :: hash) ) ,
461
+ ] . iter ( ) . map ( |& ( key, value) | {
462
+ value. map_or_else ( String :: new,
463
+ |v| format ! ( "{}={}" , key, v) )
464
+ } ) . collect :: < Vec < _ > > ( ) ;
465
+ options. join ( " " ) . trim ( ) . to_owned ( )
466
+ }
467
+ }
468
+
347
469
impl Key {
348
470
/// Requests a key with the given description by searching the thread, process, and session
349
471
/// keyrings.
@@ -445,12 +567,61 @@ impl Key {
445
567
446
568
/// Compute a Diffie-Hellman prime for use as a shared secret or public key.
447
569
pub fn compute_dh ( private : & Key , prime : & Key , base : & Key ) -> Result < Vec < u8 > > {
448
- let sz = try!( check_call_ret ( unsafe { keyctl_dh_compute ( private. id , prime. id , base. id , ptr:: null ( ) as * mut libc:: c_char , 0 ) } ) ) ;
570
+ let sz = try!( check_call_ret ( unsafe { keyctl_dh_compute ( private. id , prime. id , base. id , ptr:: null_mut ( ) as * mut libc:: c_char , 0 ) } ) ) ;
449
571
let mut buffer = Vec :: with_capacity ( sz as usize ) ;
450
572
let actual_sz = try!( check_call_ret ( unsafe { keyctl_dh_compute ( private. id , prime. id , base. id , buffer. as_mut_ptr ( ) as * mut libc:: c_char , sz as usize ) } ) ) ;
451
573
unsafe { buffer. set_len ( actual_sz as usize ) } ;
452
574
Ok ( buffer)
453
575
}
576
+
577
+ /// Query which optionally supported features may be used by the key.
578
+ pub fn query_support ( & self , password : & Option < Key > ) -> Result < KeySupportInfo > {
579
+ let mut info = keyctl_pkey_query:: new ( ) ;
580
+ let password_id = password. as_ref ( ) . map_or ( 0 , |pass| pass. id ) ;
581
+ try!( check_call_ret ( unsafe { keyctl_pkey_query ( self . id , password_id, & mut info) } ) ) ;
582
+ Ok ( KeySupportInfo :: from_c ( info) )
583
+ }
584
+
585
+ /// Encrypt data using the key.
586
+ pub fn encrypt ( & self , password : & Option < Key > , options : & PublicKeyOptions , data : & [ u8 ] ) -> Result < Vec < u8 > > {
587
+ let password_id = password. as_ref ( ) . map_or ( 0 , |pass| pass. id ) ;
588
+ let info_cstr = CString :: new ( options. info ( ) ) . unwrap ( ) ;
589
+ let sz = try!( self . query_support ( password) ) . max_enc_size ;
590
+ let mut buffer = Vec :: with_capacity ( sz as usize ) ;
591
+ let actual_sz = try!( check_call_ret ( unsafe { keyctl_pkey_encrypt ( self . id , password_id, info_cstr. as_ptr ( ) , data. as_ptr ( ) as * const libc:: c_void , data. len ( ) , buffer. as_mut_ptr ( ) as * mut libc:: c_void , buffer. len ( ) ) } ) ) ;
592
+ unsafe { buffer. set_len ( actual_sz as usize ) } ;
593
+ Ok ( buffer)
594
+ }
595
+
596
+ /// Decrypt data using the key.
597
+ pub fn decrypt ( & self , password : & Option < Key > , options : & PublicKeyOptions , data : & [ u8 ] ) -> Result < Vec < u8 > > {
598
+ let password_id = password. as_ref ( ) . map_or ( 0 , |pass| pass. id ) ;
599
+ let info_cstr = CString :: new ( options. info ( ) ) . unwrap ( ) ;
600
+ let sz = try!( self . query_support ( password) ) . max_dec_size ;
601
+ let mut buffer = Vec :: with_capacity ( sz as usize ) ;
602
+ let actual_sz = try!( check_call_ret ( unsafe { keyctl_pkey_decrypt ( self . id , password_id, info_cstr. as_ptr ( ) , data. as_ptr ( ) as * const libc:: c_void , data. len ( ) , buffer. as_mut_ptr ( ) as * mut libc:: c_void , buffer. len ( ) ) } ) ) ;
603
+ unsafe { buffer. set_len ( actual_sz as usize ) } ;
604
+ Ok ( buffer)
605
+ }
606
+
607
+ /// Sign data using the key.
608
+ pub fn sign ( & self , password : & Option < Key > , options : & PublicKeyOptions , data : & [ u8 ] ) -> Result < Vec < u8 > > {
609
+ let password_id = password. as_ref ( ) . map_or ( 0 , |pass| pass. id ) ;
610
+ let info_cstr = CString :: new ( options. info ( ) ) . unwrap ( ) ;
611
+ let sz = try!( self . query_support ( password) ) . max_sig_size ;
612
+ let mut buffer = Vec :: with_capacity ( sz as usize ) ;
613
+ let actual_sz = try!( check_call_ret ( unsafe { keyctl_pkey_sign ( self . id , password_id, info_cstr. as_ptr ( ) , data. as_ptr ( ) as * const libc:: c_void , data. len ( ) , buffer. as_mut_ptr ( ) as * mut libc:: c_void , buffer. len ( ) ) } ) ) ;
614
+ unsafe { buffer. set_len ( actual_sz as usize ) } ;
615
+ Ok ( buffer)
616
+ }
617
+
618
+ /// Verify a signature of the data using the key.
619
+ pub fn verify ( & self , password : & Option < Key > , options : & PublicKeyOptions , data : & [ u8 ] , signature : & [ u8 ] ) -> Result < bool > {
620
+ let password_id = password. as_ref ( ) . map_or ( 0 , |pass| pass. id ) ;
621
+ let info_cstr = CString :: new ( options. info ( ) ) . unwrap ( ) ;
622
+ let res = try!( check_call_ret ( unsafe { keyctl_pkey_sign ( self . id , password_id, info_cstr. as_ptr ( ) , data. as_ptr ( ) as * const libc:: c_void , data. len ( ) , signature. as_ptr ( ) as * mut libc:: c_void , signature. len ( ) ) } ) ) ;
623
+ Ok ( res == 0 )
624
+ }
454
625
}
455
626
456
627
/// Structure representing the metadata about a key or keyring.
0 commit comments