1   package com.atlassian.security.auth.trustedapps;
2   
3   import com.atlassian.security.auth.trustedapps.TrustedApplicationUtils.Header.Response;
4   import com.atlassian.security.auth.trustedapps.request.TrustedRequest;
5   
6   /**
7    * Utility class for trusted applications
8    */
9   public class TrustedApplicationUtils
10  {
11      /**
12       * Used in Request/Response Header values for validating the capabilites of the client/server.
13       * 
14       * @since 0.35
15       */
16      public static final class Constant
17      {
18          /**
19           * The protocol version. The first version of this protocol did not contain this header and so was verion#0.
20           */
21          public static final Integer VERSION = new Integer(1);
22          
23          public static final Integer VERSION_TWO = Integer.valueOf(2);
24  
25          /**
26           * Magic number used to validate successful decryption.
27           */
28          public static final String MAGIC = String.valueOf(0xBADC0FEE);
29  
30          /**
31           * Default charset used for encoding/decoding Strings.
32           */
33          public static final String CHARSET_NAME = "utf-8";
34  
35          public static final String CERTIFICATE_URL_PATH = "/admin/appTrustCertificate";
36          
37          private Constant()
38          {
39          }
40      }
41  
42      /**
43       * Request/Response header parameters
44       * 
45       * @since 0.35
46       */
47      public static final class Header
48      {
49          private static final String PREFIX = "X-Seraph-Trusted-App-";
50  
51          public static final class Request
52          {
53              /**
54               * Header name for trusted application ID
55               */
56              public static final String ID = PREFIX + "ID";
57  
58              /**
59               * Header name for the secret key, used to encrypt the certificate.
60               */
61              public static final String SECRET_KEY = PREFIX + "Key";
62  
63              /**
64               * Header name for trusted application certificate
65               */
66              public static final String CERTIFICATE = PREFIX + "Cert";
67  
68              /**
69               * Header name for trusted application protocol version
70               */
71              public static final String VERSION = PREFIX + "Version";
72  
73              /**
74               * Header name for magic number for decryption validation
75               */
76              public static final String MAGIC = PREFIX + "Magic";
77  
78              public static final String SIGNATURE = PREFIX + "Signature";
79  
80              private Request()
81              {
82              }
83          }
84  
85          public static final class Response
86          {
87              /**
88               * Header that will contain trusted application error message if it fails
89               */
90              public static final String ERROR = PREFIX + "Error";
91  
92              /**
93               * Header used to indicate the status of a response to a trusted app request
94               */
95              public static final String STATUS = PREFIX + "Status";
96  
97              private Response()
98              {
99              }
100         }
101 
102         private Header()
103         {
104         }
105     }
106 
107     /**
108      * Add request parameters to the trusted request. Values are extracted from the given certificate.
109      * 
110      * @param certificate
111      *            the encrypted certificate to retrieve values from
112      * @param request
113      *            the request to populate
114      */
115     public static void addRequestParameters(final EncryptedCertificate certificate, final TrustedRequest request)
116     {
117         request.addRequestParameter(Header.Request.ID, certificate.getID());
118         request.addRequestParameter(Header.Request.CERTIFICATE, certificate.getCertificate());
119         request.addRequestParameter(Header.Request.SECRET_KEY, certificate.getSecretKey());
120         
121         Integer version = certificate.getProtocolVersion();
122         if (version != null)
123         {
124             request.addRequestParameter(Header.Request.VERSION, version.toString());
125         }
126         
127         request.addRequestParameter(Header.Request.MAGIC, certificate.getMagicNumber());
128         if (certificate.getSignature() != null)
129         {
130             request.addRequestParameter(Header.Request.SIGNATURE, certificate.getSignature());
131         }
132     }
133     
134     /**
135      * Get a {@link TransportErrorMessage} from the {@link Response#ERROR} header. This contains an error code that can
136      * be used for i18n purposes as well the parameters. You can also get a default formatted error message.
137      * 
138      * @param errorMessage the String containing the error message. Must 
139      * @return
140      */
141     public static TransportErrorMessage parseError(String errorMessage)
142     {
143         return TransportErrorMessage.PARSER.parse(errorMessage);
144     }
145 
146     public static void validateMagicNumber(String msg, String appId, Integer protocolVersion, String magicNumber) throws InvalidCertificateException
147     {
148         // if empty don't worry
149         if ((protocolVersion != null) && !TrustedApplicationUtils.Constant.MAGIC.equals(magicNumber))
150         {
151             throw new InvalidCertificateException(new TransportErrorMessage.BadMagicNumber(msg, appId));
152         }
153     }
154 }