View Javadoc
1 package jsdsi; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.InputStream; 5 import java.net.URI; 6 import java.security.MessageDigest; 7 import java.security.NoSuchAlgorithmException; 8 import java.util.ArrayList; 9 import java.util.Iterator; 10 import java.util.List; 11 12 import jsdsi.sexp.SexpList; 13 import jsdsi.sexp.SexpParseException; 14 import jsdsi.sexp.SexpUtil; 15 import jsdsi.util.DigestAlgoEnum; 16 import jsdsi.util.DigestUtils; 17 18 /*** 19 * A cryptographic hash. 20 * 21 * @author Sameer Ajmani 22 * @author Sean Radford 23 * @version $Revision: 1.9.2.1 $ $Date: 2005/11/08 03:12:52 $ 24 * 25 * @todo add verify method(s) 26 */ 27 public class Hash extends Obj { 28 29 private static final long serialVersionUID = -1318052205486635960L; 30 31 /*** 32 * Hash algorithm. 33 */ 34 private transient final DigestAlgoEnum digest; 35 36 /*** 37 * Hash value. 38 */ 39 private transient final byte[] data; 40 41 /*** 42 * URIs of the hashed data. 43 */ 44 private transient final URI[] uris; 45 46 /*** 47 * Creates a new <code>Hash</code>. 48 * 49 * @param a hash algorithm 50 * @param d hash value (<i>not</i> the data to hash) 51 * @param u URIs of the hashed data (may be <code>null</code>). 52 * 53 */ 54 public Hash(DigestAlgoEnum a, byte[] d, URI[] u) { 55 assert(a != null) : "null algo"; 56 assert(d != null) : "null data"; 57 this.digest = a; 58 this.data = d; 59 this.uris = u; 60 } 61 62 /*** 63 * Creates a new <code>Hash</code>. 64 * 65 * @param a hash algorithm. 66 * @param o JSDSI object to hash. 67 * @param u URIs of the hashed data (may be <code>null</code>). 68 * 69 */ 70 public Hash(DigestAlgoEnum a, Obj o, URI[] u) { 71 assert(a != null) : "null algo"; 72 assert(o != null) : "null object"; 73 this.digest = a; 74 this.data = DigestUtils.getDigest(a).digest(o.toByteArray()); 75 this.uris = u; 76 } 77 78 /*** 79 * Creates a new <code>Hash</code>. 80 * 81 * @param a SPKI hash algorithm name 82 * @param d hash value (<i>not</i> the data to hash) 83 * @param u URIs of the hashed data 84 * 85 * @deprecated use {@link #Hash(jsdsi.util.DigestAlgoEnum, byte[], URI[])} 86 */ 87 public Hash(String a, byte[] d, URI[] u) { 88 this(DigestAlgoEnum.fromSpki(a), d, u); 89 } 90 91 /*** 92 * Creates a new <code>Hash</code>. 93 * 94 * @param a hash algorithm name. 95 * @param o object to hash. 96 * @param u URIs of the hashed data. 97 * 98 * @deprecated use {@link #Hash(jsdsi.util.DigestAlgoEnum, Obj, URI[])} 99 */ 100 public Hash(String a, Obj o, URI[] u) { 101 this(DigestAlgoEnum.fromSpki(a), o, u); 102 } 103 104 /*** 105 * Creates a new <code>Hash</code> from an algorithm name and a byte array 106 * that contains a hash value. 107 * 108 * @param a name of the hash algorithm used. 109 * @param d the value of the hash (<i>not</i> the data to hash). 110 * 111 * @deprecated use {@link #Hash(jsdsi.util.DigestAlgoEnum, byte[], java.net.URI[])} 112 */ 113 public Hash(String a, byte[] d) { 114 this(a, d, null); 115 } 116 117 /*** 118 * Creates a new <code>Hash</code> from an algorithm name and an object. 119 * 120 * @param a name of the hash algorithm used. 121 * @param o JSDSI object to calculate the hash value from. 122 * 123 * @deprecated use {@link #Hash(jsdsi.util.DigestAlgoEnum, jsdsi.Obj, java.net.URI[])} 124 */ 125 public Hash(String a, Obj o) { 126 this(a, o, null); 127 } 128 129 130 /*** 131 * Creates a new <code>Hash</code> using a given algorithm name, a 132 * value to hash, and an array of URIs. 133 * 134 * @param a hash algorithm 135 * @param d data to hash 136 * @param u URIs of the data to hash 137 * @return the created Hash object (may be <code>null</code>) 138 */ 139 public static Hash create(DigestAlgoEnum a, byte[] d, URI[] u) { 140 return create(a, new ByteArrayInputStream(d), u); 141 } 142 143 /*** 144 * Creates a new <code>Hash</code> of the data from the given 145 * InputStream, using the given algorithm 146 * @param a hash algorithm 147 * @param is data to hash 148 * @param u URIs of the data being hashed (may be <code>null</code>) 149 * @return the created Hash object 150 */ 151 public static Hash create(DigestAlgoEnum a, InputStream is, URI[] u) { 152 assert(a != null) : "null algo"; 153 assert(is != null) : "null data"; 154 MessageDigest digester = DigestUtils.getDigest(a); 155 Iterator it = new jsdsi.util.InputStreamIterator(is); 156 while (it.hasNext()) { 157 digester.update( (byte[]) it.next() ); 158 } 159 byte[] value = digester.digest(); 160 return new Hash(a, value, u); 161 } 162 163 /*** 164 * Creates a new <code>Hash</code> using a given algorithm name, a 165 * value to hash, and an array of URIs. 166 * 167 * @param a hash algorithm name 168 * @param d data to hash 169 * @param u URIs of the data to hash 170 * @return the created Hash object 171 * 172 * @deprecated use {@link Hash#create(jsdsi.util.DigestAlgoEnum, byte[], java.net.URI[])} 173 */ 174 public static Hash create(String a, 175 byte[] d, 176 URI[] u) throws NoSuchAlgorithmException { 177 return create(DigestAlgoEnum.fromJdk(a), 178 new ByteArrayInputStream(d), u); 179 } 180 181 /*** 182 * Creates a new <code>Hash</code> of the data from the given 183 * InputStream, using the given algorithm. 184 * @param a hash algorithm name 185 * @param is data to hash 186 * @param u URIs of the data being hashed 187 * @return the created Hash object 188 * 189 * @deprecated use {@link Hash#create(jsdsi.util.DigestAlgoEnum, java.io.InputStream, java.net.URI[])} 190 */ 191 public static Hash create(String a, 192 InputStream is, 193 URI[] u) throws NoSuchAlgorithmException { 194 return create(DigestAlgoEnum.fromJdk(a), is, u); 195 } 196 197 /*** 198 * @return the digest for this Hash 199 */ 200 public DigestAlgoEnum getDigest() { 201 return this.digest; 202 } 203 204 /*** 205 * @return the JDK name of the hash algorithm. 206 */ 207 public String getAlgorithm() { 208 return this.digest.jdkName(); 209 } 210 211 /*** 212 * @return the hash value. 213 */ 214 public byte[] getData() { 215 return data; 216 } 217 218 /*** 219 * @return the URIs of the hashed data. 220 */ 221 public URI[] getURIs() { 222 return uris; 223 } 224 225 public boolean equals(Object o) { 226 if (o instanceof Hash) { 227 Hash h = (Hash) o; 228 return this.digest.equals(h.digest) 229 && java.util.Arrays.equals(data, h.data) 230 && Util.equals(uris, h.uris); 231 } 232 return false; 233 } 234 235 /*** 236 * @see java.lang.Object#hashCode() 237 */ 238 public int hashCode() { 239 return this.digest.hashCode() 240 ^ Util.hashCode(this.data) 241 ^ Util.hashCode(this.uris); 242 } 243 244 public SexpList toSexp() { 245 List l = new ArrayList(3); 246 l.add(SexpUtil.toSexp(this.digest.spkiName())); 247 l.add(SexpUtil.toSexp(getData())); 248 if (getURIs() != null) { 249 l.add(SexpUtil.toSexp(getURIs())); 250 } 251 return SexpUtil.toSexp("hash", l); 252 } 253 254 public static Hash parseHash(SexpList l) throws SexpParseException { 255 Iterator hbody = SexpUtil.getBody(l); 256 String algo = SexpUtil.getNextString(hbody, "hash algo"); 257 DigestAlgoEnum digest = calculateDigestEnum(algo); 258 byte[] data = SexpUtil.getNextByteArray(hbody, "hash data"); 259 SexpUtil.checkDone(hbody, "hash"); // TODO: support URIs 260 return new Hash(digest, data, null); 261 } 262 263 /*** 264 * Temporary method to cope with legacy certificates/signatures 265 * which incorrectly have JDK algorithm names in their SExpression. 266 * @param algo 267 * @return 268 * @todo Method should be removed in the future when legacy data is 269 * no longer an issue 270 */ 271 static DigestAlgoEnum calculateDigestEnum(String algo) { 272 try { 273 return DigestAlgoEnum.fromSpki(algo); 274 } catch (JsdsiRuntimeException e) { 275 // was not a SPKI algo name, so was it a legacy JDK one... 276 return DigestAlgoEnum.fromJdk(algo); 277 } 278 } 279 }

This page was automatically generated by Maven