a0b7ebdad5eba9db6cb17af59d6d8f6fa32b71d8
[java-idp.git] / src / edu / internet2 / middleware / shibboleth / common / AttributeQueryHandle.java
1 package edu.internet2.middleware.shibboleth.common;
2
3 import java.util.StringTokenizer;
4
5 import javax.crypto.Cipher;
6 import javax.crypto.SecretKey;
7 import org.doomdark.uuid.UUID;
8 import org.doomdark.uuid.UUIDGenerator;
9
10 /**
11  * A Shibboleth Attribute Query Handle.
12  * 
13  * @author Walter Hoehn wassa@columbia.edu
14  *
15  */
16
17 public class AttributeQueryHandle {
18
19         private String principal;
20         private long creationTime;
21         private long expirationTime;
22         private byte[] cipherTextHandle;
23         private String handleID;
24
25         /**
26          * Unmarshalls an <code>AttributeQueryHandle</code> based on the results of the serialize() method
27          * of an existing <code>AttributeQueryHandle</code>.  Requires a key identical to the one used
28          * in the creation of the original <code>AttributeQueryHandle</code>.
29          * 
30          */
31
32         public AttributeQueryHandle(String handle, SecretKey key)
33                 throws HandleException {
34
35                 try {
36                         Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
37                         cipher.init(Cipher.DECRYPT_MODE, key);
38                         StringTokenizer tokenizer =
39                                 new StringTokenizer(
40                                         new String(cipher.doFinal(Base64.decode(handle))),
41                                         "||",
42                                         false);
43                         principal = tokenizer.nextToken();
44                         expirationTime = new Long(tokenizer.nextToken()).longValue();
45                         handleID = tokenizer.nextToken();
46                 } catch (Exception e) {
47                         throw new HandleException("Error unmarshalling handle: " + e);
48                 }
49
50         }
51
52         /**
53          * Creates a new <code>AttributeQueryHandle</code>
54          * @param principal <code>String</code> representation of user that the handle should reference
55          * @param validityPeriod Time in milliseconds for which the handle should be valid
56          * @param hsLocation URL of the Handle Service used to generate the AQH
57          * @param key Symmetric key used to encrypt the AQH upon serialization
58          * 
59          */
60
61         public AttributeQueryHandle(
62                 String principal,
63                 SecretKey key,
64                 long validityPeriod,
65                 String hsLocation)
66                 throws HandleException {
67
68                 this.principal = principal;
69                 this.creationTime = System.currentTimeMillis();
70                 this.expirationTime = creationTime + validityPeriod;
71
72                 try {
73                         //create a unique id based on the url of the HS and the current time
74                         UUIDGenerator uuidGen = UUIDGenerator.getInstance();
75                         UUID nameSpaceUUID = new UUID(UUID.NAMESPACE_URL);
76                         handleID =
77                         uuidGen.generateNameBasedUUID(nameSpaceUUID, hsLocation)+ ":" + uuidGen.generateTimeBasedUUID();
78                         
79                         Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
80                         cipher.init(Cipher.ENCRYPT_MODE, key);
81                         cipherTextHandle =
82                                 cipher.doFinal(
83                                         (principal + "||" + expirationTime + "||" + handleID)
84                                                 .getBytes("UTF-8"));
85
86                 } catch (Exception e) {
87                         throw new HandleException("Error creating handle: " + e);
88
89                 }
90
91         }
92
93         /**
94          * Returns a <code>String</code> representation of the user that the handle references.
95          */
96
97         public String getPrincipal() {
98                 return principal;
99         }
100
101         /**
102          * Returns a <code>String</code> of ciphertext representing the <code>AttributeQueryHandle</code> instance.
103          */
104
105         public String serialize() {
106
107                 return new String(Base64.encode(cipherTextHandle));
108         }
109
110         /**
111          * Boolean result indicates whether the validity of this <code>AttributeQueryHandle</code> 
112          * has lapsed.
113          */
114
115         public boolean isExpired() {
116
117                 if (System.currentTimeMillis() > expirationTime) {
118                         return true;
119                 } else {
120                         return false;
121                 }
122
123         }
124
125         /**
126          * Returns a <code>String</code> representation of the unique identifier for this handle.
127          */
128         
129         public String getHandleID() {
130                 return handleID;
131         }
132
133 }