📄 filters.cpp
字号:
newLength -= m_blockSize; } if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0) { assert(m_queue.CurrentSize() < m_blockSize); size_t len = m_blockSize - m_queue.CurrentSize(); m_queue.Put(inString, len); inString += len; NextPutModifiable(m_queue.GetBlock(), m_blockSize); newLength -= m_blockSize; } if (newLength >= m_blockSize + m_lastSize) { size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize); NextPutMaybeModifiable(inString, len, modifiable); inString += len; newLength -= len; } } } m_queue.Put(inString, newLength - m_queue.CurrentSize()); } if (messageEnd) { if (!m_firstInputDone && m_firstSize==0) FirstPut(NULL); SecByteBlock temp(m_queue.CurrentSize()); m_queue.GetAll(temp); LastPut(temp, temp.size()); m_firstInputDone = false; m_queue.ResetQueue(1, m_firstSize); Output(1, NULL, 0, messageEnd, blocking); } return 0;}void FilterWithBufferedInput::ForceNextPut(){ if (!m_firstInputDone) return; if (m_blockSize > 1) { while (m_queue.CurrentSize() >= m_blockSize) NextPutModifiable(m_queue.GetBlock(), m_blockSize); } else { size_t len; while ((len = m_queue.CurrentSize()) > 0) NextPutModifiable(m_queue.GetContigousBlocks(len), len); }}void FilterWithBufferedInput::NextPutMultiple(const byte *inString, size_t length){ assert(m_blockSize > 1); // m_blockSize = 1 should always override this function while (length > 0) { assert(length >= m_blockSize); NextPutSingle(inString); inString += m_blockSize; length -= m_blockSize; }}// *************************************************************void Redirector::Initialize(const NameValuePairs ¶meters, int propagation){ m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL); m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING); if (m_target && GetPassSignals()) m_target->Initialize(parameters, propagation);}// *************************************************************ProxyFilter::ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment) : FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter){ if (m_filter.get()) m_filter->Attach(new OutputProxy(*this, false));}bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking){ return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false;}void ProxyFilter::SetFilter(Filter *filter){ m_filter.reset(filter); if (filter) { OutputProxy *proxy; std::auto_ptr<OutputProxy> temp(proxy = new OutputProxy(*this, false)); m_filter->TransferAllTo(*proxy); m_filter->Attach(temp.release()); }}void ProxyFilter::NextPutMultiple(const byte *s, size_t len){ if (m_filter.get()) m_filter->Put(s, len);}void ProxyFilter::NextPutModifiable(byte *s, size_t len){ if (m_filter.get()) m_filter->PutModifiable(s, len);}// *************************************************************void RandomNumberSink::IsolatedInitialize(const NameValuePairs ¶meters){ parameters.GetRequiredParameter("RandomNumberSink", "RandomNumberGeneratorPointer", m_rng);}size_t RandomNumberSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking){ m_rng->IncorporateEntropy(begin, length); return 0;}size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking){ if (m_buf+m_total != begin) memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total))); m_total += length; return 0;}byte * ArraySink::CreatePutSpace(size_t &size){ size = SaturatingSubtract(m_size, m_total); return m_buf + m_total;}void ArraySink::IsolatedInitialize(const NameValuePairs ¶meters){ ByteArrayParameter array; if (!parameters.GetValue(Name::OutputBuffer(), array)) throw InvalidArgument("ArraySink: missing OutputBuffer argument"); m_buf = array.begin(); m_size = array.size(); m_total = 0;}size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking){ xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total))); m_total += length; return 0;}// *************************************************************StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool allowAuthenticatedSymmetricCipher) : FilterWithBufferedInput(attachment) , m_cipher(c){ assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize()); if (!allowAuthenticatedSymmetricCipher && dynamic_cast<AuthenticatedSymmetricCipher *>(&c) != 0) throw InvalidArgument("StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher"); IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding));}size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding){ if (c.MinLastBlockSize() > 0) return c.MinLastBlockSize(); else if (c.MandatoryBlockSize() > 1 && !c.IsForwardTransformation() && padding != NO_PADDING && padding != ZEROS_PADDING) return c.MandatoryBlockSize(); else return 0;}void StreamTransformationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize){ BlockPaddingScheme padding = parameters.GetValueWithDefault(Name::BlockPaddingScheme(), DEFAULT_PADDING); bool isBlockCipher = (m_cipher.MandatoryBlockSize() > 1 && m_cipher.MinLastBlockSize() == 0); if (padding == DEFAULT_PADDING) m_padding = isBlockCipher ? PKCS_PADDING : NO_PADDING; else m_padding = padding; if (!isBlockCipher && (m_padding == PKCS_PADDING || m_padding == ONE_AND_ZEROS_PADDING)) throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING and ONE_AND_ZEROS_PADDING cannot be used with " + m_cipher.AlgorithmName()); firstSize = 0; blockSize = m_cipher.MandatoryBlockSize(); lastSize = LastBlockSize(m_cipher, m_padding);}void StreamTransformationFilter::FirstPut(const byte *inString){ m_optimalBufferSize = m_cipher.OptimalBlockSize(); m_optimalBufferSize = (unsigned int)STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));}void StreamTransformationFilter::NextPutMultiple(const byte *inString, size_t length){ if (!length) return; size_t s = m_cipher.MandatoryBlockSize(); do { size_t len = m_optimalBufferSize; byte *space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, length, len); if (len < length) { if (len == m_optimalBufferSize) len -= m_cipher.GetOptimalBlockSizeUsed(); len = RoundDownToMultipleOf(len, s); } else len = length; m_cipher.ProcessString(space, inString, len); AttachedTransformation()->PutModifiable(space, len); inString += len; length -= len; } while (length > 0);}void StreamTransformationFilter::NextPutModifiable(byte *inString, size_t length){ m_cipher.ProcessString(inString, length); AttachedTransformation()->PutModifiable(inString, length);}void StreamTransformationFilter::LastPut(const byte *inString, size_t length){ byte *space = NULL; switch (m_padding) { case NO_PADDING: case ZEROS_PADDING: if (length > 0) { size_t minLastBlockSize = m_cipher.MinLastBlockSize(); bool isForwardTransformation = m_cipher.IsForwardTransformation(); if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize)) { // do padding size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_cipher.MandatoryBlockSize()); space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, blockSize); memcpy(space, inString, length); memset(space + length, 0, blockSize - length); m_cipher.ProcessLastBlock(space, space, blockSize); AttachedTransformation()->Put(space, blockSize); } else { if (minLastBlockSize == 0) { if (isForwardTransformation) throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified"); else throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); } space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, length, m_optimalBufferSize); m_cipher.ProcessLastBlock(space, inString, length); AttachedTransformation()->Put(space, length); } } break; case PKCS_PADDING: case ONE_AND_ZEROS_PADDING: unsigned int s; s = m_cipher.MandatoryBlockSize(); assert(s > 1); space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, m_optimalBufferSize); if (m_cipher.IsForwardTransformation()) { assert(length < s); memcpy(space, inString, length); if (m_padding == PKCS_PADDING) { assert(s < 256); byte pad = byte(s-length); memset(space+length, pad, s-length); } else { space[length] = 0x80; memset(space+length+1, 0, s-length-1); } m_cipher.ProcessData(space, space, s); AttachedTransformation()->Put(space, s); } else { if (length != s) throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); m_cipher.ProcessData(space, inString, s); if (m_padding == PKCS_PADDING) { byte pad = space[s-1]; if (pad < 1 || pad > s || std::find_if(space+s-pad, space+s, std::bind2nd(std::not_equal_to<byte>(), pad)) != space+s) throw InvalidCiphertext("StreamTransformationFilter: invalid PKCS #7 block padding found"); length = s-pad; } else { while (length > 1 && space[length-1] == 0) --length; if (space[--length] != 0x80) throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found"); } AttachedTransformation()->Put(space, length); } break; default: assert(false); }}// *************************************************************HashFilter::HashFilter(HashTransformation &hm, BufferedTransformation *attachment, bool putMessage, int truncatedDigestSize, const std::string &messagePutChannel, const std::string &hashPutChannel) : m_hashModule(hm), m_putMessage(putMessage), m_messagePutChannel(messagePutChannel), m_hashPutChannel(hashPutChannel){ m_digestSize = truncatedDigestSize < 0 ? m_hashModule.DigestSize() : truncatedDigestSize; Detach(attachment);}void HashFilter::IsolatedInitialize(const NameValuePairs ¶meters){ m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false); int s = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1); m_digestSize = s < 0 ? m_hashModule.DigestSize() : s;}size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking){ FILTER_BEGIN; if (m_putMessage) FILTER_OUTPUT3(1, 0, inString, length, 0, m_messagePutChannel); m_hashModule.Update(inString, length); if (messageEnd) { { size_t size; m_space = HelpCreatePutSpace(*AttachedTransformation(), m_hashPutChannel, m_digestSize, m_digestSize, size = m_digestSize); m_hashModule.TruncatedFinal(m_space, m_digestSize); } FILTER_OUTPUT3(2, 0, m_space, m_digestSize, messageEnd, m_hashPutChannel); } FILTER_END_NO_MESSAGE_END;}// *************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -