@@ -35,7 +35,7 @@ use keyutils_raw::*;
3535use log:: error;
3636use uninit:: extension_traits:: VecCapacity ;
3737
38- use crate :: constants:: { Permission , SpecialKeyring } ;
38+ use crate :: constants:: { KeyctlSupportFlags , Permission , SpecialKeyring } ;
3939use crate :: keytype:: * ;
4040use crate :: keytypes;
4141
@@ -511,6 +511,64 @@ pub struct Key {
511511 id : KeyringSerial ,
512512}
513513
514+ /// Structure to store results from a query on optional feature support for a key.
515+ #[ derive( Debug , Clone , Copy ) ]
516+ pub struct KeySupportInfo {
517+ /// Features supported by the key.
518+ pub supported_ops : KeyctlSupportFlags ,
519+ /// The size of the key (in bits).
520+ pub key_size : u32 ,
521+ /// The maximum size of a data blob which may be signed.
522+ pub max_data_size : u16 ,
523+ /// The maximum size of a signature blob.
524+ pub max_sig_size : u16 ,
525+ /// The maximum size of a blob to be encrypted.
526+ pub max_enc_size : u16 ,
527+ /// The maximum size of a blob to be decrypted.
528+ pub max_dec_size : u16 ,
529+ }
530+
531+ impl KeySupportInfo {
532+ fn from_c ( c_info : PKeyQuery ) -> Self {
533+ KeySupportInfo {
534+ supported_ops : c_info. supported_ops ,
535+ key_size : c_info. key_size ,
536+ max_data_size : c_info. max_data_size ,
537+ max_sig_size : c_info. max_sig_size ,
538+ max_enc_size : c_info. max_enc_size ,
539+ max_dec_size : c_info. max_dec_size ,
540+ }
541+ }
542+ }
543+
544+ /// Encodings supported by the kernel.
545+ #[ derive( Debug , Clone ) ]
546+ // #[non_exhaustive]
547+ pub enum KeyctlEncoding {
548+ /// The RSASSA-PKCS1-v1.5 encoding.
549+ RsassaPkcs1V15 ,
550+ /// The RSAES-PKCS1-v1.5 encoding.
551+ RsaesPkcs1V15 ,
552+ /// The RSASSA-PSS encoding.
553+ RsassaPss ,
554+ /// The RSAES-OAEP encoding.
555+ RsaesOaep ,
556+ /// For extensibility.
557+ OtherEncoding ( Cow < ' static , str > ) ,
558+ }
559+
560+ impl KeyctlEncoding {
561+ fn encoding ( & self ) -> & str {
562+ match * self {
563+ KeyctlEncoding :: RsassaPkcs1V15 => "pkcs1" ,
564+ KeyctlEncoding :: RsaesPkcs1V15 => "pkcs1" ,
565+ KeyctlEncoding :: RsassaPss => "pss" ,
566+ KeyctlEncoding :: RsaesOaep => "oaep" ,
567+ KeyctlEncoding :: OtherEncoding ( ref s) => & s,
568+ }
569+ }
570+ }
571+
514572/// Hashes supported by the kernel.
515573#[ derive( Debug , Clone ) ]
516574// #[non_exhaustive]
@@ -581,6 +639,28 @@ impl KeyctlHash {
581639 }
582640}
583641
642+ /// Options for output from public key functions (encryption, decryption, signing, and verifying).
643+ #[ derive( Debug , Clone ) ]
644+ pub struct PublicKeyOptions {
645+ /// The encoding of the encrypted blob or the signature.
646+ pub encoding : Option < KeyctlEncoding > ,
647+ /// Hash algorithm to use (if the encoding uses it).
648+ pub hash : Option < KeyctlHash > ,
649+ }
650+
651+ impl PublicKeyOptions {
652+ fn info ( & self ) -> String {
653+ let options = [
654+ ( "enc" , self . encoding . as_ref ( ) . map ( KeyctlEncoding :: encoding) ) ,
655+ ( "hash" , self . hash . as_ref ( ) . map ( KeyctlHash :: hash) ) ,
656+ ]
657+ . iter ( )
658+ . map ( |& ( key, value) | value. map_or_else ( String :: new, |v| format ! ( "{}={}" , key, v) ) )
659+ . collect :: < Vec < _ > > ( ) ;
660+ options. join ( " " ) . trim ( ) . to_owned ( )
661+ }
662+ }
663+
584664impl Key {
585665 /// Instantiate a key from an ID.
586666 ///
@@ -814,6 +894,60 @@ impl Key {
814894 buffer. truncate ( sz) ;
815895 Ok ( buffer)
816896 }
897+
898+ fn pkey_query_support_impl ( & self , info : & str ) -> Result < PKeyQuery > {
899+ keyctl_pkey_query ( self . id , info)
900+ }
901+
902+ /// Query which optionally supported features may be used by the key.
903+ pub fn pkey_query_support ( & self , query : & PublicKeyOptions ) -> Result < KeySupportInfo > {
904+ let info = query. info ( ) ;
905+ self . pkey_query_support_impl ( & info)
906+ . map ( KeySupportInfo :: from_c)
907+ }
908+
909+ /// Encrypt data using the key.
910+ pub fn encrypt ( & self , options : & PublicKeyOptions , data : & [ u8 ] ) -> Result < Vec < u8 > > {
911+ let info = options. info ( ) ;
912+ let support = self . pkey_query_support_impl ( & info) ?;
913+ let mut buffer = Vec :: with_capacity ( support. max_enc_size as usize ) ;
914+ let write_buffer = buffer. get_backing_buffer ( ) ;
915+ let sz = keyctl_pkey_encrypt ( self . id , & info, data, write_buffer) ?;
916+ buffer. truncate ( sz) ;
917+ Ok ( buffer)
918+ }
919+
920+ /// Decrypt data using the key.
921+ pub fn decrypt ( & self , options : & PublicKeyOptions , data : & [ u8 ] ) -> Result < Vec < u8 > > {
922+ let info = options. info ( ) ;
923+ let support = self . pkey_query_support_impl ( & info) ?;
924+ let mut buffer = Vec :: with_capacity ( support. max_dec_size as usize ) ;
925+ let write_buffer = buffer. get_backing_buffer ( ) ;
926+ let sz = keyctl_pkey_decrypt ( self . id , & info, data, write_buffer) ?;
927+ buffer. truncate ( sz) ;
928+ Ok ( buffer)
929+ }
930+
931+ /// Sign data using the key.
932+ pub fn sign ( & self , options : & PublicKeyOptions , data : & [ u8 ] ) -> Result < Vec < u8 > > {
933+ let info = options. info ( ) ;
934+ let support = self . pkey_query_support_impl ( & info) ?;
935+ let mut buffer = Vec :: with_capacity ( support. max_sig_size as usize ) ;
936+ let write_buffer = buffer. get_backing_buffer ( ) ;
937+ let sz = keyctl_pkey_sign ( self . id , & info, data, write_buffer) ?;
938+ buffer. truncate ( sz) ;
939+ Ok ( buffer)
940+ }
941+
942+ /// Verify a signature of the data using the key.
943+ pub fn verify (
944+ & self ,
945+ options : & PublicKeyOptions ,
946+ data : & [ u8 ] ,
947+ signature : & [ u8 ] ,
948+ ) -> Result < bool > {
949+ keyctl_pkey_verify ( self . id , & options. info ( ) , data, signature)
950+ }
817951}
818952
819953/// Structure representing the metadata about a key or keyring.
0 commit comments