use of javax.crypto.interfaces.DHPublicKey in project Zom-Android by zom.
the class SessionImpl method transformSending.
// Retransmit last sent message. Spec document does not mention where or
// when that should happen, must check libotr code.
public String transformSending(String msgText, List<TLV> tlvs) throws OtrException {
switch(this.getSessionStatus()) {
case PLAINTEXT:
if (getSessionPolicy().getRequireEncryption()) {
lastSentMessage = msgText;
doTransmitLastMessage = true;
this.startSession();
return null;
} else
// specification.
return msgText;
case ENCRYPTED:
this.lastSentMessage = msgText;
if (DEBUG_ENABLED)
Log.d(LOG_TAG, getSessionID().getLocalUserId() + " sends an encrypted message to " + getSessionID().getRemoteUserId() + " through " + getSessionID().getProtocolName() + ".");
// Get encryption keys.
SessionKeys encryptionKeys = this.getEncryptionSessionKeys();
int senderKeyID = encryptionKeys.getLocalKeyID();
int receipientKeyID = encryptionKeys.getRemoteKeyID();
// Increment CTR.
encryptionKeys.incrementSendingCtr();
byte[] ctr = encryptionKeys.getSendingCtr();
ByteArrayOutputStream out = new ByteArrayOutputStream();
if (msgText != null && msgText.length() > 0)
try {
out.write(msgText.getBytes("UTF8"));
} catch (IOException e) {
throw new OtrException(e);
}
// Append tlvs
if (tlvs != null && tlvs.size() > 0) {
out.write((byte) 0x00);
OtrOutputStream eoos = new OtrOutputStream(out);
for (TLV tlv : tlvs) {
try {
eoos.writeShort(tlv.type);
eoos.writeTlvData(tlv.value);
eoos.close();
} catch (IOException e) {
throw new OtrException(e);
}
}
}
OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
byte[] data = out.toByteArray();
// Encrypt message.
if (DEBUG_ENABLED)
Log.d(LOG_TAG, "Encrypting message with keyids (localKeyID, remoteKeyID) = (" + senderKeyID + ", " + receipientKeyID + ")");
byte[] encryptedMsg = otrCryptoEngine.aesEncrypt(encryptionKeys.getSendingAESKey(), ctr, data);
// Get most recent keys to get the next D-H public key.
SessionKeys mostRecentKeys = this.getMostRecentSessionKeys();
DHPublicKey nextDH = (DHPublicKey) mostRecentKeys.getLocalPair().getPublic();
// Calculate T.
MysteriousT t = new MysteriousT(2, 0, senderKeyID, receipientKeyID, nextDH, ctr, encryptedMsg);
// Calculate T hash.
byte[] sendingMACKey = encryptionKeys.getSendingMACKey();
if (DEBUG_ENABLED)
Log.d(LOG_TAG, "Transforming T to byte[] to calculate it's HmacSHA1.");
byte[] serializedT;
try {
serializedT = SerializationUtils.toByteArray(t);
} catch (IOException e) {
throw new OtrException(e);
}
byte[] mac = otrCryptoEngine.sha1Hmac(serializedT, sendingMACKey, SerializationConstants.TYPE_LEN_MAC);
// Get old MAC keys to be revealed.
byte[] oldKeys = this.collectOldMacKeys();
DataMessage m = new DataMessage(t, mac, oldKeys);
try {
return SerializationUtils.toString(m);
} catch (IOException e) {
throw new OtrException(e);
}
case FINISHED:
this.lastSentMessage = msgText;
showError("Your message to " + sessionID.getRemoteUserId() + " was not sent. Either end your private conversation, or restart it.");
return null;
default:
if (DEBUG_ENABLED)
Log.d(LOG_TAG, "Unknown message state, not processing.");
return msgText;
}
}
use of javax.crypto.interfaces.DHPublicKey in project Zom-Android by zom.
the class IOTest method testIODHPublicKey.
public void testIODHPublicKey() throws Exception {
KeyPair pair = new OtrCryptoEngineImpl().generateDHKeyPair();
DHPublicKey source = (DHPublicKey) pair.getPublic();
ByteArrayOutputStream out = new ByteArrayOutputStream();
OtrOutputStream oos = new OtrOutputStream(out);
oos.writeDHPublicKey(source);
oos.close();
byte[] converted = out.toByteArray();
ByteArrayInputStream bin = new ByteArrayInputStream(converted);
OtrInputStream ois = new OtrInputStream(bin);
DHPublicKey result = ois.readDHPublicKey();
ois.close();
assertTrue(source.getY().compareTo(result.getY()) == 0);
}
use of javax.crypto.interfaces.DHPublicKey in project Zom-Android by zom.
the class IOTest method testIOBigInt.
public void testIOBigInt() throws Exception {
KeyPair pair = new OtrCryptoEngineImpl().generateDHKeyPair();
BigInteger source = ((DHPublicKey) pair.getPublic()).getY();
ByteArrayOutputStream out = new ByteArrayOutputStream();
OtrOutputStream oos = new OtrOutputStream(out);
oos.writeBigInt(source);
oos.close();
byte[] converted = out.toByteArray();
ByteArrayInputStream bin = new ByteArrayInputStream(converted);
OtrInputStream ois = new OtrInputStream(bin);
BigInteger result = ois.readBigInt();
ois.close();
assertTrue(source.compareTo(result) == 0);
}
use of javax.crypto.interfaces.DHPublicKey in project Zom-Android by zom.
the class AuthContextImpl method handleRevealSignatureMessage.
private void handleRevealSignatureMessage(RevealSignatureMessage m) throws OtrException {
Session session = getSession();
SessionID sessionID = session.getSessionID();
logger.finest(sessionID.getLocalUserId() + " received a reveal signature message from " + sessionID.getRemoteUserId() + " throught " + sessionID.getProtocolName() + ".");
if (!session.getSessionPolicy().getAllowV2()) {
logger.finest("Policy does not allow OTRv2, ignoring message.");
return;
}
switch(this.getAuthenticationState()) {
case AWAITING_REVEALSIG:
// Use the received value of r to decrypt the value of gx
// received
// in the D-H Commit Message, and verify the hash therein.
// Decrypt
// the encrypted signature, and verify the signature and the
// MACs.
// If everything checks out:
// * Reply with a Signature Message.
// * Transition authstate to AUTHSTATE_NONE.
// * Transition msgstate to MSGSTATE_ENCRYPTED.
// * TODO If there is a recent stored message, encrypt it and
// send
// it as a Data Message.
OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
// Uses r to decrypt the value of gx sent earlier
byte[] remoteDHPublicKeyDecrypted = otrCryptoEngine.aesDecrypt(m.revealedKey, null, this.getRemoteDHPublicKeyEncrypted());
// Verifies that HASH(gx) matches the value sent earlier
byte[] remoteDHPublicKeyHash = otrCryptoEngine.sha256Hash(remoteDHPublicKeyDecrypted);
if (!Arrays.equals(remoteDHPublicKeyHash, this.getRemoteDHPublicKeyHash())) {
logger.finest("Hashes don't match, ignoring message.");
return;
}
// Verifies that Bob's gx is a legal value (2 <= gx <=
// modulus-2)
BigInteger remoteDHPublicKeyMpi;
try {
remoteDHPublicKeyMpi = SerializationUtils.readMpi(remoteDHPublicKeyDecrypted);
} catch (IOException e) {
throw new OtrException(e);
}
this.setRemoteDHPublicKey(otrCryptoEngine.getDHPublicKey(remoteDHPublicKeyMpi));
// Verify received Data.
if (!m.verify(this.getM2())) {
logger.finest("Signature MACs are not equal, ignoring message.");
return;
}
// Decrypt X.
byte[] remoteXDecrypted = m.decrypt(this.getC());
SignatureX remoteX;
try {
remoteX = SerializationUtils.toMysteriousX(remoteXDecrypted);
} catch (IOException e) {
throw new OtrException(e);
}
// Compute signature.
PublicKey remoteLongTermPublicKey = remoteX.longTermPublicKey;
SignatureM remoteM = new SignatureM(this.getRemoteDHPublicKey(), (DHPublicKey) this.getLocalDHKeyPair().getPublic(), remoteLongTermPublicKey, remoteX.dhKeyID);
// Verify signature.
byte[] signature;
try {
signature = otrCryptoEngine.sha256Hmac(SerializationUtils.toByteArray(remoteM), this.getM1());
} catch (IOException e) {
throw new OtrException(e);
}
if (!otrCryptoEngine.verify(signature, remoteLongTermPublicKey, remoteX.signature)) {
session.showWarning("Bad revealed signature");
logger.finest("Signature verification failed.");
return;
}
logger.finest("Signature verification succeeded.");
this.setAuthenticationState(AuthContext.NONE);
this.setIsSecure(true);
this.setRemoteLongTermPublicKey(remoteLongTermPublicKey);
getSession().injectMessage(messageFactory.getSignatureMessage());
break;
default:
logger.finest("Ignoring message.");
break;
}
}
use of javax.crypto.interfaces.DHPublicKey in project Zom-Android by zom.
the class AuthContextImpl method handleSignatureMessage.
private void handleSignatureMessage(SignatureMessage m) throws OtrException {
Session session = getSession();
SessionID sessionID = session.getSessionID();
logger.finest(sessionID.getLocalUserId() + " received a signature message from " + sessionID.getRemoteUserId() + " throught " + sessionID.getProtocolName() + ".");
if (!session.getSessionPolicy().getAllowV2()) {
logger.finest("Policy does not allow OTRv2, ignoring message.");
return;
}
switch(this.getAuthenticationState()) {
case AWAITING_SIG:
// Verify MAC.
if (!m.verify(this.getM2p())) {
logger.finest("Signature MACs are not equal, ignoring message.");
return;
}
// Decrypt X.
byte[] remoteXDecrypted = m.decrypt(this.getCp());
SignatureX remoteX;
try {
remoteX = SerializationUtils.toMysteriousX(remoteXDecrypted);
} catch (IOException e) {
throw new OtrException(e);
}
// Compute signature.
PublicKey remoteLongTermPublicKey = remoteX.longTermPublicKey;
SignatureM remoteM = new SignatureM(this.getRemoteDHPublicKey(), (DHPublicKey) this.getLocalDHKeyPair().getPublic(), remoteLongTermPublicKey, remoteX.dhKeyID);
OtrCryptoEngine otrCryptoEngine = new OtrCryptoEngineImpl();
// Verify signature.
byte[] signature;
try {
signature = otrCryptoEngine.sha256Hmac(SerializationUtils.toByteArray(remoteM), this.getM1p());
} catch (IOException e) {
throw new OtrException(e);
}
if (!otrCryptoEngine.verify(signature, remoteLongTermPublicKey, remoteX.signature)) {
session.showWarning("Bad signature");
logger.finest("Signature verification failed.");
return;
}
this.setIsSecure(true);
this.setRemoteLongTermPublicKey(remoteLongTermPublicKey);
break;
default:
logger.finest("We were not expecting a signature, ignoring message.");
return;
}
}
Aggregations