/* This code is part of Freenet. It is distributed under the GNU General
* Public License, version 2 (or at your option any later version). See
* http://www.gnu.org/ for further details of the GPL. */
package freenet.crypt;
import java.io.Serializable;
import java.security.InvalidKeyException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import freenet.support.Logger;
/**
* MasterSecret is a serializable secret used to derive various keys and ivs for local storage in
* Freenet.
* @author unixninja92
*
*/
public final class MasterSecret implements Serializable{
private static final long serialVersionUID = -8411217325990445764L;
private final SecretKey masterKey;
/**
* Creates a new MasterSecret.
*/
public MasterSecret(){
masterKey = KeyGenUtils.genSecretKey(KeyType.HMACSHA512);
}
public MasterSecret(byte[] secret) {
if(secret.length != 64) throw new IllegalArgumentException();
masterKey = KeyGenUtils.getSecretKey(KeyType.HMACSHA512, secret);
}
/**
* Derives a SecretKey of the specified type from the MasterSecret.
* @param type The type of key to derive
* @return The derived key
*/
public SecretKey deriveKey(KeyType type){
try {
return KeyGenUtils.deriveSecretKey(masterKey, getClass(), type.name()+" key", type);
} catch (InvalidKeyException e) {
throw new IllegalStateException(e); // Definitely a bug.
}
}
/**
* Derives a IvParameterSpec of the specified type from the MasterSecret.
* @param type The type of iv to derive
* @return The derived iv
*/
public IvParameterSpec deriveIv(KeyType type){
try {
return KeyGenUtils.deriveIvParameterSpec(masterKey, getClass(), type.name()+" iv",
type);
} catch (InvalidKeyException e) {
throw new IllegalStateException(e); // Definitely a bug.
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((masterKey == null) ? 0 : masterKey.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
MasterSecret other = (MasterSecret) obj;
return masterKey.equals(other.masterKey);
}
}