FileDocCategorySizeDatePackage
CryptoHandlerECC.javaAPI DocAzureus 3.0.3.416461Sun Jul 09 04:32:14 BST 2006com.aelitis.azureus.core.security.impl

CryptoHandlerECC

public class CryptoHandlerECC extends Object implements com.aelitis.azureus.core.security.CryptoHandler

Fields Summary
private static final org.bouncycastle.jce.spec.ECNamedCurveParameterSpec
ECCparam
private static final byte[]
ECIES_D
private static final byte[]
ECIES_E
private static final int
TIMEOUT_DEFAULT_SECS
private CryptoManagerImpl
manager
private String
CONFIG_PREFIX
private PrivateKey
use_method_private_key
private PublicKey
use_method_public_key
private long
last_unlock_time
Constructors Summary
protected CryptoHandlerECC(CryptoManagerImpl _manager, int _instance_id)

	
	
	
				
								 
	
		manager	= _manager;
		
		CONFIG_PREFIX += _instance_id + ".";
	
Methods Summary
public synchronized voidchangePassword(char[] old_password, char[] new_password)

			// ensure old password is correct
		
		use_method_private_key	= null;
		use_method_public_key	= null;
		
		getMyPrivateKey( old_password, "" );
		getMyPublicKey( old_password, "" );
		
		storeKeys( new_password );
	
protected voidcreateAndStoreKeys(char[] password, java.lang.String reason)

		if ( password == null ){
			
			password = manager.getPassword( 
							CryptoManager.HANDLER_ECC,
							CryptoManagerPasswordHandler.ACTION_ENCRYPT,
							reason );
		}
		
		KeyPair	keys = createKeys();
		
		use_method_public_key	= keys.getPublic();
		
		use_method_private_key	= keys.getPrivate();
		
		storeKeys( password );
	
protected java.security.KeyPaircreateKeys()

		try
		{
			KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
			
			keyGen.initialize(ECCparam);

			return keyGen.genKeyPair();
			
		}catch(Throwable e){
			
			throw( new CryptoManagerException( "Failed to create keys", e ));
		}
	
public byte[]decrypt(byte[] other_public_key, byte[] data, char[] password)

		return( decrypt( other_public_key, data, password, null ));
	
public byte[]decrypt(byte[] other_public_key, byte[] data, java.lang.String reason)

		return( decrypt( other_public_key, data, null, reason ));
	
protected byte[]decrypt(byte[] other_public_key, byte[] data, char[] password, java.lang.String reason)

	        
		try{
			IEKeySpec   key_spec = new IEKeySpec( getMyPrivateKey( password, reason ), rawdataToPubkey( other_public_key ));
	 	
			IESParameterSpec param = new IESParameterSpec(ECIES_D, ECIES_E, 128);
		
			InternalECIES	cipher = new InternalECIES();
	
			cipher.internalEngineInit( Cipher.DECRYPT_MODE, key_spec, param, null ); 
		
			return( cipher.internalEngineDoFinal(data, 0, data.length ));
			
		}catch( CryptoManagerException e ){
			
			throw( e );
			
		}catch( Throwable e){
			
			throw( new CryptoManagerException( "Decrypt failed", e ));
		}
	
public byte[]encrypt(byte[] other_public_key, byte[] data, char[] password)

		return( encrypt( other_public_key, data, password, null ));
	
public byte[]encrypt(byte[] other_public_key, byte[] data, java.lang.String reason)

		return( encrypt( other_public_key, data, null, reason ));
	
protected byte[]encrypt(byte[] other_public_key, byte[] data, char[] password, java.lang.String reason)

	        
		try{
			IEKeySpec   key_spec = new IEKeySpec( getMyPrivateKey( password, reason ), rawdataToPubkey( other_public_key ));
	 
			IESParameterSpec param = new IESParameterSpec(ECIES_D, ECIES_E, 128);
		
			InternalECIES	cipher = new InternalECIES();
	
			cipher.internalEngineInit( Cipher.ENCRYPT_MODE, key_spec, param, null ); 
		
			return( cipher.internalEngineDoFinal(data, 0, data.length ));
			
		}catch( CryptoManagerException e ){
			
			throw( e );
			
		}catch( Throwable e){
			
			throw( new CryptoManagerException( "Encrypt failed", e ));
		}
	
public byte[]getEncryptedPrivateKey(char[] password)

		return( getEncryptedPrivateKey( password, null ));
	
public byte[]getEncryptedPrivateKey(java.lang.String reason)

		return( getEncryptedPrivateKey( null, reason ));
	
protected byte[]getEncryptedPrivateKey(char[] password, java.lang.String reason)

		getMyPrivateKey( password, reason );
		
		byte[]	res = COConfigurationManager.getByteParameter( CONFIG_PREFIX + "privatekey", null );
		
		if ( res == null ){
			
			throw( new CryptoManagerException( "Private key unavailable" ));
		}
		
		return( res );
	
protected synchronized java.security.PrivateKeygetMyPrivateKey(char[] password, java.lang.String reason)

		if ( use_method_private_key != null ){
			
			int	timeout_secs = getUnlockTimeoutSeconds();
			
			if ( timeout_secs > 0 ){
				
				if ( SystemTime.getCurrentTime() - last_unlock_time >= timeout_secs * 1000 ){
					
					use_method_private_key = null;
				}
			}
		}
		
		if ( use_method_private_key == null ){
			
			byte[]	encoded = COConfigurationManager.getByteParameter( CONFIG_PREFIX + "privatekey", null );
			
			if ( encoded == null ){
				
				createAndStoreKeys( password, reason );
				
			}else{
				
				if ( password == null ){
					
					password = manager.getPassword( 
									CryptoManager.HANDLER_ECC, 
									CryptoManagerPasswordHandler.ACTION_DECRYPT, 
									reason );
				}

				use_method_private_key = rawdataToPrivkey( manager.decryptWithPBE( encoded, password ));
				
				last_unlock_time = SystemTime.getCurrentTime();
				
				boolean		ok = false;
				
				try{
					byte[]	test_data = "test".getBytes();
					
					ok = verify( keyToRawdata( getMyPublicKey( password, reason )), test_data,  sign( test_data, password, reason ));
					
					if ( !ok ){
											
						throw( new CryptoManagerPasswordException());
						
					}
					
				}catch( CryptoManagerException e ){
					
					throw( e );
					
				}catch( Throwable e ){
					
					throw( new CryptoManagerException( "Password incorrect", e ));
					
				}finally{
					
					if ( !ok ){
						
						use_method_private_key	= null;
					}
				}
			}
		}
		
		if ( use_method_private_key == null ){
			
			throw( new CryptoManagerException( "Failed to get private key" ));
		}
		
		return( use_method_private_key );
	
protected synchronized java.security.PublicKeygetMyPublicKey(char[] password, java.lang.String reason)

		if ( use_method_public_key == null ){
			
			byte[]	key_bytes = COConfigurationManager.getByteParameter( CONFIG_PREFIX + "publickey", null );
			
			if ( key_bytes == null ){
				
				createAndStoreKeys( password, reason );
				
			}else{
				
				use_method_public_key = rawdataToPubkey( key_bytes );
			}
		}
		
		if ( use_method_public_key == null ){
			
			throw( new CryptoManagerException( "Failed to get public key" ));
		}
		
		return( use_method_public_key );
	
public byte[]getPublicKey(char[] password)

		return( keyToRawdata( getMyPublicKey( password, null )));
	
public byte[]getPublicKey(java.lang.String reason)

		return( keyToRawdata( getMyPublicKey( null, reason )));
	
protected byte[]getPublicKey(char[] password, java.lang.String reason)

		return( keyToRawdata( getMyPublicKey( password, reason )));
	
public com.aelitis.azureus.core.security.CryptoSTSEnginegetSTSEngine(char[] password)

		return( getSTSEngine( password, null ));
	
public com.aelitis.azureus.core.security.CryptoSTSEnginegetSTSEngine(java.lang.String reason)

		return( getSTSEngine( null, reason ));
	
protected com.aelitis.azureus.core.security.CryptoSTSEnginegetSTSEngine(char[] password, java.lang.String reason)

		return( new CryptoSTSEngineImpl( this, getMyPublicKey( password, reason ), getMyPrivateKey( password, reason )));
	
public java.security.SignaturegetSignature(java.security.Key key)

		try
		{
			Signature ECCsig = Signature.getInstance("SHA1withECDSA", "BC");
			
			if( key instanceof ECPrivateKey ){
				
				ECCsig.initSign((ECPrivateKey)key);
				
			}else if( key instanceof ECPublicKey ){
				
				ECCsig.initVerify((ECPublicKey)key);

			}else{
				
				throw new CryptoManagerException("Invalid Key Type, ECC keys required");
			}
			
			return ECCsig;
			
		}catch( CryptoManagerException e ){
		
			throw( e );
			
		}catch( Throwable e ){
			
			throw( new CryptoManagerException( "Failed to create Signature", e ));
		}
	
public intgetUnlockTimeoutSeconds()

		return( COConfigurationManager.getIntParameter( CONFIG_PREFIX + "timeout", TIMEOUT_DEFAULT_SECS ));
	
protected byte[]keyToRawdata(java.security.PrivateKey privkey)

		if(!(privkey instanceof ECPrivateKey)){
			
			throw( new CryptoManagerException( "Invalid private key" ));
		}
		
		return ((ECPrivateKey)privkey).getD().toByteArray();
	
protected byte[]keyToRawdata(java.security.PublicKey pubkey)

		if(!(pubkey instanceof ECPublicKey)){
			
			throw( new CryptoManagerException( "Invalid public key" ));
		}
		
		return ((ECPublicKey)pubkey).getQ().getEncoded();
	
public synchronized voidlock()

		use_method_private_key	= null;
	
protected java.security.PrivateKeyrawdataToPrivkey(byte[] input)

		BigInteger D = new BigInteger(input);
		
		KeySpec keyspec = new ECPrivateKeySpec(D,(ECParameterSpec)ECCparam);
		
		PrivateKey privkey = null;
		
		try{
			privkey = KeyFactory.getInstance("ECDSA","BC").generatePrivate(keyspec);
			
			return privkey;
			
		}catch( Throwable e ){
	
			throw( new CryptoManagerException( "Failed to decode private key" ));
		}
	
protected java.security.PublicKeyrawdataToPubkey(byte[] input)

		ECPoint W = ECCparam.getCurve().decodePoint(input);
		
		KeySpec keyspec = new ECPublicKeySpec(W,(ECParameterSpec)ECCparam);

		try{
			
			return KeyFactory.getInstance("ECDSA", "BC").generatePublic(keyspec);
			
		}catch (Throwable e){
		
			throw( new CryptoManagerException( "Failed to decode private key" ));
		}
	
public synchronized voidrecoverKeys(byte[] public_key, byte[] encrypted_private_key)

		use_method_private_key	= null;
		use_method_public_key	= null;
		
		COConfigurationManager.setParameter( CONFIG_PREFIX + "publickey", public_key );
			
		COConfigurationManager.setParameter( CONFIG_PREFIX + "privatekey", encrypted_private_key );
		
		COConfigurationManager.save();
	
public synchronized voidresetKeys(char[] password)

		use_method_private_key	= null;
		use_method_public_key	= null;
		
		COConfigurationManager.removeParameter( CONFIG_PREFIX + "publickey" );
			
		COConfigurationManager.removeParameter( CONFIG_PREFIX + "privatekey" );
		
		COConfigurationManager.save();
		
		createAndStoreKeys( password, "" );
	
public voidsetUnlockTimeoutSeconds(int secs)

		COConfigurationManager.setParameter( CONFIG_PREFIX + "timeout", secs );
	
public byte[]sign(byte[] data, char[] password)

		return( sign( data, password, null ));
	
public byte[]sign(byte[] data, java.lang.String reason)

		return( sign( data, null, reason ));
	
protected byte[]sign(byte[] data, char[] password, java.lang.String reason)

		PrivateKey	priv = getMyPrivateKey( password, reason );
		
		Signature sig = getSignature( priv );
		
		try{
			sig.update( data );
			
			return( sig.sign());
			
		}catch( Throwable e ){
			
			throw( new CryptoManagerException( "Signature failed", e ));
		}
	
protected voidstoreKeys(char[] password)

		COConfigurationManager.setParameter( CONFIG_PREFIX + "publickey", keyToRawdata( use_method_public_key ));
		
		byte[]	priv_raw = keyToRawdata( use_method_private_key );
		
		byte[]	priv_enc = manager.encryptWithPBE( priv_raw, password );
		
		COConfigurationManager.setParameter( CONFIG_PREFIX + "privatekey", priv_enc );

		COConfigurationManager.save();
	
public voidunlock(char[] password)

		getMyPrivateKey( password, "" );
	
public booleanverify(byte[] public_key, byte[] data, byte[] signature)

		PublicKey	pub = rawdataToPubkey( public_key );
		
		Signature sig = getSignature( pub );
		
		try{
			sig.update( data );
			
			return( sig.verify( signature ));
			
		}catch( Throwable e ){
			
			throw( new CryptoManagerException( "Signature failed", e ));
		}