1212import org .cryptomator .cloudaccess .api .exceptions .VaultVerificationFailedException ;
1313import org .cryptomator .cloudaccess .api .exceptions .VaultVersionVerificationFailedException ;
1414import org .junit .jupiter .api .Assertions ;
15+ import org .junit .jupiter .api .Assumptions ;
1516import org .junit .jupiter .api .BeforeEach ;
17+ import org .junit .jupiter .api .DisplayName ;
18+ import org .junit .jupiter .api .Nested ;
1619import org .junit .jupiter .api .Test ;
1720import org .junit .jupiter .api .io .TempDir ;
1821
@@ -31,53 +34,70 @@ public class VaultFormat8IntegrationTest {
3134 private static final Duration TIMEOUT = Duration .ofMillis (100 );
3235
3336 private CloudProvider localProvider ;
34- private CloudProvider encryptedProvider ;
3537
3638 @ BeforeEach
3739 public void setup (@ TempDir Path tmpDir ) throws IOException {
3840 this .localProvider = CloudAccess .toLocalFileSystem (tmpDir );
39- var in = getClass ().getResourceAsStream ("/vaultconfig.jwt" );
40- localProvider .write (CloudPath .of ("/vaultconfig.jwt" ), false , in , in .available (), Optional .empty (), ProgressListener .NO_PROGRESS_AWARE ).toCompletableFuture ().join ();
41- this .encryptedProvider = CloudAccess .vaultFormat8GCMCloudAccess (localProvider , CloudPath .of ("/" ), new byte [64 ]);
4241 }
4342
44- @ Test
45- public void testWriteThenReadFile () throws IOException {
46- var path = CloudPath .of ("/file.txt" );
47- var content = new byte [100_000 ];
48- new Random (42l ).nextBytes (content );
49-
50- // write 100k
51- var futureMetadata = encryptedProvider .write (path , true , new ByteArrayInputStream (content ), content .length , Optional .empty (), ProgressListener .NO_PROGRESS_AWARE );
52- Assertions .assertTimeoutPreemptively (TIMEOUT , () -> futureMetadata .toCompletableFuture ().get ());
53-
54- // read all bytes
55- var futureInputStream1 = encryptedProvider .read (path , ProgressListener .NO_PROGRESS_AWARE );
56- var inputStream1 = Assertions .assertTimeoutPreemptively (TIMEOUT , () -> futureInputStream1 .toCompletableFuture ().get ());
57- Assertions .assertArrayEquals (content , inputStream1 .readAllBytes ());
58-
59- // read partially
60- var futureInputStream2 = encryptedProvider .read (path , 2000 , 15000 , ProgressListener .NO_PROGRESS_AWARE );
61- var inputStream2 = Assertions .assertTimeoutPreemptively (TIMEOUT , () -> futureInputStream2 .toCompletableFuture ().get ());
62- Assertions .assertArrayEquals (Arrays .copyOfRange (content , 2000 , 17000 ), inputStream2 .readAllBytes ());
43+ @ Nested
44+ @ DisplayName ("with valid /vaultconfig.jwt" )
45+ public class WithInitializedVaultConfig {
46+
47+ private CloudProvider encryptedProvider ;
48+
49+ @ BeforeEach
50+ public void setup () throws IOException {
51+ var in = getClass ().getResourceAsStream ("/vaultconfig.jwt" );
52+ localProvider .write (CloudPath .of ("/vaultconfig.jwt" ), false , in , in .available (), Optional .empty (), ProgressListener .NO_PROGRESS_AWARE ).toCompletableFuture ().join ();
53+ this .encryptedProvider = CloudAccess .vaultFormat8GCMCloudAccess (localProvider , CloudPath .of ("/" ), new byte [64 ]);
54+ }
55+
56+ @ Test
57+ @ DisplayName ("read and write through encryption decorator" )
58+ public void testWriteThenReadFile () throws IOException {
59+ var path = CloudPath .of ("/file.txt" );
60+ var content = new byte [100_000 ];
61+ new Random (42l ).nextBytes (content );
62+
63+ // write 100k
64+ var futureMetadata = encryptedProvider .write (path , true , new ByteArrayInputStream (content ), content .length , Optional .empty (), ProgressListener .NO_PROGRESS_AWARE );
65+ Assertions .assertTimeoutPreemptively (TIMEOUT , () -> futureMetadata .toCompletableFuture ().get ());
66+
67+ // read all bytes
68+ var futureInputStream1 = encryptedProvider .read (path , ProgressListener .NO_PROGRESS_AWARE );
69+ var inputStream1 = Assertions .assertTimeoutPreemptively (TIMEOUT , () -> futureInputStream1 .toCompletableFuture ().get ());
70+ Assertions .assertArrayEquals (content , inputStream1 .readAllBytes ());
71+
72+ // read partially
73+ var futureInputStream2 = encryptedProvider .read (path , 2000 , 15000 , ProgressListener .NO_PROGRESS_AWARE );
74+ var inputStream2 = Assertions .assertTimeoutPreemptively (TIMEOUT , () -> futureInputStream2 .toCompletableFuture ().get ());
75+ Assertions .assertArrayEquals (Arrays .copyOfRange (content , 2000 , 17000 ), inputStream2 .readAllBytes ());
76+ }
77+
6378 }
6479
6580 @ Test
81+ @ DisplayName ("init with missing /vaultconfig.jwt fails" )
6682 public void testInstantiateFormat8GCMCloudAccessWithoutVaultConfigFile () {
67- localProvider .deleteFile (CloudPath .of ("/vaultconfig.jwt" ));
83+ Assumptions .assumeFalse (localProvider .exists (CloudPath .of ("/vaultconfig.jwt" )).toCompletableFuture ().join ());
84+
6885 var exception = Assertions .assertThrows (CloudProviderException .class , () -> CloudAccess .vaultFormat8GCMCloudAccess (localProvider , CloudPath .of ("/" ), new byte [64 ]));
6986 Assertions .assertTrue (exception .getCause () instanceof NotFoundException );
7087 }
7188
7289 @ Test
90+ @ DisplayName ("init with wrong format" )
7391 public void testInstantiateFormat8GCMCloudAccessWithWrongVaultVersion () {
74- localProvider .deleteFile (CloudPath .of ("/vaultconfig.jwt" ));
92+ Assumptions .assumeFalse (localProvider .exists (CloudPath .of ("/vaultconfig.jwt" )).toCompletableFuture ().join ());
93+
7594 byte [] masterkey = new byte [64 ];
7695 Algorithm algorithm = Algorithm .HMAC256 (masterkey );
7796 var token = JWT .create ()
7897 .withJWTId (UUID .randomUUID ().toString ())
7998 .withClaim ("format" , 9 )
8099 .withClaim ("cipherCombo" , "SIV_GCM" )
100+ .withClaim ("shorteningThreshold" , Integer .MAX_VALUE )
81101 .sign (algorithm );
82102 var in = new ByteArrayInputStream (token .getBytes (StandardCharsets .US_ASCII ));
83103 localProvider .write (CloudPath .of ("/vaultconfig.jwt" ), false , in , in .available (), Optional .empty (), ProgressListener .NO_PROGRESS_AWARE ).toCompletableFuture ().join ();
@@ -86,14 +106,17 @@ public void testInstantiateFormat8GCMCloudAccessWithWrongVaultVersion() {
86106 }
87107
88108 @ Test
109+ @ DisplayName ("init with invalid cipherCombo fails" )
89110 public void testInstantiateFormat8GCMCloudAccessWithWrongCiphermode () {
90- localProvider .deleteFile (CloudPath .of ("/vaultconfig.jwt" ));
111+ Assumptions .assumeFalse (localProvider .exists (CloudPath .of ("/vaultconfig.jwt" )).toCompletableFuture ().join ());
112+
91113 byte [] masterkey = new byte [64 ];
92114 Algorithm algorithm = Algorithm .HMAC256 (masterkey );
93115 var token = JWT .create ()
94116 .withJWTId (UUID .randomUUID ().toString ())
95117 .withClaim ("format" , 8 )
96118 .withClaim ("cipherCombo" , "FOO" )
119+ .withClaim ("shorteningThreshold" , Integer .MAX_VALUE )
97120 .sign (algorithm );
98121 var in = new ByteArrayInputStream (token .getBytes (StandardCharsets .US_ASCII ));
99122 localProvider .write (CloudPath .of ("/vaultconfig.jwt" ), false , in , in .available (), Optional .empty (), ProgressListener .NO_PROGRESS_AWARE ).toCompletableFuture ().join ();
@@ -102,20 +125,42 @@ public void testInstantiateFormat8GCMCloudAccessWithWrongCiphermode() {
102125 }
103126
104127 @ Test
128+ @ DisplayName ("init with wrong key" )
105129 public void testInstantiateFormat8GCMCloudAccessWithWrongKey () {
106- localProvider .deleteFile (CloudPath .of ("/vaultconfig.jwt" ));
130+ Assumptions .assumeFalse (localProvider .exists (CloudPath .of ("/vaultconfig.jwt" )).toCompletableFuture ().join ());
131+
107132 byte [] masterkey = new byte [64 ];
108133 Arrays .fill (masterkey , (byte ) 15 );
109134 Algorithm algorithm = Algorithm .HMAC256 (masterkey );
110135 var token = JWT .create ()
111136 .withJWTId (UUID .randomUUID ().toString ())
112137 .withClaim ("format" , 8 )
113- .withClaim ("cipherCombo" , "FOO" )
138+ .withClaim ("cipherCombo" , "SIV_GCM" )
139+ .withClaim ("shorteningThreshold" , Integer .MAX_VALUE )
114140 .sign (algorithm );
115141 var in = new ByteArrayInputStream (token .getBytes (StandardCharsets .US_ASCII ));
116142 localProvider .write (CloudPath .of ("/vaultconfig.jwt" ), false , in , in .available (), Optional .empty (), ProgressListener .NO_PROGRESS_AWARE ).toCompletableFuture ().join ();
117143
118144 Assertions .assertThrows (VaultKeyVerificationFailedException .class , () -> CloudAccess .vaultFormat8GCMCloudAccess (localProvider , CloudPath .of ("/" ), new byte [64 ]));
119145 }
120146
147+ @ Test
148+ @ DisplayName ("init with shorteningThreshold" )
149+ public void testInstantiateFormat8GCMCloudAccessWithShortening () {
150+ Assumptions .assumeFalse (localProvider .exists (CloudPath .of ("/vaultconfig.jwt" )).toCompletableFuture ().join ());
151+
152+ byte [] masterkey = new byte [64 ];
153+ Algorithm algorithm = Algorithm .HMAC256 (masterkey );
154+ var token = JWT .create ()
155+ .withJWTId (UUID .randomUUID ().toString ())
156+ .withClaim ("format" , 8 )
157+ .withClaim ("cipherCombo" , "SIV_GCM" )
158+ .withClaim ("shorteningThreshold" , 42 )
159+ .sign (algorithm );
160+ var in = new ByteArrayInputStream (token .getBytes (StandardCharsets .US_ASCII ));
161+ localProvider .write (CloudPath .of ("/vaultconfig.jwt" ), false , in , in .available (), Optional .empty (), ProgressListener .NO_PROGRESS_AWARE ).toCompletableFuture ().join ();
162+
163+ Assertions .assertThrows (VaultVerificationFailedException .class , () -> CloudAccess .vaultFormat8GCMCloudAccess (localProvider , CloudPath .of ("/" ), new byte [64 ]));
164+ }
165+
121166}
0 commit comments