CryptoSTSEngineImplpublic final class CryptoSTSEngineImpl extends Object implements com.aelitis.azureus.core.security.CryptoSTSEngineSTS authentication protocol using a symmetric 4 message ECDH/ECDSA handshake |
Fields Summary |
---|
public static final int | VERSION | private CryptoHandlerECC | handler | private KeyPair | ephemeralKeyPair | private PublicKey | myPublicKey | private PrivateKey | myPrivateKey | private PublicKey | remotePubKey | private byte[] | sharedSecret | private InternalDH | ecDH |
Constructors Summary |
---|
CryptoSTSEngineImpl(CryptoHandlerECC _handler, PublicKey _myPub, PrivateKey _myPriv)
handler = _handler;
myPublicKey = _myPub;
myPrivateKey = _myPriv;
ephemeralKeyPair = handler.createKeys();
try{
ecDH = new InternalDH();
//ecDH = KeyAgreement.getInstance("ECDH", "BC");
ecDH.init(ephemeralKeyPair.getPrivate());
}catch (Exception e){
throw new CryptoManagerException("Couldn't initialize crypto handshake", e);
}
|
Methods Summary |
---|
public void | getAuth(java.nio.ByteBuffer message)
getMessage( message, false );
| protected byte[] | getBytes(java.nio.ByteBuffer buffer, int max_size)
int len = getInt( buffer, max_size );
if ( len > max_size ){
throw( new CryptoManagerException( "Invalid length" ));
}
try{
byte[] res = new byte[len];
buffer.get( res );
return( res );
}catch( Throwable e ){
throw( new CryptoManagerException( "Failed to get byte[]", e ));
}
| protected int | getInt(java.nio.ByteBuffer buffer, int max_size)
try{
if ( max_size < 256 ){
return( buffer.get() & 0xff);
}else if ( max_size < 65536 ){
return( buffer.getShort() & 0xffff);
}else{
return( buffer.getInt());
}
}catch( Throwable e ){
throw( new CryptoManagerException( "Failed to get int", e ));
}
| public void | getKeys(java.nio.ByteBuffer message)
getMessage( message, true );
| public void | getMessage(java.nio.ByteBuffer buffer, boolean keys)
// System.out.println( "get( " + keys + ") " + this );
try{
putInt( buffer, VERSION, 255 );
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
Signature sig = handler.getSignature(myPrivateKey);
if ( keys ){
final byte[] rawMyPubkey = handler.keyToRawdata(myPublicKey);
final byte[] rawEphemeralPubkey = handler.keyToRawdata(ephemeralKeyPair.getPublic());
sig.update(rawMyPubkey);
sig.update(rawEphemeralPubkey);
final byte[] rawSign = sig.sign();
final byte[] pad = new byte[random.nextInt(32)];
random.nextBytes(pad);
putBytes( buffer, rawMyPubkey, 65535 );
putBytes( buffer, rawEphemeralPubkey, 65535 );
putBytes( buffer, rawSign, 65535 );
putBytes( buffer, pad, 65535 );
}else{
if ( sharedSecret == null ){
throw( new CryptoManagerException( "phase error: keys not received" ));
}
final byte[] IV = new byte[20 + random.nextInt(32)];
random.nextBytes(IV);
sig.update(IV);
sig.update(sharedSecret);
final byte[] rawSig = sig.sign();
putBytes( buffer, IV, 65535 );
putBytes( buffer, rawSig, 65535 );
}
}catch( CryptoManagerException e ){
throw( e );
}catch( Throwable e ){
throw( new CryptoManagerException( "Failed to generate message" ));
}
| public byte[] | getRemotePublicKey()
if ( remotePubKey == null ){
throw( new CryptoManagerException( "key not yet available" ));
}
return( handler.keyToRawdata( remotePubKey ));
| public byte[] | getSharedSecret()
if ( sharedSecret == null ){
throw( new CryptoManagerException( "secret not yet available" ));
}
return sharedSecret;
| public void | putAuth(java.nio.ByteBuffer message)
putMessage( message, false );
| protected void | putBytes(java.nio.ByteBuffer buffer, byte[] value, int max_size)
putInt( buffer, value.length, max_size );
try{
buffer.put( value );
}catch( Throwable e ){
throw( new CryptoManagerException( "Failed to put byte[]", e ));
}
| protected void | putInt(java.nio.ByteBuffer buffer, int value, int max_size)
try{
if ( max_size < 256 ){
buffer.put((byte)value);
}else if ( max_size < 65536 ){
buffer.putShort((short)value );
}else{
buffer.putInt( value );
}
}catch( Throwable e ){
throw( new CryptoManagerException( "Failed to put int", e ));
}
| public void | putKeys(java.nio.ByteBuffer message)
putMessage( message, true );
| public void | putMessage(java.nio.ByteBuffer message, boolean keys)
// System.out.println( "put( " + keys + ") " + this );
try{
int version = getInt( message, 255 );
if ( version != VERSION ){
throw( new CryptoManagerException( "invalid version (" + version + ")" ));
}
if ( keys ){
if ( sharedSecret != null ){
throw( new CryptoManagerException( "phase error: keys already received" ));
}
final byte[] rawRemoteOtherPubkey = getBytes( message, 65535 );
final byte[] rawRemoteEphemeralPubkey = getBytes( message, 65535 );
final byte[] remoteSig = getBytes( message, 65535 );
final byte[] pad = getBytes( message, 65535 );
remotePubKey = handler.rawdataToPubkey(rawRemoteOtherPubkey);
Signature check = handler.getSignature(remotePubKey);
check.update(rawRemoteOtherPubkey);
check.update(rawRemoteEphemeralPubkey);
if ( check.verify(remoteSig)){
ecDH.doPhase(handler.rawdataToPubkey(rawRemoteEphemeralPubkey), true);
sharedSecret = ecDH.generateSecret();
}else{
throw( new CryptoManagerException( "Signature check failed" ));
}
}else{
if ( sharedSecret == null ){
throw( new CryptoManagerException( "phase error: keys not received" ));
}
final byte[] IV = getBytes( message, 65535 );
final byte[] remoteSig = getBytes( message, 65535);
Signature check = handler.getSignature( remotePubKey );
check.update(IV);
check.update(sharedSecret);
if ( !check.verify(remoteSig)){
throw( new CryptoManagerException( "Signature check failed" ));
}
}
}catch( CryptoManagerException e ){
throw( e );
}catch( Throwable e ){
throw( new CryptoManagerException( "Failed to generate message" ));
}
|
|