1 package com.atlassian.security.auth.trustedapps;
2
3 import com.atlassian.security.auth.trustedapps.Transcoder.Base64Transcoder;
4
5 import java.security.NoSuchAlgorithmException;
6 import java.security.NoSuchProviderException;
7 import java.security.PublicKey;
8 import java.security.spec.InvalidKeySpecException;
9 import java.util.ArrayList;
10 import java.util.List;
11
12 public class ListApplicationRetriever implements ApplicationRetriever
13 {
14 private final List<String> values;
15 private final EncryptionProvider encryptionProvider;
16 private final Transcoder transcoder = new Base64Transcoder();
17
18 ListApplicationRetriever(final EncryptionProvider encryptionProvider, final List<String> values)
19 {
20 Null.not("encryptionProvider", encryptionProvider);
21 Null.not("values", values);
22 int i = 0;
23 for (final Object element : values)
24 {
25 Null.not("value: " + i++, element);
26 }
27
28 this.encryptionProvider = encryptionProvider;
29 this.values = new ArrayList<String>(values);
30 }
31
32 public Application getApplication() throws RetrievalException
33 {
34 if (values.size() < 2)
35 {
36 throw new ApplicationNotFoundException("Application Certificate too small");
37 }
38 if (values.size() == 2)
39 {
40 return getApplicationProtocolV0();
41 }
42 return getApplicationProtocolV1();
43 }
44
45 private Application getApplicationProtocolV1() throws RetrievalException
46 {
47
48 final Application result = getApplicationProtocolV0();
49
50 final String protocol = values.get(2);
51 final String magic = values.get(3);
52 try
53 {
54 final Integer protocolVersion = isBlank(protocol) ? null : Integer.valueOf(protocol);
55 try
56 {
57 TrustedApplicationUtils.validateMagicNumber("application details", result.getID(), protocolVersion, magic);
58 }
59 catch (final InvalidCertificateException e)
60 {
61 throw new InvalidApplicationDetailsException(e);
62 }
63 }
64 catch (final NumberFormatException e)
65 {
66 throw new InvalidApplicationDetailsException(e);
67 }
68 return result;
69 }
70
71 private Application getApplicationProtocolV0() throws RetrievalException
72 {
73 try
74 {
75 final String id = values.get(0);
76 final String keyStr = values.get(1);
77
78 if (keyStr == null)
79 {
80 throw new ApplicationNotFoundException("Public Key not found");
81 }
82
83 final byte[] data = transcoder.decode(keyStr);
84 final PublicKey key = encryptionProvider.toPublicKey(data);
85 return new SimpleApplication(id, key);
86 }
87 catch (final InvalidKeySpecException e)
88 {
89 throw new RuntimeException(e);
90 }
91 catch (final NoSuchAlgorithmException e)
92 {
93 throw new RuntimeException(e);
94 }
95 catch (final NoSuchProviderException e)
96 {
97 throw new RuntimeException(e);
98 }
99 }
100
101 private static boolean isBlank(final String input)
102 {
103 return (input == null) || (input.trim().length() == 0);
104 }
105 }