package abstrasy.libraries.crypt;
/**
* Abstrasy Interpreter
*
* Copyright : Copyright (c) 2006-2012, Luc Bruninx.
*
* Concédée sous licence EUPL, version 1.1 uniquement (la «Licence»).
*
* Vous ne pouvez utiliser la présente oeuvre que conformément à la Licence.
* Vous pouvez obtenir une copie de la Licence à l’adresse suivante:
*
* http://www.osor.eu/eupl
*
* Sauf obligation légale ou contractuelle écrite, le logiciel distribué sous
* la Licence est distribué "en l’état", SANS GARANTIES OU CONDITIONS QUELLES
* QU’ELLES SOIENT, expresses ou implicites.
*
* Consultez la Licence pour les autorisations et les restrictions
* linguistiques spécifiques relevant de la Licence.
*
*
* @author Luc Bruninx
* @version 1.0
*/
import abstrasy.Buffer;
import abstrasy.Node;
import abstrasy.externals.AExtCachable;
import abstrasy.externals.AExtTools;
import abstrasy.externals.OptAccess;
import abstrasy.externals.OptAccessList;
import abstrasy.externals.OptAccessProvider;
import abstrasy.interpreter.InterpreterException;
import abstrasy.interpreter.ORef;
import abstrasy.interpreter.StdErrors;
import abstrasy.libraries.io.External_Buffer;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
public class External_Blowfish extends OptAccessProvider implements AExtCachable {
private int keySize = 128; // [32..448]
private Key secretKey;
private OptAccess oa_key_size = new OptAccess("key-size") {
public Node getNode() {
return new Node(keySize);
}
public void setNode(Node optNode) throws Exception {
optNode.requireNodeType(Node.TYPE_NUMBER);
setKeySize((int) optNode.getNumber());
generateKey();
}
};
private OptAccess oa_secret_key = new OptAccess("secret-key") {
public Node getNode() throws Exception {
External_Buffer res = new External_Buffer();
if (secretKey != null) {
Buffer bu = new Buffer();
bu.write_bytes(secretKey.getEncoded());
res.setBuffer(bu);
}
return Node.createExternal(res);
}
public void setNode(Node optNode) throws Exception {
Buffer data = ((External_Buffer) AExtTools.getObjectFromExternalInstance(optNode, External_Buffer.class, Node.ACCESSVTYPE_MUTABLE_WRITELOCK)).getBuffer();
byte[] keyData = data.getArray();
setKeySize(keyData.length * 8);
setSecretKey(keyData);
}
};
private OptAccess[] DEFAULT_OPTIONS = new OptAccess[] { oa_key_size,
oa_secret_key };
public External_Blowfish() throws NoSuchAlgorithmException {
generateKey();
this.setOptAccessList(new OptAccessList(DEFAULT_OPTIONS));
}
public Node external_encrypt(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
Buffer src = ((External_Buffer) AExtTools.getArgExternalInstance(startAt, 1, External_Buffer.class, Node.ACCESSVTYPE_MUTABLE_WRITELOCK)).getBuffer();
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
External_Buffer res = new External_Buffer();
Buffer bu = new Buffer(cipher.doFinal(src.getArray()));
res.setBuffer(bu);
return Node.createExternal(res);
}
public Node external_decrypt(Node startAt) throws Exception {
startAt.isGoodArgsCnt(2);
Buffer src = ((External_Buffer) AExtTools.getArgExternalInstance(startAt, 1, External_Buffer.class, Node.ACCESSVTYPE_MUTABLE_WRITELOCK)).getBuffer();
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
External_Buffer res = new External_Buffer();
Buffer bu = new Buffer(cipher.doFinal(src.getArray()));
res.setBuffer(bu);
return Node.createExternal(res);
}
/*
* ----------------------------------------------------------------------------
*
* Optimisation par cache d'instanciantion (mars 2012) rev 1.0-6321.0
*
* ----------------------------------------------------------------------------
*/
private static ORef _optim_symbols_cache_ = new ORef();
@Override
public Object getSymbolsCache() {
return _optim_symbols_cache_.getRef();
}
@Override
public void setSymbolsCache(Object cache) {
_optim_symbols_cache_.setRef(cache);
}
/*
* méthodes internes...
*/
public void generateKey() throws NoSuchAlgorithmException {
KeyGenerator keyGen = KeyGenerator.getInstance("Blowfish");
keyGen.init(keySize);
secretKey = keyGen.generateKey();
}
public void setSecretKey(Key secretKey) {
this.secretKey = secretKey;
}
public Key getSecretKey() {
return secretKey;
}
public void setSecretKey(byte[] keyData) {
secretKey = new SecretKeySpec(keyData, "Blowfish");
}
public void setKeySize(int keySize) throws InterpreterException {
if (keySize > 448 && keySize < 32)
throw new InterpreterException(StdErrors.extend(StdErrors.Out_of_range, "key size(" + keySize + ") not in [32..448]"));
this.keySize = keySize;
this.secretKey = null;
}
public int getKeySize() {
return secretKey.getEncoded().length;
}
}