Example usage for org.bouncycastle.crypto.params KeyParameter KeyParameter

List of usage examples for org.bouncycastle.crypto.params KeyParameter KeyParameter

Introduction

In this page you can find the example usage for org.bouncycastle.crypto.params KeyParameter KeyParameter.

Prototype

public KeyParameter(byte[] key, int keyOff, int keyLen) 

Source Link

Usage

From source file:ch.lamacrypt.internal.crypto.CPCipher.java

License:Open Source License

/**
 * Initializes Poly1305 with the given instance of ChaCha20Engine
 *
 * @param cipher// w  ww . ja  v  a2  s . com
 */
private void initMAC(ChaChaEngine cipher) {
    byte[] firstBlock = new byte[64];
    cipher.processBytes(firstBlock, 0, firstBlock.length, firstBlock, 0);

    // NOTE: The BC implementation puts 'r' after 'k'
    System.arraycopy(firstBlock, 0, firstBlock, 32, 16);
    KeyParameter macKey = new KeyParameter(firstBlock, 16, 32);
    Poly1305KeyGenerator.clamp(macKey.getKey());
    mac.init(macKey);
}

From source file:com.vmware.admiral.common.security.EncryptorService.java

License:Open Source License

private BufferedBlockCipher getCipher(boolean forEncryption) {
    BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()),
            new PKCS7Padding());
    cipher.init(forEncryption, new ParametersWithIV(
            new KeyParameter(keyBytes, IV_LENGTH, keyBytes.length - IV_LENGTH), keyBytes, 0, IV_LENGTH));
    return cipher;
}

From source file:freemail.OutboundContact.java

License:Open Source License

/**
 * Set up an outbound contact. Fetch the mailsite, generate a new SSK keypair and post an RTS message to the appropriate KSK.
 * Will block for mailsite retrieval and RTS insertion
 *
 * @return true for success/*from   w w  w.  j  a va 2  s .  c  o m*/
 */
private boolean init() throws ConnectionTerminatedException, InterruptedException {
    Logger.normal(this, "Initialising Outbound Contact " + address.toString());

    // try to fetch get all necessary info. will fetch mailsite / generate new keys if necessary
    String initialslot = this.getCurrentLowestSlot();
    SSKKeyPair commssk = this.getCommKeyPair();
    if (commssk == null)
        return false;
    SSKKeyPair ackssk = this.getAckKeyPair();
    RSAKeyParameters their_pub_key = this.getPubKey();
    if (their_pub_key == null)
        return false;
    String rtsksk = this.getRtsKsk();
    if (rtsksk == null)
        return false;

    StringBuffer rtsmessage = new StringBuffer();

    // the public part of the SSK keypair we generated
    rtsmessage.append("commssk=" + commssk.pubkey + "\r\n");

    rtsmessage.append("ackssk=" + ackssk.privkey + "\r\n");

    rtsmessage.append("initialslot=" + initialslot + "\r\n");

    rtsmessage.append("messagetype=rts\r\n");

    // must include who this RTS is to, otherwise we're vulnerable to surreptitious forwarding
    rtsmessage.append("to=" + this.address.getSubDomain() + "\r\n");

    // get our mailsite URI
    String our_mailsite_uri = account.getProps().get("mailsite.pubkey");

    rtsmessage.append("mailsite=" + our_mailsite_uri + "\r\n");

    rtsmessage.append("\r\n");
    //FreemailLogger.normal(this,rtsmessage.toString());

    // sign the message
    SHA256Digest sha256 = new SHA256Digest();
    sha256.update(rtsmessage.toString().getBytes(), 0, rtsmessage.toString().getBytes().length);
    byte[] hash = new byte[sha256.getDigestSize()];
    sha256.doFinal(hash, 0);

    RSAKeyParameters our_priv_key = AccountManager.getPrivateKey(account.getProps());

    AsymmetricBlockCipher sigcipher = new RSAEngine();
    sigcipher.init(true, our_priv_key);
    byte[] sig = null;
    try {
        sig = sigcipher.processBlock(hash, 0, hash.length);
    } catch (InvalidCipherTextException icte) {
        Logger.error(this, "Failed to RSA encrypt hash: " + icte.getMessage());
        icte.printStackTrace();
        return false;
    }

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    try {
        bos.write(rtsmessage.toString().getBytes());
        bos.write(sig);
    } catch (IOException ioe) {
        ioe.printStackTrace();
        return false;
    }

    // make up a symmetric key
    PaddedBufferedBlockCipher aescipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()),
            new PKCS7Padding());

    // quick paranoia check!
    if (aescipher.getBlockSize() != AES_BLOCK_LENGTH) {
        // bouncycastle must have changed their implementation, so 
        // we're in trouble
        Logger.normal(this,
                "Incompatible block size change detected in cryptography API! Are you using a newer version of the bouncycastle libraries? If so, we suggest you downgrade for now, or check for a newer version of Freemail.");
        return false;
    }

    byte[] aes_iv_and_key = this.getAESParams();

    // now encrypt that with our recipient's public key
    AsymmetricBlockCipher enccipher = new RSAEngine();
    enccipher.init(true, their_pub_key);
    byte[] encrypted_aes_params = null;
    try {
        encrypted_aes_params = enccipher.processBlock(aes_iv_and_key, 0, aes_iv_and_key.length);
    } catch (InvalidCipherTextException icte) {
        Logger.error(this,
                "Failed to perform asymmertic encryption on RTS symmetric key: " + icte.getMessage());
        icte.printStackTrace();
        return false;
    }

    // now encrypt the message with the symmetric key
    KeyParameter kp = new KeyParameter(aes_iv_and_key, aescipher.getBlockSize(), AES_KEY_LENGTH);
    ParametersWithIV kpiv = new ParametersWithIV(kp, aes_iv_and_key, 0, aescipher.getBlockSize());
    aescipher.init(true, kpiv);

    byte[] encmsg = new byte[aescipher.getOutputSize(bos.toByteArray().length) + encrypted_aes_params.length];
    System.arraycopy(encrypted_aes_params, 0, encmsg, 0, encrypted_aes_params.length);
    int offset = encrypted_aes_params.length;
    offset += aescipher.processBytes(bos.toByteArray(), 0, bos.toByteArray().length, encmsg, offset);

    try {
        aescipher.doFinal(encmsg, offset);
    } catch (InvalidCipherTextException icte) {
        Logger.error(this, "Failed to perform symmertic encryption on RTS data: " + icte.getMessage());
        icte.printStackTrace();
        return false;
    }

    // insert it!
    HighLevelFCPClient cli = new HighLevelFCPClient();
    if (cli.slotInsert(encmsg, "KSK@" + rtsksk + "-" + DateStringFactory.getKeyString(), 1, "") < 0) {
        // safe to copy the message into the contact outbox though
        return false;
    }

    // remember the fact that we have successfully inserted the rts
    this.contactfile.put("status", "rts-sent");
    // and remember when we sent it!
    this.contactfile.put("rts-sent-at", Long.toString(System.currentTimeMillis()));
    // and since that's been successfully inserted to that key, we can
    // throw away the symmetric key
    this.contactfile.remove("aesparams");

    Logger.normal(this, "Succesfully initialised Outbound Contact");

    return true;
}

From source file:freemail.RTSFetcher.java

License:Open Source License

private byte[] decrypt_rts(File rtsmessage) throws IOException, InvalidCipherTextException {
    // initialise our ciphers
    RSAKeyParameters ourprivkey = AccountManager.getPrivateKey(account.getProps());
    AsymmetricBlockCipher deccipher = new RSAEngine();
    deccipher.init(false, ourprivkey);/* ww  w .java  2s  .  co  m*/

    PaddedBufferedBlockCipher aescipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine()),
            new PKCS7Padding());

    // first n bytes will be an encrypted RSA block containting the
    // AES IV and Key. Read that.
    byte[] encrypted_params = new byte[deccipher.getInputBlockSize()];
    FileInputStream fis = new FileInputStream(rtsmessage);
    int read = 0;

    while (read < encrypted_params.length) {
        read += fis.read(encrypted_params, read, encrypted_params.length - read);
        if (read < 0)
            break;
    }

    if (read < 0) {
        throw new InvalidCipherTextException("RTS Message too short");
    }

    byte[] aes_iv_and_key = deccipher.processBlock(encrypted_params, 0, encrypted_params.length);

    KeyParameter kp = new KeyParameter(aes_iv_and_key, aescipher.getBlockSize(),
            aes_iv_and_key.length - aescipher.getBlockSize());
    ParametersWithIV kpiv = new ParametersWithIV(kp, aes_iv_and_key, 0, aescipher.getBlockSize());
    try {
        aescipher.init(false, kpiv);
    } catch (IllegalArgumentException iae) {
        throw new InvalidCipherTextException(iae.getMessage());
    }

    byte[] plaintext = new byte[aescipher.getOutputSize((int) rtsmessage.length() - read)];

    int ptbytes = 0;
    while (read < rtsmessage.length()) {
        byte[] buf = new byte[(int) rtsmessage.length() - read];

        int thisread = fis.read(buf, 0, (int) rtsmessage.length() - read);
        ptbytes += aescipher.processBytes(buf, 0, thisread, plaintext, ptbytes);
        read += thisread;
    }

    fis.close();

    try {
        aescipher.doFinal(plaintext, ptbytes);
    } catch (DataLengthException dle) {
        throw new InvalidCipherTextException(dle.getMessage());
    }

    return plaintext;
}

From source file:gnu.java.zrtp.ZRtp.java

License:Open Source License

/**
 * Send the SAS relay packet./*from ww  w .  ja  va 2  s  .  c  om*/
 * 
 * The method creates and sends a SAS relay packet according to the ZRTP
 * specifications. Usually only a MitM capable user agent (PBX) uses this
 * function.
 * 
 * @param sh the full SAS hash value
 * @param render the SAS rendering algorithm
 */
public boolean sendSASRelayPacket(byte[] sh, ZrtpConstants.SupportedSASTypes render) {
    byte[] hkey, ekey;
    // If we are responder then the PBX used it's Initiator keys
    if (myRole == ZrtpCallback.Role.Responder) {
        hkey = hmacKeyR;
        ekey = zrtpKeyR;
    } else {
        hkey = hmacKeyI;
        ekey = zrtpKeyI;
    }
    secRand.nextBytes(randomIV);
    zrtpSasRelay.setIv(randomIV);
    zrtpSasRelay.setTrustedSas(sh);
    zrtpSasRelay.setSasType(render.name);

    // Encrypt and HMAC with selectedkey
    byte[] dataToSecure = zrtpSasRelay.getDataToSecure();
    try {
        cipher.cipher.init(true, new ParametersWithIV(new KeyParameter(ekey, 0, cipher.keyLength), randomIV));
        int done = cipher.cipher.processBytes(dataToSecure, 0, dataToSecure.length, dataToSecure, 0);
        cipher.cipher.doFinal(dataToSecure, done);
    } catch (Exception e) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereSecurityException));
        return false;
    }
    byte[] confMac = computeHmac(hkey, hashLength, dataToSecure, dataToSecure.length);
    zrtpSasRelay.setDataToSecure(dataToSecure);
    zrtpSasRelay.setHmac(confMac);
    stateEngine.sendSASRelay(zrtpSasRelay);
    return true;
}

From source file:gnu.java.zrtp.ZRtp.java

License:Open Source License

/**
 * Prepare the Confirm1 packet.//  ww w  . j av a 2  s . c  o m
 * 
 * This method prepare the Confirm1 packet. The input to this method is the
 * DHPart2 packect received from our peer. The peer sends the DHPart2 packet
 * as response of our DHPart1. Here we are in the role of the Responder.
 * 
 * The method uses the data of the DHPart2 packet to create the responder's
 * secrets. 
 * 
 */
protected ZrtpPacketConfirm prepareConfirm1(ZrtpPacketDHPart dhPart2, ZrtpCodes.ZrtpErrorCodes[] errMsg) {

    sendInfo(ZrtpCodes.MessageSeverity.Info, EnumSet.of(ZrtpCodes.InfoCodes.InfoRespDH2Received));

    if (!dhPart2.isLengthOk()) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    // Because we are responder we received a Commit and stored its H2.
    // Now re-compute H2 from received H1 and compare with stored peer's H2.
    byte[] tmpHash = new byte[ZrtpConstants.MAX_DIGEST_LENGTH];
    hashFunctionImpl.update(dhPart2.getH1(), 0, ZrtpPacketBase.HASH_IMAGE_SIZE);
    hashFunctionImpl.doFinal(tmpHash, 0);

    if (ZrtpUtils.byteArrayCompare(tmpHash, peerH2, ZrtpPacketBase.HASH_IMAGE_SIZE) != 0) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.IgnorePacket;
        return null;
    }
    // Because we are responder re-compute my
    // hvi using my Hello packet and the Initiator's DHPart2 and compare
    // with hvi sent in commit packet. If it doesn't macht then a MitM
    // attack may have occured.
    computeHvi(dhPart2, currentHelloPacket);
    if (ZrtpUtils.byteArrayCompare(hvi, peerHvi, ZrtpPacketBase.HVI_SIZE) != 0) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.DHErrorWrongHVI;
        return null;
    }
    // Check HMAC of Commit packet stored in temporary buffer. The
    // HMAC key of the Commit packet is peer's H1 that is contained in.
    // DHPart2. Refer to chapter 9.1 and chapter 10.
    if (!checkMsgHmac(dhPart2.getH1())) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereCommitHMACFailed));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    // Get and check the Initiator's public value, see chap. 5.4.2 of the
    // spec
    byte[] pviBytes = dhPart2.getPv();
    int dhSize;

    if (pubKey == ZrtpConstants.SupportedPubKeys.DH2K || pubKey == ZrtpConstants.SupportedPubKeys.DH3K) {

        // generate the resonpder's public key from the pvi data and the key
        // specs, then compute the shared secret.
        BigIntegerCrypto pviBigInt = new BigIntegerCrypto(1, pviBytes);
        if (!checkPubKey(pviBigInt, pubKey)) {
            errMsg[0] = ZrtpCodes.ZrtpErrorCodes.DHErrorWrongPV;
            return null;
        }
        pubKey.dhContext.init(dhKeyPair.getPrivate());
        DHPublicKeyParameters pvi = new DHPublicKeyParameters(pviBigInt, pubKey.specDh);
        dhSize = pubKey.pubKeySize;
        BigIntegerCrypto bi = pubKey.dhContext.calculateAgreement(pvi);
        DHss = bi.toByteArray();
        pubKey.dhContext.clear();
        bi.zeroize(); // clear secret big integer data
    }
    // Here produce the ECDH stuff
    else if (pubKey == ZrtpConstants.SupportedPubKeys.EC25 || pubKey == ZrtpConstants.SupportedPubKeys.EC38) {

        byte[] encoded = new byte[pviBytes.length + 1];
        encoded[0] = 0x04; // uncompressed
        System.arraycopy(pviBytes, 0, encoded, 1, pviBytes.length);
        ECPoint pubPoint = pubKey.curve.decodePoint(encoded);
        dhSize = pubKey.pubKeySize / 2;
        pubKey.dhContext.init(ecKeyPair.getPrivate());
        BigIntegerCrypto bi = pubKey.dhContext.calculateAgreement(new ECPublicKeyParameters(pubPoint, null));
        DHss = bi.toByteArray();
        pubKey.dhContext.clear();
        bi.zeroize(); // clear secret big integer data
    } else if (pubKey == ZrtpConstants.SupportedPubKeys.E255) {
        dhSize = pubKey.pubKeySize;
        pubKey.dhContext.init(ecKeyPair.getPrivate());
        BigIntegerCrypto bi = pubKey.dhContext.calculateAgreement(new Djb25519PublicKeyParameters(pviBytes));
        DHss = bi.toByteArray();
        pubKey.dhContext.clear();
        bi.zeroize(); // clear secret big integer data
    } else {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    if (DHss.length != dhSize) {
        if ((DHss = adjustBigBytes(DHss, dhSize)) == null) {
            errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
            return null;
        }
    }
    // Hash the Initiator's DH2 into the message Hash (other messages
    // already prepared, see method prepareDHPart1().
    hashCtxFunction.update(dhPart2.getHeaderBase(), 0, dhPart2.getLength() * ZrtpPacketBase.ZRTP_WORD_SIZE);
    hashCtxFunction.doFinal(messageHash, 0);
    hashCtxFunction = null;

    /*
     * The expected shared secret Ids were already computed when we built the DHPart1 packet. Generate s0, all
     * depended keys, and the new RS1 value for the ZID record. The functions also performs sign SAS callback if
     * it's active.
     */
    generateKeysResponder(dhPart2);

    // Fill in Confirm1 packet.
    zrtpConfirm1.setMessageType(ZrtpConstants.Confirm1Msg);

    // Check if user verfied the SAS in a previous call and thus verfied
    // the retained secret. Forward this information to our peer. Don't set
    // the verified flag if paranoidMode is true.
    if (zidRec.isSasVerified() && !paranoidMode) {
        zrtpConfirm1.setSASFlag();
    }
    zrtpConfirm1.setExpTime(0xFFFFFFFF);
    zrtpConfirm1.setIv(randomIV);
    zrtpConfirm1.setHashH0(H0);

    // if this run at PBX user agent enrollment service then set flag in confirm
    // packet and store the MitM key
    if (enrollmentMode) {
        computePBXSecret();
        zrtpConfirm1.setPBXEnrollment();
        zidRec.setMiTMData(pbxSecretTmp);
    }

    // Encrypt and HMAC with Responder's key - we are Respondere here
    // see ZRTP specification chapter
    byte[] dataToSecure = zrtpConfirm1.getDataToSecure();
    try {
        cipher.cipher.init(true,
                new ParametersWithIV(new KeyParameter(zrtpKeyR, 0, cipher.keyLength), randomIV));
        int done = cipher.cipher.processBytes(dataToSecure, 0, dataToSecure.length, dataToSecure, 0);
        cipher.cipher.doFinal(dataToSecure, done);
    } catch (Exception e) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereSecurityException));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    byte[] confMac = computeHmac(hmacKeyR, hashLength, dataToSecure, dataToSecure.length);
    zrtpConfirm1.setDataToSecure(dataToSecure);
    zrtpConfirm1.setHmac(confMac);

    // store DHPart2 data temporarily until we can check HMAC after
    // receiving Confirm2
    storeMsgTemp(dhPart2);
    return zrtpConfirm1;
}

From source file:gnu.java.zrtp.ZRtp.java

License:Open Source License

protected ZrtpPacketConfirm prepareConfirm1MultiStream(ZrtpPacketCommit commit,
        ZrtpCodes.ZrtpErrorCodes[] errMsg) {

    sendInfo(ZrtpCodes.MessageSeverity.Info, EnumSet.of(ZrtpCodes.InfoCodes.InfoRespCommitReceived));

    if (!commit.isLengthOk()) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }/*from  ww  w . j a  v a2s .co  m*/
    // In multi stream mode we don't get a DH packt. Thus we need to
    // recompute the hash chain starting with Commit's H2.
    // Use the implicit hash algo
    System.arraycopy(commit.getH2(), 0, peerH2, 0, ZrtpPacketBase.HASH_IMAGE_SIZE);
    byte[] tmpH3 = new byte[ZrtpConstants.MAX_DIGEST_LENGTH];
    hashFunctionImpl.update(peerH2, 0, ZrtpPacketBase.HASH_IMAGE_SIZE);
    hashFunctionImpl.doFinal(tmpH3, 0);

    if (ZrtpUtils.byteArrayCompare(tmpH3, peerH3, ZrtpPacketBase.HASH_IMAGE_SIZE) != 0) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.IgnorePacket;
        return null;
    }
    // Check HMAC of previous Hello packet stored in temporary buffer. The
    // HMAC key of peer's Hello packet is peer's H2 that is contained in the
    // Commit packet. Refer to chapter 9.1.
    if (!checkMsgHmac(peerH2)) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereCommitHMACFailed));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    // check if we support the commited pub key type
    if (commit.getPubKey() != ZrtpConstants.SupportedPubKeys.MULT) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.UnsuppPKExchange;
        return null;
    }
    cipher = commit.getCipher();
    if (cipher == null) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.UnsuppCiphertype;
        return null;
    }
    // check if we support the commited Authentication length
    authLength = commit.getAuthlen();
    if (authLength == null) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.UnsuppSRTPAuthTag;
        return null;
    }
    ZrtpConstants.SupportedHashes newHash = commit.getHash();
    if (newHash == null) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.UnsuppHashType;
        return null;
    }
    if (newHash != hash) {
        hash = newHash;
        setNegotiatedHash(hash);
    }
    myRole = ZrtpCallback.Role.Responder;
    // We are responder. Reset message SHA context
    hashCtxFunction.reset();
    // Hash messages to produce overall message hash:
    // First the Responder's (my) Hello message, second the Commit
    // (always Initator's)
    hashCtxFunction.update(currentHelloPacket.getHeaderBase(), 0,
            currentHelloPacket.getLength() * ZrtpPacketBase.ZRTP_WORD_SIZE);
    hashCtxFunction.update(commit.getHeaderBase(), 0, commit.getLength() * ZrtpPacketBase.ZRTP_WORD_SIZE);
    hashCtxFunction.doFinal(messageHash, 0);
    hashCtxFunction = null;

    generateKeysMultiStream();

    // Fill in Confirm1 packet.
    zrtpConfirm1.setMessageType(ZrtpConstants.Confirm1Msg);
    zrtpConfirm1.setExpTime(0xFFFFFFFF);
    zrtpConfirm1.setIv(randomIV);
    zrtpConfirm1.setHashH0(H0);

    // Encrypt and HMAC with Responder's key - we are Respondere here
    // see ZRTP specification chapter xYxY
    byte[] dataToSecure = zrtpConfirm1.getDataToSecure();
    try {
        cipher.cipher.init(true,
                new ParametersWithIV(new KeyParameter(zrtpKeyR, 0, cipher.keyLength), randomIV));
        int done = cipher.cipher.processBytes(dataToSecure, 0, dataToSecure.length, dataToSecure, 0);
        cipher.cipher.doFinal(dataToSecure, done);
    } catch (Exception e) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereSecurityException));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    byte[] confMac = computeHmac(hmacKeyR, hashLength, dataToSecure, dataToSecure.length);
    zrtpConfirm1.setDataToSecure(dataToSecure);
    zrtpConfirm1.setHmac(confMac);

    // Store Commit data temporarily until we can check HMAC after receiving
    // Confirm2
    storeMsgTemp(commit);
    return zrtpConfirm1;
}

From source file:gnu.java.zrtp.ZRtp.java

License:Open Source License

/**
 * Prepare the Confirm2 packet.//from w  w  w  .j a  v a  2  s.  c  om
 * 
 * This method prepare the Confirm2 packet. The input to this method is the
 * Confirm1 packet received from our peer. The peer sends the Confirm1
 * packet as response of our DHPart2. Here we are in the role of the
 * Initiator
 */
protected ZrtpPacketConfirm prepareConfirm2(ZrtpPacketConfirm confirm1, ZrtpCodes.ZrtpErrorCodes[] errMsg) {
    sendInfo(ZrtpCodes.MessageSeverity.Info, EnumSet.of(ZrtpCodes.InfoCodes.InfoInitConf1Received));

    if (!confirm1.isLengthOk()) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    // Use the Responder's keys here to decrypt because we are
    // Initiator and receive packets from Responder
    byte[] dataToSecure = confirm1.getDataToSecure();
    byte[] confMac = computeHmac(hmacKeyR, hashLength, dataToSecure, dataToSecure.length);

    if (ZrtpUtils.byteArrayCompare(confMac, confirm1.getHmac(), 2 * ZrtpPacketBase.ZRTP_WORD_SIZE) != 0) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.ConfirmHMACWrong;
        return null;
    }
    try {
        // Decrypting here
        cipher.cipher.init(false,
                new ParametersWithIV(new KeyParameter(zrtpKeyR, 0, cipher.keyLength), confirm1.getIv()));
        int done = cipher.cipher.processBytes(dataToSecure, 0, dataToSecure.length, dataToSecure, 0);
        cipher.cipher.doFinal(dataToSecure, done);
    } catch (Exception e) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereSecurityException));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    confirm1.setDataToSecure(dataToSecure);

    // Check HMAC of DHPart1 packet stored in temporary buffer. The
    // HMAC key of the DHPart1 packet is peer's H0 that is contained in
    // Confirm1. Refer to chapter 9
    if (!checkMsgHmac(confirm1.getHashH0())) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereDH1HMACFailed));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    signatureLength = confirm1.getSignatureLength();
    if (signSasSeen && signatureLength > 0) {
        signatureData = confirm1.getSignatureData();
        callback.checkSASSignature(sasHash);
    }
    /*
     * The Confirm1 is ok, handle the Retained secret stuff and inform GUI about state.
     */
    // Did our peer verified the SAS during last session? Get its SAS verified flag.
    boolean sasFlag = confirm1.isSASFlag();

    // Our peer did not confirm the SAS in last session, thus reset our stored SAS 
    // flag too. Reset the flag also if paranoidMode is true.
    if (!sasFlag || paranoidMode) {
        zidRec.resetSasVerified();
    }

    // Now get the resulting SAS verified flag from current RS1 before setting a new RS1.
    // It's a combination of our SAS verfied flag and peer's verified flag. Only if both
    // were set (true) then sasFlag becomes true.
    sasFlag = zidRec.isSasVerified();

    // now we are ready to save the new RS1 which inherits the verified
    // flag from old RS1
    zidRec.setNewRs1(newRs1, -1);

    // now generate my Confirm2 message
    zrtpConfirm2.setMessageType(ZrtpConstants.Confirm2Msg);
    zrtpConfirm2.setHashH0(H0);

    if (sasFlag) {
        zrtpConfirm2.setSASFlag();
    }
    zrtpConfirm2.setExpTime(0xFFFFFFFF);
    zrtpConfirm2.setIv(randomIV);

    // Compute PBX secret if we are in enrollemnt mode (PBX user agent)
    // or enrollment was enabled at normal user agent and flag in confirm packet
    if (enrollmentMode || (enableMitmEnrollment && confirm1.isPBXEnrollment())) {
        computePBXSecret();

        // if this runs at PBX user agent enrollment service then set flag in confirm
        // packet and store the MitM key. The PBX user agent service always stores
        // its MitM key.
        if (enrollmentMode) {
            zrtpConfirm2.setPBXEnrollment();
            zidRec.setMiTMData(pbxSecretTmp);
        }
    }
    ZidFile.getInstance().saveRecord(zidRec);

    // Encrypt and HMAC with Initiator's key - we are Initiator here
    dataToSecure = zrtpConfirm2.getDataToSecure();

    try {
        cipher.cipher.init(true,
                new ParametersWithIV(new KeyParameter(zrtpKeyI, 0, cipher.keyLength), randomIV));
        int done = cipher.cipher.processBytes(dataToSecure, 0, dataToSecure.length, dataToSecure, 0);
        cipher.cipher.doFinal(dataToSecure, done);
    } catch (Exception e) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereSecurityException));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    confMac = computeHmac(hmacKeyI, hashLength, dataToSecure, dataToSecure.length);

    zrtpConfirm2.setDataToSecure(dataToSecure);
    zrtpConfirm2.setHmac(confMac);

    callback.srtpSecretsOn(cipher.readable + "/" + pubKey, SAS, sasFlag);

    // Ask for enrollment only if enabled via configuration and the
    // confirm packet contains the enrollment flag. The enrolling user
    // agent stores the MitM key only if the user accepts the enrollment
    // request.
    if (enableMitmEnrollment && confirm1.isPBXEnrollment()) {
        callback.zrtpAskEnrollment(ZrtpCodes.InfoEnrollment.EnrollmentRequest);
    }
    return zrtpConfirm2;
}

From source file:gnu.java.zrtp.ZRtp.java

License:Open Source License

/**
 * @param confirm1 The ZRTP confirm1 packet
 * @param errMsg Arry to return an error code
 * @return a ZRTP confirm packet, here a confirm2
 *//*from  ww  w.  j  a  v a  2 s  .c  o  m*/
protected ZrtpPacketConfirm prepareConfirm2MultiStream(ZrtpPacketConfirm confirm1,
        ZrtpCodes.ZrtpErrorCodes[] errMsg) {

    // check Confirm1 packet using the keys
    // prepare Confirm2 packet
    // don't update SAS, RS
    sendInfo(ZrtpCodes.MessageSeverity.Info, EnumSet.of(ZrtpCodes.InfoCodes.InfoInitConf1Received));

    if (!confirm1.isLengthOk()) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    hashCtxFunction.doFinal(messageHash, 0);
    hashCtxFunction = null;

    myRole = ZrtpCallback.Role.Initiator;

    generateKeysMultiStream();

    // Use the Responder's keys here to decrypt because we are
    // Initiator and receive packets from Responder
    byte[] dataToSecure = confirm1.getDataToSecure();
    byte[] confMac = computeHmac(hmacKeyR, hashLength, dataToSecure, dataToSecure.length);

    if (ZrtpUtils.byteArrayCompare(confMac, confirm1.getHmac(), 2 * ZrtpPacketBase.ZRTP_WORD_SIZE) != 0) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.ConfirmHMACWrong;
        return null;
    }
    try {
        // Decrypting here
        cipher.cipher.init(false,
                new ParametersWithIV(new KeyParameter(zrtpKeyR, 0, cipher.keyLength), confirm1.getIv()));
        int done = cipher.cipher.processBytes(dataToSecure, 0, dataToSecure.length, dataToSecure, 0);
        cipher.cipher.doFinal(dataToSecure, done);
    } catch (Exception e) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereSecurityException));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    confirm1.setDataToSecure(dataToSecure);

    // Because we are initiator the protocol engine didn't receive Commit
    // and because we are using multi-stream mode here we also did not
    // receive a DHPart1 and thus could not store a responder's H2 or H1.
    // A two step hash is required to re-compute H1 and H2.
    // Use implicit hash algo
    byte[] tmpHash = new byte[ZrtpConstants.MAX_DIGEST_LENGTH];
    hashFunctionImpl.update(confirm1.getHashH0(), 0, ZrtpPacketBase.HASH_IMAGE_SIZE); // Compute peer's H1 in
                                                                                      // tmpHash
    hashFunctionImpl.doFinal(tmpHash, 0);
    // Compute peer's H2
    hashFunctionImpl.update(tmpHash, 0, ZrtpPacketBase.HASH_IMAGE_SIZE);
    hashFunctionImpl.doFinal(peerH2, 0);

    // Check HMAC of previous Hello packet stored in temporary buffer. The
    // HMAC key of the Hello packet is peer's H2 that was computed above.
    // Refer to chapter 9.1 and chapter 10.
    if (!checkMsgHmac(peerH2)) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereHelloHMACFailed));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    // now generate my Confirm2 message
    zrtpConfirm2.setMessageType(ZrtpConstants.Confirm2Msg);
    zrtpConfirm2.setHashH0(H0);
    zrtpConfirm2.setExpTime(0xFFFFFFFF);
    zrtpConfirm2.setIv(randomIV);

    // Encrypt and HMAC with Initiator's key - we are Initiator here
    dataToSecure = zrtpConfirm2.getDataToSecure();

    try {
        cipher.cipher.init(true,
                new ParametersWithIV(new KeyParameter(zrtpKeyI, 0, cipher.keyLength), randomIV));
        int done = cipher.cipher.processBytes(dataToSecure, 0, dataToSecure.length, dataToSecure, 0);
        cipher.cipher.doFinal(dataToSecure, done);
    } catch (Exception e) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereSecurityException));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    confMac = computeHmac(hmacKeyI, hashLength, dataToSecure, dataToSecure.length);
    zrtpConfirm2.setDataToSecure(dataToSecure);
    zrtpConfirm2.setHmac(confMac);

    // Inform GUI about security state, don't show SAS and its state
    callback.srtpSecretsOn(cipher.readable, null, true);
    return zrtpConfirm2;
}

From source file:gnu.java.zrtp.ZRtp.java

License:Open Source License

/**
 * Prepare the Conf2Ack packet./*from   ww  w . j  av  a2  s.  c  om*/
 * 
 * This method prepare the Conf2Ack packet. The input to this method is the
 * Confirm2 packet received from our peer. The peer sends the Confirm2
 * packet as response of our Confirm1. Here we are in the role of the
 * Initiator
 */
protected ZrtpPacketConf2Ack prepareConf2Ack(ZrtpPacketConfirm confirm2, ZrtpCodes.ZrtpErrorCodes[] errMsg) {
    sendInfo(ZrtpCodes.MessageSeverity.Info, EnumSet.of(ZrtpCodes.InfoCodes.InfoRespConf2Received));

    if (!confirm2.isLengthOk()) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    // Use the Initiator's keys here because we are Responder here and
    // reveice packets from Initiator
    byte[] dataToSecure = confirm2.getDataToSecure();
    byte[] confMac = computeHmac(hmacKeyI, hashLength, dataToSecure, dataToSecure.length);

    if (ZrtpUtils.byteArrayCompare(confMac, confirm2.getHmac(), 2 * ZrtpPacketBase.ZRTP_WORD_SIZE) != 0) {
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.ConfirmHMACWrong;
        return null;
    }
    try {
        // Decrypting here
        cipher.cipher.init(false,
                new ParametersWithIV(new KeyParameter(zrtpKeyI, 0, cipher.keyLength), confirm2.getIv()));
        int done = cipher.cipher.processBytes(dataToSecure, 0, dataToSecure.length, dataToSecure, 0);
        cipher.cipher.doFinal(dataToSecure, done);
    } catch (Exception e) {
        sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereSecurityException));
        errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
        return null;
    }
    confirm2.setDataToSecure(dataToSecure);

    if (!multiStream) {
        // Check HMAC of DHPart2 packet stored in temporary buffer. The
        // HMAC key of the DHPart2 packet is peer's H0 that is contained in
        // Confirm2. Refer to chapter 9.1 and chapter 10.
        if (!checkMsgHmac(confirm2.getHashH0())) {
            sendInfo(ZrtpCodes.MessageSeverity.Severe, EnumSet.of(ZrtpCodes.SevereCodes.SevereDH2HMACFailed));
            errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
            return null;
        }
        signatureLength = confirm2.getSignatureLength();
        if (signSasSeen && signatureLength > 0) {
            signatureData = confirm2.getSignatureData();
            callback.checkSASSignature(sasHash);
        }
        /*
         * The Confirm2 is ok, handle the Retained secret stuff and inform GUI about state.
         */
        // Did our peer verify the SAS during last session? Get its SAS verified flag.
        boolean sasFlag = confirm2.isSASFlag();

        // Our peer did not confirm the SAS in last session, thus reset our stored SAS 
        // flag too. Reset the flag also if paranoidMode is true.
        if (!sasFlag || paranoidMode) {
            zidRec.resetSasVerified();
        }
        // Now get the resulting SAS verified flag from current RS1 before setting a new RS1.
        // It's a combination of our SAS verfied flag and peer's verified flag. Only if both
        // were set (true) then sasFlag becomes true.
        sasFlag = zidRec.isSasVerified();

        // save new RS1, this inherits the verified flag from old RS1
        zidRec.setNewRs1(newRs1, -1);
        ZidFile.getInstance().saveRecord(zidRec);

        // Ask for enrollment only if enabled via configuration and the
        // confirm packet contains the enrollment flag. The enrolling user
        // agent stores the MitM key only if the user accepts the enrollment
        // request.
        if (enableMitmEnrollment && confirm2.isPBXEnrollment()) {
            computePBXSecret();
            callback.zrtpAskEnrollment(ZrtpCodes.InfoEnrollment.EnrollmentRequest);
        }
        callback.srtpSecretsOn(cipher.readable + "/" + pubKey, SAS, sasFlag);
    } else {
        byte[] tmpHash = new byte[ZrtpConstants.MAX_DIGEST_LENGTH];
        hashFunctionImpl.update(confirm2.getHashH0(), 0, ZrtpPacketBase.HASH_IMAGE_SIZE); // Compute initiator's H1
                                                                                          // in tmpHash
        hashFunctionImpl.doFinal(tmpHash, 0);

        if (!checkMsgHmac(tmpHash)) {
            sendInfo(ZrtpCodes.MessageSeverity.Severe,
                    EnumSet.of(ZrtpCodes.SevereCodes.SevereCommitHMACFailed));
            errMsg[0] = ZrtpCodes.ZrtpErrorCodes.CriticalSWError;
            return null;
        }
        // Inform GUI about security state, don't show SAS and its state
        callback.srtpSecretsOn(cipher.readable, null, true);

    }
    return zrtpConf2Ack;
}