package com.trilead.ssh2.crypto.digest;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.List;
public final class MessageMac extends MAC {
private final Mac messageMac;
public MessageMac(String type, byte[] key) {
super(type, key);
try {
messageMac = Mac.getInstance(Hmac.getHmac(type).getAlgorithm());
messageMac.init(new SecretKeySpec(key, type));
} catch (GeneralSecurityException ex) {
throw new IllegalArgumentException("Could not create Mac", ex);
}
}
public static String[] getMacs() {
List<String> macList = new ArrayList<String>();
for (Hmac hmac : Hmac.values()) {
macList.add(0, hmac.getType());
}
return macList.toArray(new String[macList.size()]);
}
public static void checkMacs(String[] macs) {
for (String mac : macs) {
Hmac.getHmac(mac);
}
}
public static int getKeyLength(String type) {
return Hmac.getHmac(type).getLength();
}
public final void initMac(int seq) {
messageMac.reset();
messageMac.update((byte) (seq >> 24));
messageMac.update((byte) (seq >> 16));
messageMac.update((byte) (seq >> 8));
messageMac.update((byte) (seq));
}
public final void update(byte[] packetdata, int off, int len)
{
messageMac.update(packetdata, off, len);
}
public final void getMac(byte[] out, int off) {
byte[] mac = messageMac.doFinal();
System.arraycopy(mac, off, out, 0, mac.length - off);
}
public final int size()
{
return messageMac.getMacLength();
}
private enum Hmac {
HMAC_MD5_96("hmac-md5-96", "HmacMD5", 16),
HMAC_MD5("hmac-md5", "HmacMD5", 16),
HMAC_SHA1_96("hmac-sha1-96", "HmacSHA1", 20),
HMAC_SHA1("hmac-sha1", "HmacSHA1", 20),
HMAC_SHA2_256("hmac-sha2-256", "HmacSHA256", 32),
HMAC_SHA2_512("hmac-sha2-512", "HmacSHA512", 64);
private String type;
private String algorithm;
private int length;
Hmac(String type, String algorithm, int length) {
this.type = type;
this.algorithm = algorithm;
this.length = length;
}
public String getType() {
return type;
}
public String getAlgorithm() {
return algorithm;
}
public int getLength() {
return length;
}
private static Hmac getHmac(String type) {
for (Hmac hmac : values()) {
if (hmac.getType().equals(type)) {
return hmac;
}
}
throw new IllegalArgumentException("Invalid HMAC type: " + type);
}
}
}