@@ -826,3 +826,113 @@ fn connection_fails_encoder_returned_too_long() {
826826
827827 connect_fail ( & mut client, & mut server) ;
828828}
829+
830+ fn connected_pair ( ) -> ( Client , Server ) {
831+ fixture_init ( ) ;
832+ let mut client = Client :: new ( "server.example" , true ) . expect ( "should create client" ) ;
833+ let mut server = Server :: new ( & [ "key" ] ) . expect ( "should create server" ) ;
834+ connect ( & mut client, & mut server) ;
835+ ( client, server)
836+ }
837+
838+ #[ test]
839+ fn export_keying_material_basic ( ) {
840+ let ( client, _server) = connected_pair ( ) ;
841+
842+ let material = client
843+ . export_keying_material ( b"EXPORTER-test" , & [ ] , 32 )
844+ . expect ( "should export keying material" ) ;
845+ assert_eq ! ( material. len( ) , 32 ) ;
846+ }
847+
848+ #[ test]
849+ fn export_keying_material_differs_across_connections ( ) {
850+ let label = b"EXPORTER-test" ;
851+ let context = b"context-data" ;
852+
853+ let ( client1, _server1) = connected_pair ( ) ;
854+ let material1 = client1
855+ . export_keying_material ( label, context, 32 )
856+ . expect ( "first connection export" ) ;
857+
858+ let ( client2, _server2) = connected_pair ( ) ;
859+ let material2 = client2
860+ . export_keying_material ( label, context, 32 )
861+ . expect ( "second connection export" ) ;
862+
863+ assert_ne ! (
864+ material1, material2,
865+ "Different connections should produce different keying material"
866+ ) ;
867+ }
868+
869+ #[ test]
870+ fn export_keying_material_different_labels ( ) {
871+ let ( client, _server) = connected_pair ( ) ;
872+
873+ let material1 = client
874+ . export_keying_material ( b"EXPORTER-test1" , & [ ] , 32 )
875+ . expect ( "export with label1" ) ;
876+ let material2 = client
877+ . export_keying_material ( b"EXPORTER-test2" , & [ ] , 32 )
878+ . expect ( "export with label2" ) ;
879+
880+ assert_eq ! ( material1. len( ) , 32 ) ;
881+ assert_eq ! ( material2. len( ) , 32 ) ;
882+ assert_ne ! (
883+ material1, material2,
884+ "Different labels should produce different output"
885+ ) ;
886+ }
887+
888+ #[ test]
889+ fn export_keying_material_different_contexts ( ) {
890+ let ( client, _server) = connected_pair ( ) ;
891+
892+ let material1 = client
893+ . export_keying_material ( b"EXPORTER-test" , b"context1" , 32 )
894+ . expect ( "export with context1" ) ;
895+ let material2 = client
896+ . export_keying_material ( b"EXPORTER-test" , b"context2" , 32 )
897+ . expect ( "export with context2" ) ;
898+
899+ assert_eq ! ( material1. len( ) , 32 ) ;
900+ assert_eq ! ( material2. len( ) , 32 ) ;
901+ assert_ne ! (
902+ material1, material2,
903+ "Different contexts should produce different output"
904+ ) ;
905+ }
906+
907+ #[ test]
908+ fn export_keying_material_before_handshake ( ) {
909+ fixture_init ( ) ;
910+ let client = Client :: new ( "server.example" , true ) . expect ( "should create client" ) ;
911+
912+ assert_eq ! (
913+ client
914+ . export_keying_material( b"EXPORTER-test" , & [ ] , 32 )
915+ . unwrap_err( ) ,
916+ Error :: InvalidState
917+ ) ;
918+ }
919+
920+ #[ test]
921+ fn export_keying_material_same_for_both_sides ( ) {
922+ let ( client, server) = connected_pair ( ) ;
923+
924+ let label = b"EXPORTER-test" ;
925+ let context = b"shared-context" ;
926+
927+ let client_material = client
928+ . export_keying_material ( label, context, 32 )
929+ . expect ( "client export" ) ;
930+ let server_material = server
931+ . export_keying_material ( label, context, 32 )
932+ . expect ( "server export" ) ;
933+
934+ assert_eq ! (
935+ client_material, server_material,
936+ "Both sides should export identical material"
937+ ) ;
938+ }
0 commit comments