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 final TransportErrorMessage error =
37 new TransportErrorMessage(TransportErrorMessage.Code.MISSING_CERT,
38 "\"Application Certificate too small.\" Values found: [" + values.size() + "] ." + values);
39 final Exception cause = new TransportException(error) {};
40 throw new ApplicationNotFoundException(cause);
41 }
42 if (values.size() == 2)
43 {
44 return getApplicationProtocolV0();
45 }
46 return getApplicationProtocolV1();
47 }
48
49 private Application getApplicationProtocolV1() throws RetrievalException
50 {
51
52 final Application result = getApplicationProtocolV0();
53
54 final String protocol = values.get(2);
55 final String magic = values.get(3);
56 try
57 {
58 final Integer protocolVersion = isBlank(protocol) ? null : Integer.valueOf(protocol);
59 try
60 {
61 TrustedApplicationUtils.validateMagicNumber("application details", result.getID(), protocolVersion, magic);
62 }
63 catch (final InvalidCertificateException e)
64 {
65 throw new InvalidApplicationDetailsException(e);
66 }
67 }
68 catch (final NumberFormatException e)
69 {
70 throw new InvalidApplicationDetailsException(e);
71 }
72 return result;
73 }
74
75 private Application getApplicationProtocolV0() throws RetrievalException
76 {
77 try
78 {
79 final String id = values.get(0);
80 final String keyStr = values.get(1);
81
82 if (keyStr == null)
83 {
84 throw new ApplicationNotFoundException("Public Key not found");
85 }
86
87 final byte[] data = transcoder.decode(keyStr);
88 final PublicKey key = encryptionProvider.toPublicKey(data);
89 return new SimpleApplication(id, key);
90 }
91 catch (final InvalidKeySpecException e)
92 {
93 throw new RuntimeException(e);
94 }
95 catch (final NoSuchAlgorithmException e)
96 {
97 throw new RuntimeException(e);
98 }
99 catch (final NoSuchProviderException e)
100 {
101 throw new RuntimeException(e);
102 }
103 }
104
105 private static boolean isBlank(final String input)
106 {
107 return (input == null) || (input.trim().length() == 0);
108 }
109 }