private void encryptAndSend(Message msg) throws Exception { EncryptHeader hdr = new EncryptHeader(EncryptHeader.ENCRYPT, getSymVersion()); if (this.encrypt_entire_message) hdr.type |= EncryptHeader.ENCRYPT_ENTIRE_MSG; if (encrypt_entire_message) { if (msg.getSrc() == null) msg.setSrc(local_addr); Buffer serialized_msg = Util.streamableToBuffer(msg); byte[] encrypted_msg = code( serialized_msg.getBuf(), serialized_msg.getOffset(), serialized_msg.getLength(), false); // exclude existing headers, they will be seen again when we decrypt and unmarshal the msg at // the receiver Message tmp = msg.copy(false, false).setBuffer(encrypted_msg).putHeader(this.id, hdr); down_prot.down(new Event(Event.MSG, tmp)); return; } // copy neeeded because same message (object) may be retransmitted -> no double encryption Message msgEncrypted = msg.copy(false) .putHeader(this.id, hdr) .setBuffer(code(msg.getRawBuffer(), msg.getOffset(), msg.getLength(), false)); down_prot.down(new Event(Event.MSG, msgEncrypted)); }
private Object handleUpMessage(Event evt) throws Exception { Message msg = (Message) evt.getArg(); EncryptHeader hdr; if (msg == null || (msg.getLength() == 0 && !encrypt_entire_message) || ((hdr = (EncryptHeader) msg.getHeader(this.id)) == null)) return up_prot.up(evt); if (log.isTraceEnabled()) log.trace("header received %s", hdr); switch (hdr.getType()) { case EncryptHeader.ENCRYPT: return handleEncryptedMessage(msg, evt, hdr); default: handleUpEvent(msg, hdr); return null; } }
/** * Does the actual work for decrypting - if version does not match current cipher then tries the * previous cipher */ private Message decryptMessage(Cipher cipher, Message msg) throws Exception { EncryptHeader hdr = (EncryptHeader) msg.getHeader(this.id); if (!Arrays.equals(hdr.getVersion(), getSymVersion())) { log.warn( "attempting to use stored cipher as message does not use current encryption version "); cipher = keyMap.get(new AsciiString(hdr.getVersion())); if (cipher == null) { log.warn("unable to find a matching cipher in previous key map"); return null; } log.trace("decrypting using previous cipher version"); synchronized (cipher) { return _decrypt(cipher, msg, hdr.encryptEntireMessage()); } } return _decrypt(cipher, msg, hdr.encryptEntireMessage()); }
public Message visit(Message msg, MessageBatch batch) { EncryptHeader hdr; if (msg == null || (msg.getLength() == 0 && !encrypt_entire_message) || ((hdr = (EncryptHeader) msg.getHeader(id)) == null)) return null; if (hdr.getType() == EncryptHeader.ENCRYPT) { // if queueing then pass into queue to be dealt with later if (queue_up) { queueUpMessage(msg, batch); return null; } // make sure we pass up any queued messages first if (!suppliedKey) drainUpQueue(); if (lock == null) { int index = getNextIndex(); lock = decoding_locks[index]; cipher = decoding_ciphers[index]; lock.lock(); } try { Message tmpMsg = decryptMessage(cipher, msg.copy()); // need to copy for possible xmits if (tmpMsg != null) batch.replace(msg, tmpMsg); } catch (Exception e) { log.error( "failed decrypting message from %s (offset=%d, length=%d, buf.length=%d): %s, headers are %s", msg.getSrc(), msg.getOffset(), msg.getLength(), msg.getRawBuffer().length, e, msg.printHeaders()); } } else { batch.remove( msg); // a control message will get handled by ENCRYPT and should not be passed up handleUpEvent(msg, hdr); } return null; }
protected void handleUpEvent(Message msg, EncryptHeader hdr) { // check if we had some sort of encrypt control header if using supplied key we should not // process it if (suppliedKey) { log.warn("we received an encrypt header of %s while in configured mode", hdr.getType()); return; } // see what sort of encrypt control message we have received switch (hdr.getType()) { // if a key request case EncryptHeader.KEY_REQUEST: log.debug("received a key request from peer %s", msg.getSrc()); // if a key request send response key back try { // extract peer's public key PublicKey tmpKey = generatePubKey(msg.getBuffer()); // send back the secret key we have sendSecretKey(getSecretKey(), tmpKey, msg.getSrc()); } catch (Exception e) { log.warn("unable to reconstitute peer's public key"); } break; case EncryptHeader.SECRETKEY: log.debug("received a secretkey response from keyserver %s", msg.getSrc()); try { SecretKey tmp = decodeKey(msg.getBuffer()); if (tmp == null) sendKeyRequest(); // unable to understand response, let's try again else { // otherwise lets set the returned key as the shared key setKeys(tmp, hdr.getVersion()); log.debug("decoded secretkey response"); } } catch (Exception e) { log.warn("unable to process received public key", e); } break; default: log.warn("received ignored encrypt header of %s", hdr.getType()); break; } }