Clover Coverage Report - Atlassian Trusted Apps(Aggregated)
Coverage timestamp: Tue Jun 9 2009 19:34:44 CDT
150   381   38   6
0   334   0.25   8.33
25     1.52  
3    
 
 
  TestBouncyCastleEncryptionProvider       Line # 26 124 29 93.8% 0.9375
  TestBouncyCastleEncryptionProvider.Token       Line # 294 26 9 87.1% 0.87096775
  TestBouncyCastleEncryptionProvider.Token.KeyData       Line # 296 0 0 - -1.0
 
  (17)
 
1    package com.atlassian.security.auth.trustedapps;
2   
3    import com.atlassian.security.auth.trustedapps.ApplicationRetriever.ApplicationNotFoundException;
4    import com.atlassian.security.auth.trustedapps.ApplicationRetriever.RemoteSystemNotFoundException;
5   
6    import org.bouncycastle.jce.provider.BouncyCastleProvider;
7    import org.bouncycastle.util.encoders.Base64;
8   
9    import java.io.File;
10    import java.io.FileWriter;
11    import java.net.URI;
12    import java.net.URL;
13    import java.security.KeyFactory;
14    import java.security.PrivateKey;
15    import java.security.Provider;
16    import java.security.PublicKey;
17    import java.security.spec.PKCS8EncodedKeySpec;
18    import java.security.spec.X509EncodedKeySpec;
19   
20    import javax.crypto.Cipher;
21    import javax.crypto.SecretKey;
22    import javax.crypto.spec.SecretKeySpec;
23   
24    import junit.framework.TestCase;
25   
 
26    public class TestBouncyCastleEncryptionProvider extends TestCase
27    {
28    private final EncryptionProvider encryptionProvider = new BouncyCastleEncryptionProvider();
29   
 
30  1 toggle public void testGetApplicationCertificateReturnsEmpty() throws Exception
31    {
32  1 URL url = this.getClass().getResource("/trustedapps");
33  1 File root = new File(new URI(url.toString()));
34  1 assertTrue(root.isDirectory());
35  1 File cert = new File(root, "admin/appTrustCertificate");
36  1 cert.delete();
37  1 File certDir = new File(root, "admin");
38  1 certDir.mkdirs();
39  1 assertTrue(cert.getCanonicalPath(), cert.createNewFile());
40  1 FileWriter writer = new FileWriter(cert);
41  1 writer.write("");
42  1 writer.close();
43  1 try
44    {
45  1 encryptionProvider.getApplicationCertificate(root.toURI().toString());
46  0 fail("CertNotFound expected");
47    }
48    catch (ApplicationNotFoundException e)
49    {
50    // expected
51    }
52    }
53   
 
54  1 toggle public void testGetApplicationCertificateNotFoundAtAll() throws Exception
55    {
56  1 URL url = this.getClass().getResource("/");
57  1 File root = new File(new URI(url.toString()));
58  1 assertTrue(root.isDirectory());
59  1 try
60    {
61  1 encryptionProvider.getApplicationCertificate(root.toURI().toString());
62  0 fail("FNFE expected");
63    }
64    catch (ApplicationNotFoundException e)
65    {
66    // expected
67    }
68    }
69   
 
70  1 toggle public void testGetApplicationCertificateMalformedUrl() throws Exception
71    {
72  1 try
73    {
74  1 encryptionProvider.getApplicationCertificate("noscheme://some/url");
75  0 fail("InvalidApplicationDetailsException expected");
76    }
77    catch (RemoteSystemNotFoundException yay)
78    {
79    // expected
80    }
81    }
82   
 
83  1 toggle public void testGetApplicationCertificateReturnsProperly() throws Exception
84    {
85  1 final String publicKeyData = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6q2RIBqhT0Ny59W7cZ1zwSHFBAJeCpkbzY0nCMUK5eiim/9TUfNvlpSJj5Ks/zs5Ll4R129rYtTfIfvIq4sSMjXKB8rftswet4uQWdTcTJyesLHbYgHqSIS0b+1JtQsDvjB5aEYApS4nc+fjZmwJQkpN++J8QpqQeoGDzq+zVxAzuGdVrkMEuCXcAS4znYFqW7VytvS0DHhreSIh1fGWLJIqE15Jih91Up2W+dRdLAdW0OVozOsWYFx5+L325PWkSgsDCMGVyNCdTnwCzI4FiYsT4MLODkOnOt9gDQTMjn8H1NM5K3d3Sb7WH2hKwuBxLyDRUY7qUB1bwtGU6LgjQIDAQAB";
86   
87  1 URL url = this.getClass().getResource("/trustedapps");
88  1 File root = new File(new URI(url.toString()));
89  1 assertTrue(root.isDirectory());
90  1 File cert = new File(root, "admin/appTrustCertificate");
91  1 cert.delete();
92  1 File certDir = new File(root, "admin");
93  1 certDir.mkdirs();
94  1 assertTrue(cert.getCanonicalPath(), cert.createNewFile());
95  1 FileWriter writer = new FileWriter(cert);
96  1 writer.write("myApplicationId\n");
97  1 writer.write(publicKeyData);
98  1 writer.close();
99  1 Application app = encryptionProvider.getApplicationCertificate(root.toURI().toString());
100  1 assertEquals("myApplicationId", app.getID());
101    }
102   
 
103  1 toggle public void testDecodeBadSecretKey() throws Exception
104    {
105  1 Token token = new Token();
106  1 long time = System.currentTimeMillis();
107  1 EncryptedCertificate encrypted = new DefaultEncryptedCertificate("id", "bad-secret-key-bad!", token.encrypt("fred", time), TrustedApplicationUtils.Constant.VERSION, token.getMagic());
108  1 try
109    {
110  1 encryptionProvider.decodeEncryptedCertificate(encrypted, token.getPublicKey(), "id");
111  0 fail("InvalidCertificateException expected");
112    }
113    catch (InvalidCertificateException e)
114    {
115    // expected
116    }
117    }
118   
 
119  1 toggle public void testDecodeSecretKey() throws Exception
120    {
121  1 Token token = new Token();
122  1 long time = System.currentTimeMillis();
123  1 EncryptedCertificate encrypted = new DefaultEncryptedCertificate("id", token.getSecretKey(), token.encrypt("fred", time), TrustedApplicationUtils.Constant.VERSION, token.getMagic());
124  1 ApplicationCertificate cert = encryptionProvider.decodeEncryptedCertificate(encrypted, token.getPublicKey(), "id");
125  1 assertEquals(time, cert.getCreationTime().getTime());
126  1 assertEquals("fred", cert.getUserName());
127  1 assertEquals("id", cert.getApplicationID());
128    }
129   
 
130  1 toggle public void testDecodeBadMagicNumber() throws Exception
131    {
132  1 Token token = new Token();
133  1 long time = System.currentTimeMillis();
134  1 EncryptedCertificate encrypted = new DefaultEncryptedCertificate("id", token.getSecretKey(), token.encrypt("fred", time), TrustedApplicationUtils.Constant.VERSION, "bad-magic, bad!");
135  1 try
136    {
137  1 encryptionProvider.decodeEncryptedCertificate(encrypted, token.getPublicKey(), "id");
138  0 fail("InvalidCertificateException expected");
139    }
140    catch (InvalidCertificateException e)
141    {
142    // expected
143    }
144    }
145   
 
146  1 toggle public void testDecodeInvalidCertificate() throws Exception
147    {
148  1 Token token = new Token();
149  1 EncryptedCertificate encrypted = new DefaultEncryptedCertificate("id", token.getSecretKey(), "TestTrustedApplicationClient.id", TrustedApplicationUtils.Constant.VERSION, token.getMagic());
150  1 try
151    {
152  1 encryptionProvider.decodeEncryptedCertificate(encrypted, token.getPublicKey(), "id");
153  0 fail("InvalidCertificateException expected");
154    }
155    catch (InvalidCertificateException e)
156    {
157    // expected - will be a SystemException under IBM JDK due to SER-118
158    }
159    }
160   
 
161  1 toggle public void testDecodeNumberFormatException() throws Exception
162    {
163  1 Token token = new Token()
164    {
 
165  1 toggle String encrypt(String userName, long time)
166    {
167  1 try
168    {
169  1 Cipher cipher = Cipher.getInstance(KeyData.STREAM_CIPHER, KeyData.BOUNCY_CASTLE_PROVIDER);
170  1 cipher.init(Cipher.ENCRYPT_MODE, secretKey);
171  1 StringBuffer buffer = new StringBuffer("not-a-number").append("\n").append(userName).append("\n").append(TrustedApplicationUtils.Constant.MAGIC);
172  1 return new String(Base64.encode(cipher.doFinal(buffer.toString().getBytes())), TrustedApplicationUtils.Constant.CHARSET_NAME);
173    }
174    catch (Exception e)
175    {
176  0 throw new RuntimeException(e);
177    }
178    }
179    };
180  1 long time = System.currentTimeMillis();
181  1 EncryptedCertificate encrypted = new DefaultEncryptedCertificate("id", token.getSecretKey(), token.encrypt("fred", time), TrustedApplicationUtils.Constant.VERSION, token.getMagic());
182  1 try
183    {
184  1 encryptionProvider.decodeEncryptedCertificate(encrypted, token.getPublicKey(), "id");
185  0 fail("InvalidCertificateException expected");
186    }
187    catch (SystemException e)
188    {
189    // expected
190    }
191    }
192   
 
193  1 toggle public void testDecodeNullMagicNumberVersion0() throws Exception
194    {
195  1 Token token = new Token();
196  1 long time = System.currentTimeMillis();
197  1 EncryptedCertificate encrypted = new DefaultEncryptedCertificate("id", token.getSecretKey(), token.encrypt("fred", time), null, null);
198  1 ApplicationCertificate cert = encryptionProvider.decodeEncryptedCertificate(encrypted, token.getPublicKey(), "id");
199  1 assertEquals(time, cert.getCreationTime().getTime());
200  1 assertEquals("fred", cert.getUserName());
201  1 assertEquals("id", cert.getApplicationID());
202    }
203   
 
204  1 toggle public void testDecodeNullMagicNumberVersion1() throws Exception
205    {
206  1 Token token = new Token();
207  1 long time = System.currentTimeMillis();
208  1 EncryptedCertificate encrypted = new DefaultEncryptedCertificate("id", token.getSecretKey(), token.encrypt("fred", time), TrustedApplicationUtils.Constant.VERSION, null);
209  1 try
210    {
211  1 encryptionProvider.decodeEncryptedCertificate(encrypted, token.getPublicKey(), "id");
212  0 fail("InvalidCertificateException expected");
213    }
214    catch (InvalidCertificateException e)
215    {
216    // expected
217    }
218    }
219   
 
220  1 toggle public void testBCSecretKeyFactory()
221    {
222  1 BouncyCastleEncryptionProvider.SecretKeyFactory keyFactory = new BouncyCastleEncryptionProvider.BCKeyFactory();
223  1 SecretKey secretKey = keyFactory.generateSecretKey();
224  1 assertNotNull(secretKey);
225  1 assertEquals("RC4", secretKey.getAlgorithm());
226  1 assertEquals("RAW", secretKey.getFormat());
227  1 assertNotNull(secretKey.getEncoded());
228  1 assertEquals(16, secretKey.getEncoded().length);
229    }
230   
 
231  1 toggle public void testSecretKeyValidatorValidatesLength16()
232    {
233  1 BouncyCastleEncryptionProvider.SecretKeyValidator keyValidator = new BouncyCastleEncryptionProvider.TransmissionValidator();
234  1 SecretKey secretKey = new SecretKeySpec(new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, "ALG");
235  1 assertTrue(keyValidator.isValid(secretKey));
236    }
237   
 
238  1 toggle public void testSecretKeyValidatorInValidatesLengthLessThan16()
239    {
240  1 BouncyCastleEncryptionProvider.SecretKeyValidator keyValidator = new BouncyCastleEncryptionProvider.TransmissionValidator();
241  1 SecretKey secretKey = new SecretKeySpec(new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, "ALG");
242  1 assertFalse(keyValidator.isValid(secretKey));
243    }
244   
 
245  1 toggle public void testSecretKeyValidatorInValidatesLengthGreaterThan16()
246    {
247  1 BouncyCastleEncryptionProvider.SecretKeyValidator keyValidator = new BouncyCastleEncryptionProvider.TransmissionValidator();
248  1 SecretKey secretKey = new SecretKeySpec(new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, "ALG");
249  1 assertFalse(keyValidator.isValid(secretKey));
250    }
251   
 
252  1 toggle public void testSecretKeyValidatorInValidatesLeadingZero()
253    {
254  1 BouncyCastleEncryptionProvider.SecretKeyValidator keyValidator = new BouncyCastleEncryptionProvider.TransmissionValidator();
255  1 SecretKey secretKey = new SecretKeySpec(new byte[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, "ALG");
256  1 assertFalse(keyValidator.isValid(secretKey));
257    }
258   
 
259  1 toggle public void testValidatingSecretKeyFactory()
260    {
261  1 final int[] called = new int[2];
262  1 final int factory = 0;
263  1 final int validation = 1;
264  1 final int expectedCallCount = 5;
265   
266  1 BouncyCastleEncryptionProvider.SecretKeyFactory mockFactory = new BouncyCastleEncryptionProvider.SecretKeyFactory()
267    {
 
268  5 toggle public SecretKey generateSecretKey()
269    {
270  5 ++called[factory];
271  5 return new SecretKeySpec(new byte[] { (byte) called[factory], 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, "ALG");
272    }
273    };
274   
275  1 BouncyCastleEncryptionProvider.SecretKeyValidator mockValidator = new BouncyCastleEncryptionProvider.SecretKeyValidator()
276    {
 
277  5 toggle public boolean isValid(SecretKey secretKey)
278    {
279  5 return ++called[validation] == expectedCallCount;
280    }
281    };
282   
283  1 BouncyCastleEncryptionProvider.SecretKeyFactory testFactory = new BouncyCastleEncryptionProvider.ValidatingSecretKeyFactory(mockFactory, mockValidator);
284  1 SecretKey secretKey = testFactory.generateSecretKey();
285  1 assertNotNull(secretKey);
286  1 assertEquals(expectedCallCount, called[factory]);
287  1 assertEquals(expectedCallCount, called[validation]);
288  1 assertEquals(expectedCallCount, called[factory]);
289  1 assertNotNull(secretKey.getEncoded());
290  1 assertEquals(16, secretKey.getEncoded().length);
291  1 assertEquals(expectedCallCount, secretKey.getEncoded()[0]);
292    }
293   
 
294    private static class Token
295    {
 
296    static final class KeyData
297    {
298    private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCySptbugHAzWUJY3ALWhuSCPhVXnwbUBfsRExYQitBCVny4V1DcU2SAx22bH9dSM0X7NdMObF74r+Wd77QoPAtaySqFLqCeRCbFmhHgVSi+pGeCipTpueefSkz2AX8Aj+9x27tqjBsX1LtNWVLDsinEhBWN68R+iEOmf/6jGWObQIDAQAB";
299    private static final String PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALJKm1u6AcDNZQljcAtaG5II+FVefBtQF+xETFhCK0EJWfLhXUNxTZIDHbZsf11IzRfs10w5sXviv5Z3vtCg8C1rJKoUuoJ5EJsWaEeBVKL6kZ4KKlOm5559KTPYBfwCP73Hbu2qMGxfUu01ZUsOyKcSEFY3rxH6IQ6Z//qMZY5tAgMBAAECgYB4QXJAkFmWXfOEPZnZTlHCUmKN0kkLcx5vsjF8ZkUefNw6wl9Rmh6kGY30+YF+vhf3xzwAoflggjSPnP0LY0Ibf0XxMcNjR1zBsl9X7gKfXghIunS6gbcwrEwBNc5GR4zkYjYaZQ4zVvm3oMS2glV9NlXAUl41VL2XAQC/ENwbUQJBAOdoAz4hZGgke9AxoKLZh215gY+PLXqVLlWf14Ypk70Efk/bVvF10EsAOuAm9queCyr0qNf/vgHrm4HHXwJz4SsCQQDFPXir5qs+Kf2Y0KQ+WO5IRaNmrOlNvWDqJP/tDGfF/TYo6nSI0dGtWNfwZyDB47PbUq3zxCHYjExBJ9vQNZLHAkEA4JlCtHYCl1X52jug1w7c9DN/vc/Q626J909aB3ypSUdoNagFPf0EexcxDcijmDSgUEQA8Qzm5cRBPfg9Tgsc2wJBAIKbiv2hmEFowtHfTvMuJlNbMbF6zF67CaLib0oEDe+QFb4QSqyS69py20MItytM4btYy3GArbzcYl4+y5La9t8CQE2BkMV3MLcpAKjxtK5SYwCyLT591k35isGxmIlSQBQbDmGP9L5ZeXmVGVxRCGbBQjCzeoafPvUZo65kaRQHUJc=";
300    // private static final String SECRET_KEY = "6FcMEe0BgY6ohvXJrjnuig==";
301    private static final String SECRET_KEY = "T52KBiVRRol8V2/DS7cy9G9iRdv+vSH4wLqH9q7wdSiFtZw9MRG3ihhLSmmH1MnkwPeLg+y0wtDZuokMr6eJwPo+1dHO3t2pb7IwVJg+UqGgn97LdihAMgwqLApnQIMquDe5uDuuK6Qaey+D6EXu2E90FI4Z0mHqaE3Wbo+HC50=";
302    private static final String ALGORITHM = "RSA";
303    private static final Provider BOUNCY_CASTLE_PROVIDER = new BouncyCastleProvider();
304    private static final String STREAM_CIPHER = "RC4";
305    private static final String ASYM_CIPHER = "RSA/NONE/NoPadding";
306    }
307   
308    final PrivateKey privateKey;
309    final PublicKey publicKey;
310    final SecretKey secretKey;
311   
 
312  7 toggle Token()
313    {
314  7 try
315    {
316  7 KeyFactory keyFactory = KeyFactory.getInstance(KeyData.ALGORITHM, KeyData.BOUNCY_CASTLE_PROVIDER);
317  7 privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decode(KeyData.PRIVATE_KEY.getBytes(TrustedApplicationUtils.Constant.CHARSET_NAME))));
318  7 publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decode(KeyData.PUBLIC_KEY.getBytes(TrustedApplicationUtils.Constant.CHARSET_NAME))));
319   
320  7 Cipher cipher = Cipher.getInstance(KeyData.ASYM_CIPHER, KeyData.BOUNCY_CASTLE_PROVIDER);
321  7 cipher.init(Cipher.DECRYPT_MODE, publicKey);
322   
323  7 byte[] secretKeyData = cipher.doFinal(Base64.decode(KeyData.SECRET_KEY.getBytes(TrustedApplicationUtils.Constant.CHARSET_NAME)));
324   
325  7 secretKey = new SecretKeySpec(secretKeyData, KeyData.STREAM_CIPHER);
326    }
327    catch (Exception e)
328    {
329  0 throw new RuntimeException(e);
330    }
331    }
332   
 
333  7 toggle PublicKey getPublicKey()
334    {
335  7 return publicKey;
336    }
337   
 
338  6 toggle String getSecretKey()
339    {
340  6 try
341    {
342  6 Cipher cipher = Cipher.getInstance(KeyData.ASYM_CIPHER, KeyData.BOUNCY_CASTLE_PROVIDER);
343  6 cipher.init(Cipher.ENCRYPT_MODE, privateKey);
344  6 return new String(Base64.encode(cipher.doFinal(secretKey.getEncoded())), TrustedApplicationUtils.Constant.CHARSET_NAME);
345    }
346    catch (Exception e)
347    {
348  0 throw new RuntimeException(e);
349    }
350    }
351   
 
352  4 toggle String getMagic()
353    {
354  4 try
355    {
356  4 Cipher cipher = Cipher.getInstance(KeyData.ASYM_CIPHER, KeyData.BOUNCY_CASTLE_PROVIDER);
357  4 cipher.init(Cipher.ENCRYPT_MODE, privateKey);
358  4 return new String(Base64.encode(cipher.doFinal(TrustedApplicationUtils.Constant.MAGIC.getBytes())), TrustedApplicationUtils.Constant.CHARSET_NAME);
359    }
360    catch (Exception e)
361    {
362  0 throw new RuntimeException(e);
363    }
364    }
365   
 
366  5 toggle String encrypt(String userName, long time)
367    {
368  5 try
369    {
370  5 Cipher cipher = Cipher.getInstance(KeyData.STREAM_CIPHER, KeyData.BOUNCY_CASTLE_PROVIDER);
371  5 cipher.init(Cipher.ENCRYPT_MODE, secretKey);
372  5 StringBuffer buffer = new StringBuffer(String.valueOf(time)).append("\n").append(userName).append("\n").append(TrustedApplicationUtils.Constant.MAGIC);
373  5 return new String(Base64.encode(cipher.doFinal(buffer.toString().getBytes(TrustedApplicationUtils.Constant.CHARSET_NAME))), TrustedApplicationUtils.Constant.CHARSET_NAME);
374    }
375    catch (Exception e)
376    {
377  0 throw new RuntimeException(e);
378    }
379    }
380    }
381    }