1   package com.atlassian.security.auth.trustedapps.filter;
2   
3   import java.io.UnsupportedEncodingException;
4   import java.security.InvalidKeyException;
5   import java.security.NoSuchAlgorithmException;
6   import java.security.PublicKey;
7   import java.security.Signature;
8   import java.security.SignatureException;
9   
10  import com.atlassian.security.auth.trustedapps.BouncyCastleEncryptionProvider;
11  
12  import org.bouncycastle.util.encoders.Base64;
13  
14  /**
15   * Verifies signatures of URLs.
16   * 
17   * @since 2.4
18   */
19  class RequestSignatureTool
20  {
21      public static final String ALGORITHM = "SHA1withRSA";
22      private static final String UTF8 = "utf-8";
23      
24      private Signature getSigImpl() throws NoSuchAlgorithmException
25      {
26          return Signature.getInstance(ALGORITHM, BouncyCastleEncryptionProvider.PROVIDER);
27      }
28      
29      public boolean verify(long timestamp, String requestUrl, PublicKey key, String signature)
30          throws UnableToVerifySignatureException
31      {
32          try
33          {
34              String signatureMaterial = Long.toString(timestamp) + '\n' + requestUrl;
35              
36              Signature sig = getSigImpl();
37              
38              sig.initVerify(key);
39              sig.update(signatureMaterial.getBytes(UTF8));
40              return sig.verify(Base64.decode(signature));
41          }
42          catch (InvalidKeyException e)
43          {
44              throw new UnableToVerifySignatureException(e);
45          }
46          catch (SignatureException e)
47          {
48              throw new UnableToVerifySignatureException(e);
49          }
50          catch (NoSuchAlgorithmException e)
51          {
52              throw new UnableToVerifySignatureException(e);
53          }
54          catch (StringIndexOutOfBoundsException e)
55          {
56              throw new UnableToVerifySignatureException(e);
57          }
58          catch (UnsupportedEncodingException e)
59          {
60              throw new UnableToVerifySignatureException(e);
61          }
62      }
63  
64      class UnableToVerifySignatureException extends Exception
65      {
66          public UnableToVerifySignatureException(Exception cause)
67          {
68              super(cause);
69          }
70      }
71  }