'Extracts (i.e., decrypts and authenticates) protocol messages.
The raw `data\' coming directly from the wire is decrypted using `aes\'
and authenticated using `hmacKey\'.  The payload is then returned as
unencrypted protocol messages.  In case of invalid headers or HMACs, an
exception is raised.'

def extract(self, data, aes, hmacKey):

    self.recvBuf += data
    msgs = []
    while (len(self.recvBuf) >= const.HDR_LENGTH):
        if (self.totalLen == self.payloadLen == self.flags == None):
            self.totalLen = pack.ntohs(aes.decrypt(self.recvBuf[16:18]))
            self.payloadLen = pack.ntohs(aes.decrypt(self.recvBuf[18:20]))
            self.flags = ord(aes.decrypt(self.recvBuf[20]))
            if (not isSane(self.totalLen, self.payloadLen, self.flags)):
                raise base.PluggableTransportError('Invalid    header.')
        if ((len(self.recvBuf) - const.HDR_LENGTH) < self.totalLen):
            break
        rcvdHMAC = self.recvBuf[0:const.HMAC_SHA256_128_LENGTH]
        vrfyHMAC = mycrypto.HMAC_SHA256_128(hmacKey, self.recvBuf[const.HMAC_SHA256_128_LENGTH:(self.totalLen + const.HDR_LENGTH)])
        if (rcvdHMAC != vrfyHMAC):
            raise base.PluggableTransportError('Invalid    message    HMAC.')
        extracted = aes.decrypt(self.recvBuf[const.HDR_LENGTH:(self.totalLen + const.HDR_LENGTH)])[:self.payloadLen]
        msgs.append(ProtocolMessage(payload=extracted, flags=self.flags))
        self.recvBuf = self.recvBuf[(const.HDR_LENGTH + self.totalLen):]
        self.totalLen = self.payloadLen = self.flags = None
    return msgs
