39 |
public static String PREFIX = "urn:x-storm:pointer-0.1:"; |
public static String PREFIX = "urn:x-storm:pointer-0.1:"; |
40 |
public static int PREFIX_LEN = PREFIX.length(); |
public static int PREFIX_LEN = PREFIX.length(); |
41 |
|
|
42 |
private static KeyFactory keyFactory; |
static final KeyFactory keyFactory; |
43 |
static { |
static { |
44 |
try { |
try { |
45 |
keyFactory = KeyFactory.getInstance("DSA"); |
keyFactory = KeyFactory.getInstance("DSA"); |
51 |
private static SecureRandom random = new SecureRandom(); |
private static SecureRandom random = new SecureRandom(); |
52 |
|
|
53 |
private String uri; |
private String uri; |
54 |
|
private byte[] bytes; |
55 |
private String randomPart; |
private String randomPart; |
|
private byte[] keyBytes; |
|
|
private PublicKey key; |
|
56 |
|
|
57 |
public PointerId(String uri) |
public PointerId(String uri) |
58 |
throws IllegalArgumentException, InvalidKeyException, |
throws IllegalArgumentException, InvalidKeyException, |
60 |
uri = uri.toLowerCase().intern(); |
uri = uri.toLowerCase().intern(); |
61 |
this.uri = uri; |
this.uri = uri; |
62 |
|
|
63 |
int colon = uri.indexOf(':', PREFIX_LEN); |
int colon = uri.lastIndexOf(':'); |
64 |
|
|
65 |
if(!uri.startsWith(PREFIX)) |
if(!uri.startsWith(PREFIX)) |
66 |
throw new IllegalArgumentException("Storm URN must start "+PREFIX+" [[ was "+uri+" ]]"); |
throw new IllegalArgumentException("Storm URN must start "+PREFIX+" [[ was "+uri+" ]]"); |
67 |
if(colon < 0) |
if(colon < PREFIX_LEN) |
68 |
throw new IllegalArgumentException("URN must contain random part"); |
throw new IllegalArgumentException("Illegal pointer URN (colon missing)"); |
69 |
|
bytes = Base32.decode(uri.substring(PREFIX_LEN, colon)); |
|
|
|
70 |
randomPart = uri.substring(colon+1); |
randomPart = uri.substring(colon+1); |
|
keyBytes = Base32.decode(uri.substring(PREFIX_LEN, colon)); |
|
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); |
|
|
key = keyFactory.generatePublic(keySpec); |
|
71 |
} |
} |
72 |
|
|
73 |
public PointerId(PublicKey key, String randomPart) |
public PointerId(PublicKey key, String randomPart) |
74 |
throws InvalidKeyException, InvalidKeySpecException { |
throws InvalidKeyException, InvalidKeySpecException { |
75 |
|
|
76 |
key = (PublicKey)keyFactory.translateKey(key); |
MessageDigest d; |
77 |
this.key = key; |
try { |
78 |
EncodedKeySpec keySpec = |
d = MessageDigest.getInstance("SHA-1"); |
79 |
(EncodedKeySpec)keyFactory.getKeySpec(key, X509EncodedKeySpec.class); |
} catch(NoSuchAlgorithmException _) { |
80 |
keyBytes = keySpec.getEncoded(); |
throw new Error("Need SHA-1 algorithm support in Storm"); |
81 |
|
} |
82 |
|
|
83 |
this.randomPart = randomPart; |
d.update(getKeyBytes(key)); |
84 |
|
|
85 |
String uri = PREFIX + Base32.encode(keyBytes) + ":" + randomPart; |
this.bytes = d.digest(); |
86 |
|
this.randomPart = randomPart; |
87 |
|
String uri = PREFIX + Base32.encode(bytes) + ":" + randomPart; |
88 |
this.uri = uri.toLowerCase().intern(); |
this.uri = uri.toLowerCase().intern(); |
89 |
} |
} |
90 |
|
|
94 |
this(key, Base32.encode(randomBytes())); |
this(key, Base32.encode(randomBytes())); |
95 |
} |
} |
96 |
|
|
|
public PublicKey getKey() { return key; } |
|
|
public String getRandomPart() { return randomPart; } |
|
|
|
|
97 |
public String getURI() { return uri; } |
public String getURI() { return uri; } |
98 |
public String toString() { return uri; } |
public String toString() { return uri; } |
99 |
|
|
104 |
|
|
105 |
public int hashCode() { return uri.hashCode(); } |
public int hashCode() { return uri.hashCode(); } |
106 |
|
|
107 |
|
public void verify(byte[] keyBytes) { |
108 |
|
MessageDigest d; |
109 |
|
try { |
110 |
|
d = MessageDigest.getInstance("SHA-1"); |
111 |
|
} catch(NoSuchAlgorithmException _) { |
112 |
|
throw new Error("Need SHA-1 algorithm support in Storm"); |
113 |
|
} |
114 |
|
|
115 |
|
d.update(keyBytes); |
116 |
|
|
117 |
|
if(!d.isEqual(d.digest(), this.bytes)) |
118 |
|
throw new IllegalArgumentException("Pointer doesn't match: "+this); |
119 |
|
} |
120 |
|
|
121 |
private static byte[] randomBytes() { |
private static byte[] randomBytes() { |
122 |
byte[] b = new byte[20]; |
byte[] b = new byte[20]; |
123 |
random.nextBytes(b); |
random.nextBytes(b); |
124 |
return b; |
return b; |
125 |
} |
} |
126 |
|
|
127 |
|
public static byte[] getKeyBytes(PublicKey key) |
128 |
|
throws InvalidKeyException, InvalidKeySpecException { |
129 |
|
key = (PublicKey)keyFactory.translateKey(key); |
130 |
|
EncodedKeySpec keySpec = |
131 |
|
(EncodedKeySpec)keyFactory.getKeySpec(key, X509EncodedKeySpec.class); |
132 |
|
return keySpec.getEncoded(); |
133 |
|
} |
134 |
} |
} |