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