1616
1717package com .google .cloud .spanner .omni ;
1818
19+ import static com .google .common .truth .Truth .assertThat ;
1920import static org .junit .Assert .assertEquals ;
2021import static org .junit .Assert .assertNotNull ;
2122import static org .junit .Assert .assertNull ;
@@ -41,99 +42,138 @@ public class DynamicKeyManagerTest {
4142 @ Test
4243 public void testInitialLoadAndDynamicRotation () throws Exception {
4344 SelfSignedCertificate ssc1 = new SelfSignedCertificate ("spanner.test.1" );
44- File certFile = tempFolder .newFile ("client.crt" );
45- File keyFile = tempFolder .newFile ("client.key" );
45+ SelfSignedCertificate ssc2 = new SelfSignedCertificate ("spanner.test.2" );
46+ try {
47+ File certFile = tempFolder .newFile ("client.crt" );
48+ File keyFile = tempFolder .newFile ("client.key" );
4649
47- Files .write (certFile .toPath (), Files .readAllBytes (ssc1 .certificate ().toPath ()));
48- Files .write (keyFile .toPath (), Files .readAllBytes (ssc1 .privateKey ().toPath ()));
50+ Files .write (certFile .toPath (), Files .readAllBytes (ssc1 .certificate ().toPath ()));
51+ Files .write (keyFile .toPath (), Files .readAllBytes (ssc1 .privateKey ().toPath ()));
4952
50- DynamicKeyManager keyManager = new DynamicKeyManager (certFile , keyFile , 0L );
53+ DynamicKeyManager keyManager = new DynamicKeyManager (certFile , keyFile , 0L );
5154
52- String alias1 = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
53- assertNotNull (alias1 );
54- assertEquals (alias1 , keyManager .chooseEngineClientAlias (new String [] {"RSA" }, null , null ));
55+ String alias1 = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
56+ assertNotNull (alias1 );
57+ assertEquals (alias1 , keyManager .chooseEngineClientAlias (new String [] {"RSA" }, null , null ));
5558
56- X509Certificate [] chain1 = keyManager .getCertificateChain (alias1 );
57- assertNotNull (chain1 );
58- assertEquals (1 , chain1 .length );
59- assertEquals (ssc1 .cert ().getSubjectDN (), chain1 [0 ].getSubjectDN ());
59+ X509Certificate [] chain1 = keyManager .getCertificateChain (alias1 );
60+ assertNotNull (chain1 );
61+ assertEquals (1 , chain1 .length );
62+ assertEquals (ssc1 .cert ().getSubjectDN (), chain1 [0 ].getSubjectDN ());
6063
61- PrivateKey pk1 = keyManager .getPrivateKey (alias1 );
62- assertNotNull (pk1 );
63- assertEquals (ssc1 .key ().getAlgorithm (), pk1 .getAlgorithm ());
64+ PrivateKey pk1 = keyManager .getPrivateKey (alias1 );
65+ assertNotNull (pk1 );
66+ assertEquals (ssc1 .key ().getAlgorithm (), pk1 .getAlgorithm ());
6467
65- String [] aliases1 = keyManager .getClientAliases ("RSA" , null );
66- assertNotNull (aliases1 );
67- assertEquals (1 , aliases1 .length );
68- assertEquals (alias1 , aliases1 [0 ]);
68+ String [] aliases1 = keyManager .getClientAliases ("RSA" , null );
69+ assertNotNull (aliases1 );
70+ assertEquals (1 , aliases1 .length );
71+ assertEquals (alias1 , aliases1 [0 ]);
6972
70- // Ensure lastModified timestamp changes upon rotation
71- Thread .sleep (1100 );
73+ // Ensure lastModified timestamp changes upon rotation
74+ Thread .sleep (1100 );
7275
73- SelfSignedCertificate ssc2 = new SelfSignedCertificate ("spanner.test.2" );
74- Files .write (certFile .toPath (), Files .readAllBytes (ssc2 .certificate ().toPath ()));
75- Files .write (keyFile .toPath (), Files .readAllBytes (ssc2 .privateKey ().toPath ()));
76+ Files .write (certFile .toPath (), Files .readAllBytes (ssc2 .certificate ().toPath ()));
77+ Files .write (keyFile .toPath (), Files .readAllBytes (ssc2 .privateKey ().toPath ()));
7678
77- String alias2 = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
78- assertNotNull (alias2 );
79+ String alias2 = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
80+ assertNotNull (alias2 );
7981
80- X509Certificate [] chain2 = keyManager .getCertificateChain (alias2 );
81- assertNotNull (chain2 );
82- assertEquals (ssc2 .cert ().getSubjectDN (), chain2 [0 ].getSubjectDN ());
82+ X509Certificate [] chain2 = keyManager .getCertificateChain (alias2 );
83+ assertNotNull (chain2 );
84+ assertEquals (ssc2 .cert ().getSubjectDN (), chain2 [0 ].getSubjectDN ());
8385
84- PrivateKey pk2 = keyManager .getPrivateKey (alias2 );
85- assertNotNull (pk2 );
86+ PrivateKey pk2 = keyManager .getPrivateKey (alias2 );
87+ assertNotNull (pk2 );
88+ } finally {
89+ ssc1 .delete ();
90+ ssc2 .delete ();
91+ }
8692 }
8793
8894 @ Test
8995 public void testFileCheckThrottling () throws Exception {
9096 SelfSignedCertificate ssc1 = new SelfSignedCertificate ("spanner.test.throttle1" );
91- File certFile = tempFolder .newFile ("client-throttle.crt" );
92- File keyFile = tempFolder .newFile ("client-throttle.key" );
93-
94- Files .write (certFile .toPath (), Files .readAllBytes (ssc1 .certificate ().toPath ()));
95- Files .write (keyFile .toPath (), Files .readAllBytes (ssc1 .privateKey ().toPath ()));
96-
97- // 60-second check interval
98- DynamicKeyManager keyManager = new DynamicKeyManager (certFile , keyFile , 60000L );
99-
100- String alias1 = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
101- assertEquals (
102- ssc1 .cert ().getSubjectDN (), keyManager .getCertificateChain (alias1 )[0 ].getSubjectDN ());
103-
104- // Rotate files immediately on disk
10597 SelfSignedCertificate ssc2 = new SelfSignedCertificate ("spanner.test.throttle2" );
106- Files .write (certFile .toPath (), Files .readAllBytes (ssc2 .certificate ().toPath ()));
107- Files .write (keyFile .toPath (), Files .readAllBytes (ssc2 .privateKey ().toPath ()));
108-
109- // Within the throttle interval, the manager should retain and return previous certificate
110- assertEquals (
111- ssc1 .cert ().getSubjectDN (), keyManager .getCertificateChain (alias1 )[0 ].getSubjectDN ());
98+ try {
99+ File certFile = tempFolder .newFile ("client-throttle.crt" );
100+ File keyFile = tempFolder .newFile ("client-throttle.key" );
101+
102+ Files .write (certFile .toPath (), Files .readAllBytes (ssc1 .certificate ().toPath ()));
103+ Files .write (keyFile .toPath (), Files .readAllBytes (ssc1 .privateKey ().toPath ()));
104+
105+ // 60-second check interval
106+ DynamicKeyManager keyManager = new DynamicKeyManager (certFile , keyFile , 60000L );
107+
108+ String alias1 = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
109+ assertEquals (
110+ ssc1 .cert ().getSubjectDN (), keyManager .getCertificateChain (alias1 )[0 ].getSubjectDN ());
111+
112+ // Rotate files immediately on disk
113+ Files .write (certFile .toPath (), Files .readAllBytes (ssc2 .certificate ().toPath ()));
114+ Files .write (keyFile .toPath (), Files .readAllBytes (ssc2 .privateKey ().toPath ()));
115+
116+ // Within the throttle interval, the manager should retain and return previous certificate
117+ assertEquals (
118+ ssc1 .cert ().getSubjectDN (), keyManager .getCertificateChain (alias1 )[0 ].getSubjectDN ());
119+ } finally {
120+ ssc1 .delete ();
121+ ssc2 .delete ();
122+ }
112123 }
113124
114125 @ Test
115126 public void testCorruptRotationFallsBackToPrevious () throws Exception {
116127 SelfSignedCertificate ssc = new SelfSignedCertificate ("spanner.test.fallback" );
117- File certFile = tempFolder .newFile ("client-fallback.crt" );
118- File keyFile = tempFolder .newFile ("client-fallback.key" );
119-
120- Files .write (certFile .toPath (), Files .readAllBytes (ssc .certificate ().toPath ()));
121- Files .write (keyFile .toPath (), Files .readAllBytes (ssc .privateKey ().toPath ()));
122-
123- DynamicKeyManager keyManager = new DynamicKeyManager (certFile , keyFile , 0L );
124- String aliasBefore = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
125- assertNotNull (aliasBefore );
126-
127- Thread .sleep (1100 );
128-
129- // Overwrite certFile with corrupt bytes
130- Files .write (certFile .toPath (), "NOT A CERTIFICATE CONTENT" .getBytes (StandardCharsets .UTF_8 ));
128+ try {
129+ File certFile = tempFolder .newFile ("client-fallback.crt" );
130+ File keyFile = tempFolder .newFile ("client-fallback.key" );
131+
132+ Files .write (certFile .toPath (), Files .readAllBytes (ssc .certificate ().toPath ()));
133+ Files .write (keyFile .toPath (), Files .readAllBytes (ssc .privateKey ().toPath ()));
134+
135+ DynamicKeyManager keyManager = new DynamicKeyManager (certFile , keyFile , 0L );
136+ String aliasBefore = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
137+ assertNotNull (aliasBefore );
138+
139+ Thread .sleep (1100 );
140+
141+ // Overwrite certFile with corrupt bytes
142+ Files .write (certFile .toPath (), "NOT A CERTIFICATE CONTENT" .getBytes (StandardCharsets .UTF_8 ));
143+
144+ // DynamicKeyManager should catch reload error and retain previous material
145+ String aliasAfter = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
146+ assertEquals (aliasBefore , aliasAfter );
147+ assertNotNull (keyManager .getCertificateChain (aliasAfter ));
148+ assertNotNull (keyManager .getPrivateKey (aliasAfter ));
149+ } finally {
150+ ssc .delete ();
151+ }
152+ }
131153
132- // DynamicKeyManager should catch reload error and retain previous material
133- String aliasAfter = keyManager .chooseClientAlias (new String [] {"RSA" }, null , null );
134- assertEquals (aliasBefore , aliasAfter );
135- assertNotNull (keyManager .getCertificateChain (aliasAfter ));
136- assertNotNull (keyManager .getPrivateKey (aliasAfter ));
154+ @ Test
155+ public void testPkcs1KeyThrowsIllegalArgumentException () throws Exception {
156+ SelfSignedCertificate ssc = new SelfSignedCertificate ("spanner.test.pkcs1" );
157+ try {
158+ File certFile = tempFolder .newFile ("client-pkcs1.crt" );
159+ File keyFile = tempFolder .newFile ("client-pkcs1.key" );
160+
161+ Files .write (certFile .toPath (), Files .readAllBytes (ssc .certificate ().toPath ()));
162+ Files .write (
163+ keyFile .toPath (),
164+ ("-----BEGIN RSA PRIVATE KEY-----\n "
165+ + "MIIEowIBAAKCAQEA0Y3...\n "
166+ + "-----END RSA PRIVATE KEY-----\n " )
167+ .getBytes (StandardCharsets .UTF_8 ));
168+
169+ IllegalArgumentException exception =
170+ assertThrows (
171+ IllegalArgumentException .class , () -> new DynamicKeyManager (certFile , keyFile ));
172+ assertThat (exception .getMessage ()).contains ("PKCS#1 private keys are not supported" );
173+ assertThat (exception .getMessage ()).contains ("openssl pkcs8" );
174+ } finally {
175+ ssc .delete ();
176+ }
137177 }
138178
139179 @ Test
@@ -148,15 +188,19 @@ public void testNonExistentFileFailsInitialization() {
148188 @ Test
149189 public void testServerAliasesReturnNull () throws Exception {
150190 SelfSignedCertificate ssc = new SelfSignedCertificate ("spanner.test.server" );
151- File certFile = tempFolder .newFile ("server-test.crt" );
152- File keyFile = tempFolder .newFile ("server-test.key" );
153-
154- Files .write (certFile .toPath (), Files .readAllBytes (ssc .certificate ().toPath ()));
155- Files .write (keyFile .toPath (), Files .readAllBytes (ssc .privateKey ().toPath ()));
156-
157- DynamicKeyManager keyManager = new DynamicKeyManager (certFile , keyFile );
158- assertNull (keyManager .getServerAliases ("RSA" , null ));
159- assertNull (keyManager .chooseServerAlias ("RSA" , null , null ));
160- assertNull (keyManager .chooseEngineServerAlias ("RSA" , null , null ));
191+ try {
192+ File certFile = tempFolder .newFile ("server-test.crt" );
193+ File keyFile = tempFolder .newFile ("server-test.key" );
194+
195+ Files .write (certFile .toPath (), Files .readAllBytes (ssc .certificate ().toPath ()));
196+ Files .write (keyFile .toPath (), Files .readAllBytes (ssc .privateKey ().toPath ()));
197+
198+ DynamicKeyManager keyManager = new DynamicKeyManager (certFile , keyFile );
199+ assertNull (keyManager .getServerAliases ("RSA" , null ));
200+ assertNull (keyManager .chooseServerAlias ("RSA" , null , null ));
201+ assertNull (keyManager .chooseEngineServerAlias ("RSA" , null , null ));
202+ } finally {
203+ ssc .delete ();
204+ }
161205 }
162206}
0 commit comments