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 = CryptoECCUtils.rawdataToPubkey(rawRemoteOtherPubkey);
Signature check = CryptoECCUtils.getSignature(remotePubKey);
check.update(rawRemoteOtherPubkey);
check.update(rawRemoteEphemeralPubkey);
if ( check.verify(remoteSig)){
ecDH.doPhase(CryptoECCUtils.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 = CryptoECCUtils.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" ));
}
}