@@ -26,7 +26,7 @@ use aes_gcm::KeyInit;
2626use aes_siv:: { siv:: CmacSiv , Aes256SivAead } ;
2727
2828use cloudkit_proto:: CuttlefishEstablishResponse ;
29- use crate :: { TokenProvider , cloudkit:: { SaveRecordOperation , ZoneDeleteOperation , ZoneSaveOperation , record_identifier, should_reset} , keychain, pcs:: PCSKey } ;
29+ use crate :: { TokenProvider , cloudkit:: { DeleteRecordOperation , SaveRecordOperation , ZoneDeleteOperation , ZoneSaveOperation , record_identifier, should_reset} , keychain, pcs:: PCSKey , util :: { ec_key_from_apple , ec_key_to_apple } } ;
3030use aes:: { cipher:: { consts:: { U12 , U16 , U32 } , Unsigned } , Aes128 , Aes256 } ;
3131use sha2:: { digest:: FixedOutputReset , Digest , Sha256 , Sha384 } ;
3232use srp:: { client:: { SrpClient , SrpClientVerifier } , groups:: G_2048 , server:: SrpServer } ;
@@ -181,7 +181,6 @@ impl CuttlefishEncItem {
181181 self . parentkeyref . record_identifier . as_ref ( ) . unwrap ( ) . value . as_ref ( ) . unwrap ( ) . name ( )
182182 }
183183
184- // TODO not secure for raw passwords length, padding is lazy. Only cryptographic keys for now
185184 fn encrypt ( & mut self , uuid : & str , key : & SivKey , data : Dictionary ) -> Result < ( ) , PushError > {
186185 let record_key: [ u8 ; 64 ] = rand:: random ( ) ;
187186 self . wrappedkey = base64_encode ( & key. encrypt ( & record_key) ) ;
@@ -195,8 +194,15 @@ impl CuttlefishEncItem {
195194 headers. extend ( aad. into_values ( ) ) ;
196195
197196 let mut data = plist_to_bin ( & data) ?;
198- data. push ( 0x80 ) ; // lazy padding
199- data. push ( 0x00 ) ;
197+ data. push ( 0x80 ) ;
198+
199+ const BLOCK_PAD_SIZE : usize = 20 ;
200+ let mut blocks = ( data. len ( ) + ( BLOCK_PAD_SIZE - 1 ) ) / BLOCK_PAD_SIZE ;
201+ if blocks == 1 {
202+ blocks += 1 ;
203+ }
204+
205+ data. resize ( blocks * BLOCK_PAD_SIZE , 0 ) ;
200206
201207 let data = cipher. encrypt :: < & [ Vec < u8 > ] , & Vec < u8 > > ( & headers, & data) . unwrap ( ) ;
202208 self . data = [ & iv[ ..] , & data] . concat ( ) ;
@@ -425,21 +431,6 @@ fn msg_from_bin(bin: &[u8], header_len: usize, section_count: usize) -> (Vec<u8>
425431 ( header, offsets. collect ( ) )
426432}
427433
428- fn ec_key_from_apple ( apple : & [ u8 ] ) -> EcKey < Private > {
429- let curve = EcGroup :: from_curve_name ( Nid :: SECP384R1 ) . unwrap ( ) ;
430- let mut num_context_ref = BigNumContext :: new ( ) . unwrap ( ) ;
431- let main_point = EcPoint :: from_bytes ( & curve, & apple[ ..97 ] , & mut num_context_ref) . unwrap ( ) ;
432- EcKey :: from_private_components ( & curve, & BigNum :: from_slice ( & apple[ 97 ..] ) . unwrap ( ) , & main_point) . unwrap ( )
433- }
434-
435- fn ec_key_to_apple ( key : & EcKey < Private > ) -> Vec < u8 > {
436- let mut num_context_ref = BigNumContext :: new ( ) . unwrap ( ) ;
437- let mut point = key. public_key ( ) . to_bytes ( & key. group ( ) , PointConversionForm :: UNCOMPRESSED , & mut num_context_ref) . unwrap ( ) ;
438- assert_eq ! ( point. len( ) , 97 ) ;
439- point. extend ( key. private_key ( ) . to_vec ( ) ) ;
440- point
441- }
442-
443434struct KeyVaultMessage {
444435 header : Vec < u8 > ,
445436 sections : Vec < Vec < u8 > > ,
@@ -1256,6 +1247,21 @@ impl<P: AnisetteProvider> KeychainClient<P> {
12561247
12571248 Ok ( ( ) )
12581249 }
1250+
1251+ pub async fn delete_keychain ( & self , uuid : & str , zone : & str ) -> Result < ( ) , PushError > {
1252+ let security_container = self . get_security_container ( ) . await ?;
1253+ let record_zone = security_container. private_zone ( zone. to_string ( ) ) ;
1254+
1255+ security_container. perform ( & CloudKitSession :: new ( ) , DeleteRecordOperation :: new ( record_identifier ( record_zone, uuid) ) ) . await ?;
1256+
1257+ let mut state = self . state . write ( ) . await ;
1258+ let zone = state. items . entry ( zone. to_string ( ) ) . or_default ( ) ;
1259+ zone. keys . remove ( uuid) ;
1260+
1261+ ( self . update_state ) ( & state) ;
1262+
1263+ Ok ( ( ) )
1264+ }
12591265
12601266 pub async fn insert_keychain ( & self , uuid : & str , zone : & str , class : & str , mut dict : Dictionary , pcs : Option < & PCSMeta > , associated_tag : Option < & str > ) -> Result < ( ) , PushError > {
12611267 let security_container = self . get_security_container ( ) . await ?;
@@ -1287,7 +1293,7 @@ impl<P: AnisetteProvider> KeychainClient<P> {
12871293 item. encrypt ( & uuid, & key. decode ( & state. get_cloudkey_access_key ( ) ?) , dict. clone ( ) ) ?;
12881294
12891295 let mut ops = vec ! [ SaveRecordOperation :: new(
1290- record_identifier( record_zone. clone( ) , & uuid) , item, None , false ) ] ;
1296+ record_identifier( record_zone. clone( ) , & uuid) , item, None , true ) ] ;
12911297
12921298 if let Some ( tag) = associated_tag {
12931299 ops. push ( SaveRecordOperation :: new ( record_identifier ( record_zone. clone ( ) , tag) , CuttlefishCurrentItem {
@@ -1684,13 +1690,15 @@ impl<P: AnisetteProvider> KeychainClient<P> {
16841690 & * [ & cipertext. ciphertext ( ) [ ..] , & cipertext. authentication_code ( ) [ ..] ] . concat ( ) ) . map_err ( |_| PushError :: AESGCMError ) ?;
16851691
16861692 let decoded = OtInternalBottle :: decode ( Cursor :: new ( & result) ) ?;
1693+
1694+ let key_group = EcGroup :: from_curve_name ( Nid :: SECP384R1 ) . unwrap ( ) ;
16871695
16881696 // reconstruct a keychain identity for our other peer
16891697 Ok ( KeychainUserIdentity {
16901698 identifier : outer_bottle. peer_id ( ) . to_string ( ) ,
16911699 info : peer. 0 . permanent_info . clone ( ) . unwrap ( ) ,
1692- signing_key : SoftEcKey ( ec_key_from_apple ( decoded. signing_key . as_ref ( ) . unwrap ( ) . key_data . as_ref ( ) . unwrap ( ) ) ) ,
1693- encryption_key : SoftEcKey ( ec_key_from_apple ( decoded. encryption_key . as_ref ( ) . unwrap ( ) . key_data . as_ref ( ) . unwrap ( ) ) ) ,
1700+ signing_key : SoftEcKey ( ec_key_from_apple ( decoded. signing_key . as_ref ( ) . unwrap ( ) . key_data . as_ref ( ) . unwrap ( ) , & key_group ) ) ,
1701+ encryption_key : SoftEcKey ( ec_key_from_apple ( decoded. encryption_key . as_ref ( ) . unwrap ( ) . key_data . as_ref ( ) . unwrap ( ) , & key_group ) ) ,
16941702 current_state : peer. get_dynamic_info ( ) ?,
16951703 } )
16961704 }
0 commit comments