00001
00002
00003 #include "pch.h"
00004
00005 #ifndef CRYPTOPP_IMPORTS
00006
00007 #include "filters.h"
00008 #include "mqueue.h"
00009 #include "fltrimpl.h"
00010 #include "argnames.h"
00011 #include <memory>
00012 #include <functional>
00013
00014 NAMESPACE_BEGIN(CryptoPP)
00015
00016 Filter::Filter(BufferedTransformation *attachment)
00017 : m_attachment(attachment), m_continueAt(0)
00018 {
00019 }
00020
00021 BufferedTransformation * Filter::NewDefaultAttachment() const
00022 {
00023 return new MessageQueue;
00024 }
00025
00026 BufferedTransformation * Filter::AttachedTransformation()
00027 {
00028 if (m_attachment.get() == NULL)
00029 m_attachment.reset(NewDefaultAttachment());
00030 return m_attachment.get();
00031 }
00032
00033 const BufferedTransformation *Filter::AttachedTransformation() const
00034 {
00035 if (m_attachment.get() == NULL)
00036 const_cast<Filter *>(this)->m_attachment.reset(NewDefaultAttachment());
00037 return m_attachment.get();
00038 }
00039
00040 void Filter::Detach(BufferedTransformation *newOut)
00041 {
00042 m_attachment.reset(newOut);
00043 }
00044
00045 void Filter::Insert(Filter *filter)
00046 {
00047 filter->m_attachment.reset(m_attachment.release());
00048 m_attachment.reset(filter);
00049 }
00050
00051 size_t Filter::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
00052 {
00053 return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking);
00054 }
00055
00056 size_t Filter::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
00057 {
00058 return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking);
00059 }
00060
00061 void Filter::Initialize(const NameValuePairs ¶meters, int propagation)
00062 {
00063 m_continueAt = 0;
00064 IsolatedInitialize(parameters);
00065 PropagateInitialize(parameters, propagation);
00066 }
00067
00068 bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
00069 {
00070 switch (m_continueAt)
00071 {
00072 case 0:
00073 if (IsolatedFlush(hardFlush, blocking))
00074 return true;
00075 case 1:
00076 if (OutputFlush(1, hardFlush, propagation, blocking))
00077 return true;
00078 }
00079 return false;
00080 }
00081
00082 bool Filter::MessageSeriesEnd(int propagation, bool blocking)
00083 {
00084 switch (m_continueAt)
00085 {
00086 case 0:
00087 if (IsolatedMessageSeriesEnd(blocking))
00088 return true;
00089 case 1:
00090 if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
00091 return true;
00092 }
00093 return false;
00094 }
00095
00096 void Filter::PropagateInitialize(const NameValuePairs ¶meters, int propagation)
00097 {
00098 if (propagation)
00099 AttachedTransformation()->Initialize(parameters, propagation-1);
00100 }
00101
00102 size_t Filter::OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel)
00103 {
00104 if (messageEnd)
00105 messageEnd--;
00106 size_t result = AttachedTransformation()->PutModifiable2(inString, length, messageEnd, blocking);
00107 m_continueAt = result ? outputSite : 0;
00108 return result;
00109 }
00110
00111 size_t Filter::Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel)
00112 {
00113 if (messageEnd)
00114 messageEnd--;
00115 size_t result = AttachedTransformation()->Put2(inString, length, messageEnd, blocking);
00116 m_continueAt = result ? outputSite : 0;
00117 return result;
00118 }
00119
00120 bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel)
00121 {
00122 if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking))
00123 {
00124 m_continueAt = outputSite;
00125 return true;
00126 }
00127 m_continueAt = 0;
00128 return false;
00129 }
00130
00131 bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel)
00132 {
00133 if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking))
00134 {
00135 m_continueAt = outputSite;
00136 return true;
00137 }
00138 m_continueAt = 0;
00139 return false;
00140 }
00141
00142
00143
00144 size_t MeterFilter::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
00145 {
00146 if (m_transparent)
00147 {
00148 FILTER_BEGIN;
00149 m_currentMessageBytes += length;
00150 m_totalBytes += length;
00151
00152 if (messageEnd)
00153 {
00154 m_currentMessageBytes = 0;
00155 m_currentSeriesMessages++;
00156 m_totalMessages++;
00157 }
00158
00159 FILTER_OUTPUT(1, begin, length, messageEnd);
00160 FILTER_END_NO_MESSAGE_END;
00161 }
00162 return 0;
00163 }
00164
00165 size_t MeterFilter::PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
00166 {
00167 if (m_transparent)
00168 {
00169 FILTER_BEGIN;
00170 m_currentMessageBytes += length;
00171 m_totalBytes += length;
00172
00173 if (messageEnd)
00174 {
00175 m_currentMessageBytes = 0;
00176 m_currentSeriesMessages++;
00177 m_totalMessages++;
00178 }
00179
00180 FILTER_OUTPUT_MODIFIABLE(1, begin, length, messageEnd);
00181 FILTER_END_NO_MESSAGE_END;
00182 }
00183 return 0;
00184 }
00185
00186 bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking)
00187 {
00188 m_currentMessageBytes = 0;
00189 m_currentSeriesMessages = 0;
00190 m_totalMessageSeries++;
00191 return false;
00192 }
00193
00194
00195
00196 void FilterWithBufferedInput::BlockQueue::ResetQueue(size_t blockSize, size_t maxBlocks)
00197 {
00198 m_buffer.New(blockSize * maxBlocks);
00199 m_blockSize = blockSize;
00200 m_maxBlocks = maxBlocks;
00201 m_size = 0;
00202 m_begin = m_buffer;
00203 }
00204
00205 byte *FilterWithBufferedInput::BlockQueue::GetBlock()
00206 {
00207 if (m_size >= m_blockSize)
00208 {
00209 byte *ptr = m_begin;
00210 if ((m_begin+=m_blockSize) == m_buffer.end())
00211 m_begin = m_buffer;
00212 m_size -= m_blockSize;
00213 return ptr;
00214 }
00215 else
00216 return NULL;
00217 }
00218
00219 byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(size_t &numberOfBytes)
00220 {
00221 numberOfBytes = STDMIN(numberOfBytes, STDMIN(size_t(m_buffer.end()-m_begin), m_size));
00222 byte *ptr = m_begin;
00223 m_begin += numberOfBytes;
00224 m_size -= numberOfBytes;
00225 if (m_size == 0 || m_begin == m_buffer.end())
00226 m_begin = m_buffer;
00227 return ptr;
00228 }
00229
00230 size_t FilterWithBufferedInput::BlockQueue::GetAll(byte *outString)
00231 {
00232 size_t size = m_size;
00233 size_t numberOfBytes = m_maxBlocks*m_blockSize;
00234 const byte *ptr = GetContigousBlocks(numberOfBytes);
00235 memcpy(outString, ptr, numberOfBytes);
00236 memcpy(outString+numberOfBytes, m_begin, m_size);
00237 m_size = 0;
00238 return size;
00239 }
00240
00241 void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t length)
00242 {
00243 assert(m_size + length <= m_buffer.size());
00244 byte *end = (m_size < size_t(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size();
00245 size_t len = STDMIN(length, size_t(m_buffer.end()-end));
00246 memcpy(end, inString, len);
00247 if (len < length)
00248 memcpy(m_buffer, inString+len, length-len);
00249 m_size += length;
00250 }
00251
00252 FilterWithBufferedInput::FilterWithBufferedInput(BufferedTransformation *attachment)
00253 : Filter(attachment)
00254 {
00255 }
00256
00257 FilterWithBufferedInput::FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment)
00258 : Filter(attachment), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize)
00259 , m_firstInputDone(false)
00260 {
00261 if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
00262 throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
00263
00264 m_queue.ResetQueue(1, m_firstSize);
00265 }
00266
00267 void FilterWithBufferedInput::IsolatedInitialize(const NameValuePairs ¶meters)
00268 {
00269 InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize);
00270 if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
00271 throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
00272 m_queue.ResetQueue(1, m_firstSize);
00273 m_firstInputDone = false;
00274 }
00275
00276 bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking)
00277 {
00278 if (!blocking)
00279 throw BlockingInputOnly("FilterWithBufferedInput");
00280
00281 if (hardFlush)
00282 ForceNextPut();
00283 FlushDerived();
00284
00285 return false;
00286 }
00287
00288 size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable)
00289 {
00290 if (!blocking)
00291 throw BlockingInputOnly("FilterWithBufferedInput");
00292
00293 if (length != 0)
00294 {
00295 size_t newLength = m_queue.CurrentSize() + length;
00296
00297 if (!m_firstInputDone && newLength >= m_firstSize)
00298 {
00299 size_t len = m_firstSize - m_queue.CurrentSize();
00300 m_queue.Put(inString, len);
00301 FirstPut(m_queue.GetContigousBlocks(m_firstSize));
00302 assert(m_queue.CurrentSize() == 0);
00303 m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize);
00304
00305 inString += len;
00306 newLength -= m_firstSize;
00307 m_firstInputDone = true;
00308 }
00309
00310 if (m_firstInputDone)
00311 {
00312 if (m_blockSize == 1)
00313 {
00314 while (newLength > m_lastSize && m_queue.CurrentSize() > 0)
00315 {
00316 size_t len = newLength - m_lastSize;
00317 byte *ptr = m_queue.GetContigousBlocks(len);
00318 NextPutModifiable(ptr, len);
00319 newLength -= len;
00320 }
00321
00322 if (newLength > m_lastSize)
00323 {
00324 size_t len = newLength - m_lastSize;
00325 NextPutMaybeModifiable(inString, len, modifiable);
00326 inString += len;
00327 newLength -= len;
00328 }
00329 }
00330 else
00331 {
00332 while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize)
00333 {
00334 NextPutModifiable(m_queue.GetBlock(), m_blockSize);
00335 newLength -= m_blockSize;
00336 }
00337
00338 if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0)
00339 {
00340 assert(m_queue.CurrentSize() < m_blockSize);
00341 size_t len = m_blockSize - m_queue.CurrentSize();
00342 m_queue.Put(inString, len);
00343 inString += len;
00344 NextPutModifiable(m_queue.GetBlock(), m_blockSize);
00345 newLength -= m_blockSize;
00346 }
00347
00348 if (newLength >= m_blockSize + m_lastSize)
00349 {
00350 size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize);
00351 NextPutMaybeModifiable(inString, len, modifiable);
00352 inString += len;
00353 newLength -= len;
00354 }
00355 }
00356 }
00357
00358 m_queue.Put(inString, newLength - m_queue.CurrentSize());
00359 }
00360
00361 if (messageEnd)
00362 {
00363 if (!m_firstInputDone && m_firstSize==0)
00364 FirstPut(NULL);
00365
00366 SecByteBlock temp(m_queue.CurrentSize());
00367 m_queue.GetAll(temp);
00368 LastPut(temp, temp.size());
00369
00370 m_firstInputDone = false;
00371 m_queue.ResetQueue(1, m_firstSize);
00372
00373 Output(1, NULL, 0, messageEnd, blocking);
00374 }
00375 return 0;
00376 }
00377
00378 void FilterWithBufferedInput::ForceNextPut()
00379 {
00380 if (!m_firstInputDone)
00381 return;
00382
00383 if (m_blockSize > 1)
00384 {
00385 while (m_queue.CurrentSize() >= m_blockSize)
00386 NextPutModifiable(m_queue.GetBlock(), m_blockSize);
00387 }
00388 else
00389 {
00390 size_t len;
00391 while ((len = m_queue.CurrentSize()) > 0)
00392 NextPutModifiable(m_queue.GetContigousBlocks(len), len);
00393 }
00394 }
00395
00396 void FilterWithBufferedInput::NextPutMultiple(const byte *inString, size_t length)
00397 {
00398 assert(m_blockSize > 1);
00399 while (length > 0)
00400 {
00401 assert(length >= m_blockSize);
00402 NextPutSingle(inString);
00403 inString += m_blockSize;
00404 length -= m_blockSize;
00405 }
00406 }
00407
00408
00409
00410 void Redirector::Initialize(const NameValuePairs ¶meters, int propagation)
00411 {
00412 m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL);
00413 m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING);
00414
00415 if (m_target && GetPassSignals())
00416 m_target->Initialize(parameters, propagation);
00417 }
00418
00419
00420
00421 ProxyFilter::ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment)
00422 : FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter)
00423 {
00424 if (m_filter.get())
00425 m_filter->Attach(new OutputProxy(*this, false));
00426 }
00427
00428 bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking)
00429 {
00430 return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false;
00431 }
00432
00433 void ProxyFilter::SetFilter(Filter *filter)
00434 {
00435 m_filter.reset(filter);
00436 if (filter)
00437 {
00438 OutputProxy *proxy;
00439 std::auto_ptr<OutputProxy> temp(proxy = new OutputProxy(*this, false));
00440 m_filter->TransferAllTo(*proxy);
00441 m_filter->Attach(temp.release());
00442 }
00443 }
00444
00445 void ProxyFilter::NextPutMultiple(const byte *s, size_t len)
00446 {
00447 if (m_filter.get())
00448 m_filter->Put(s, len);
00449 }
00450
00451 void ProxyFilter::NextPutModifiable(byte *s, size_t len)
00452 {
00453 if (m_filter.get())
00454 m_filter->PutModifiable(s, len);
00455 }
00456
00457
00458
00459 size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
00460 {
00461 memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
00462 m_total += length;
00463 return 0;
00464 }
00465
00466 byte * ArraySink::CreatePutSpace(size_t &size)
00467 {
00468 size = SaturatingSubtract(m_size, m_total);
00469 return m_buf + m_total;
00470 }
00471
00472 void ArraySink::IsolatedInitialize(const NameValuePairs ¶meters)
00473 {
00474 ByteArrayParameter array;
00475 if (!parameters.GetValue(Name::OutputBuffer(), array))
00476 throw InvalidArgument("ArraySink: missing OutputBuffer argument");
00477 m_buf = array.begin();
00478 m_size = array.size();
00479 m_total = 0;
00480 }
00481
00482 size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
00483 {
00484 xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
00485 m_total += length;
00486 return 0;
00487 }
00488
00489
00490
00491 size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding)
00492 {
00493 if (c.MinLastBlockSize() > 0)
00494 return c.MinLastBlockSize();
00495 else if (c.MandatoryBlockSize() > 1 && !c.IsForwardTransformation() && padding != NO_PADDING && padding != ZEROS_PADDING)
00496 return c.MandatoryBlockSize();
00497 else
00498 return 0;
00499 }
00500
00501 StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding)
00502 : FilterWithBufferedInput(0, c.MandatoryBlockSize(), LastBlockSize(c, padding), attachment)
00503 , m_cipher(c)
00504 {
00505 assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize());
00506
00507 bool isBlockCipher = (c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0);
00508
00509 if (padding == DEFAULT_PADDING)
00510 {
00511 if (isBlockCipher)
00512 m_padding = PKCS_PADDING;
00513 else
00514 m_padding = NO_PADDING;
00515 }
00516 else
00517 m_padding = padding;
00518
00519 if (!isBlockCipher && (m_padding == PKCS_PADDING || m_padding == ONE_AND_ZEROS_PADDING))
00520 throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING and ONE_AND_ZEROS_PADDING cannot be used with " + c.AlgorithmName());
00521 }
00522
00523 void StreamTransformationFilter::FirstPut(const byte *inString)
00524 {
00525 m_optimalBufferSize = m_cipher.OptimalBlockSize();
00526 m_optimalBufferSize = (unsigned int)STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));
00527 }
00528
00529 void StreamTransformationFilter::NextPutMultiple(const byte *inString, size_t length)
00530 {
00531 if (!length)
00532 return;
00533
00534 size_t s = m_cipher.MandatoryBlockSize();
00535
00536 do
00537 {
00538 size_t len = m_optimalBufferSize;
00539 byte *space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, s, length, len);
00540 if (len < length)
00541 {
00542 if (len == m_optimalBufferSize)
00543 len -= m_cipher.GetOptimalBlockSizeUsed();
00544 len = RoundDownToMultipleOf(len, s);
00545 }
00546 else
00547 len = length;
00548 m_cipher.ProcessString(space, inString, len);
00549 AttachedTransformation()->PutModifiable(space, len);
00550 inString += len;
00551 length -= len;
00552 }
00553 while (length > 0);
00554 }
00555
00556 void StreamTransformationFilter::NextPutModifiable(byte *inString, size_t length)
00557 {
00558 m_cipher.ProcessString(inString, length);
00559 AttachedTransformation()->PutModifiable(inString, length);
00560 }
00561
00562 void StreamTransformationFilter::LastPut(const byte *inString, size_t length)
00563 {
00564 byte *space = NULL;
00565
00566 switch (m_padding)
00567 {
00568 case NO_PADDING:
00569 case ZEROS_PADDING:
00570 if (length > 0)
00571 {
00572 size_t minLastBlockSize = m_cipher.MinLastBlockSize();
00573 bool isForwardTransformation = m_cipher.IsForwardTransformation();
00574
00575 if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize))
00576 {
00577
00578 size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_cipher.MandatoryBlockSize());
00579 space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, blockSize);
00580 memcpy(space, inString, length);
00581 memset(space + length, 0, blockSize - length);
00582 m_cipher.ProcessLastBlock(space, space, blockSize);
00583 AttachedTransformation()->Put(space, blockSize);
00584 }
00585 else
00586 {
00587 if (minLastBlockSize == 0)
00588 {
00589 if (isForwardTransformation)
00590 throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified");
00591 else
00592 throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
00593 }
00594
00595 space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, length, m_optimalBufferSize);
00596 m_cipher.ProcessLastBlock(space, inString, length);
00597 AttachedTransformation()->Put(space, length);
00598 }
00599 }
00600 break;
00601
00602 case PKCS_PADDING:
00603 case ONE_AND_ZEROS_PADDING:
00604 unsigned int s;
00605 s = m_cipher.MandatoryBlockSize();
00606 assert(s > 1);
00607 space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, s, m_optimalBufferSize);
00608 if (m_cipher.IsForwardTransformation())
00609 {
00610 assert(length < s);
00611 memcpy(space, inString, length);
00612 if (m_padding == PKCS_PADDING)
00613 {
00614 assert(s < 256);
00615 byte pad = byte(s-length);
00616 memset(space+length, pad, s-length);
00617 }
00618 else
00619 {
00620 space[length] = 0x80;
00621 memset(space+length+1, 0, s-length-1);
00622 }
00623 m_cipher.ProcessData(space, space, s);
00624 AttachedTransformation()->Put(space, s);
00625 }
00626 else
00627 {
00628 if (length != s)
00629 throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
00630 m_cipher.ProcessData(space, inString, s);
00631 if (m_padding == PKCS_PADDING)
00632 {
00633 byte pad = space[s-1];
00634 if (pad < 1 || pad > s || std::find_if(space+s-pad, space+s, std::bind2nd(std::not_equal_to<byte>(), pad)) != space+s)
00635 throw InvalidCiphertext("StreamTransformationFilter: invalid PKCS #7 block padding found");
00636 length = s-pad;
00637 }
00638 else
00639 {
00640 while (length > 1 && space[length-1] == 0)
00641 --length;
00642 if (space[--length] != 0x80)
00643 throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found");
00644 }
00645 AttachedTransformation()->Put(space, length);
00646 }
00647 break;
00648
00649 default:
00650 assert(false);
00651 }
00652 }
00653
00654
00655
00656 void HashFilter::IsolatedInitialize(const NameValuePairs ¶meters)
00657 {
00658 m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
00659 m_truncatedDigestSize = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1);
00660 m_hashModule.Restart();
00661 }
00662
00663 size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00664 {
00665 FILTER_BEGIN;
00666 m_hashModule.Update(inString, length);
00667 if (m_putMessage)
00668 FILTER_OUTPUT(1, inString, length, 0);
00669 if (messageEnd)
00670 {
00671 {
00672 size_t size;
00673 m_digestSize = m_hashModule.DigestSize();
00674 if (m_truncatedDigestSize >= 0 && (unsigned int)m_truncatedDigestSize < m_digestSize)
00675 m_digestSize = m_truncatedDigestSize;
00676 m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, m_digestSize, m_digestSize, size = m_digestSize);
00677 m_hashModule.TruncatedFinal(m_space, m_digestSize);
00678 }
00679 FILTER_OUTPUT(2, m_space, m_digestSize, messageEnd);
00680 }
00681 FILTER_END_NO_MESSAGE_END;
00682 }
00683
00684
00685
00686 HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags)
00687 : FilterWithBufferedInput(attachment)
00688 , m_hashModule(hm)
00689 {
00690 IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags));
00691 }
00692
00693 void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
00694 {
00695 m_flags = parameters.GetValueWithDefault(Name::HashVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
00696 m_hashModule.Restart();
00697 size_t size = m_hashModule.DigestSize();
00698 m_verified = false;
00699 firstSize = m_flags & HASH_AT_BEGIN ? size : 0;
00700 blockSize = 1;
00701 lastSize = m_flags & HASH_AT_BEGIN ? 0 : size;
00702 }
00703
00704 void HashVerificationFilter::FirstPut(const byte *inString)
00705 {
00706 if (m_flags & HASH_AT_BEGIN)
00707 {
00708 m_expectedHash.New(m_hashModule.DigestSize());
00709 memcpy(m_expectedHash, inString, m_expectedHash.size());
00710 if (m_flags & PUT_HASH)
00711 AttachedTransformation()->Put(inString, m_expectedHash.size());
00712 }
00713 }
00714
00715 void HashVerificationFilter::NextPutMultiple(const byte *inString, size_t length)
00716 {
00717 m_hashModule.Update(inString, length);
00718 if (m_flags & PUT_MESSAGE)
00719 AttachedTransformation()->Put(inString, length);
00720 }
00721
00722 void HashVerificationFilter::LastPut(const byte *inString, size_t length)
00723 {
00724 if (m_flags & HASH_AT_BEGIN)
00725 {
00726 assert(length == 0);
00727 m_verified = m_hashModule.Verify(m_expectedHash);
00728 }
00729 else
00730 {
00731 m_verified = (length==m_hashModule.DigestSize() && m_hashModule.Verify(inString));
00732 if (m_flags & PUT_HASH)
00733 AttachedTransformation()->Put(inString, length);
00734 }
00735
00736 if (m_flags & PUT_RESULT)
00737 AttachedTransformation()->Put(m_verified);
00738
00739 if ((m_flags & THROW_EXCEPTION) && !m_verified)
00740 throw HashVerificationFailed();
00741 }
00742
00743
00744
00745 void SignerFilter::IsolatedInitialize(const NameValuePairs ¶meters)
00746 {
00747 m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
00748 m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng));
00749 }
00750
00751 size_t SignerFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00752 {
00753 FILTER_BEGIN;
00754 m_messageAccumulator->Update(inString, length);
00755 if (m_putMessage)
00756 FILTER_OUTPUT(1, inString, length, 0);
00757 if (messageEnd)
00758 {
00759 m_buf.New(m_signer.SignatureLength());
00760 m_signer.Sign(m_rng, m_messageAccumulator.release(), m_buf);
00761 FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd);
00762 m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng));
00763 }
00764 FILTER_END_NO_MESSAGE_END;
00765 }
00766
00767 SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment, word32 flags)
00768 : FilterWithBufferedInput(attachment)
00769 , m_verifier(verifier)
00770 {
00771 IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags));
00772 }
00773
00774 void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
00775 {
00776 m_flags = parameters.GetValueWithDefault(Name::SignatureVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
00777 m_messageAccumulator.reset(m_verifier.NewVerificationAccumulator());
00778 size_t size = m_verifier.SignatureLength();
00779 assert(size != 0);
00780 m_verified = false;
00781 firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0;
00782 blockSize = 1;
00783 lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size;
00784 }
00785
00786 void SignatureVerificationFilter::FirstPut(const byte *inString)
00787 {
00788 if (m_flags & SIGNATURE_AT_BEGIN)
00789 {
00790 if (m_verifier.SignatureUpfront())
00791 m_verifier.InputSignature(*m_messageAccumulator, inString, m_verifier.SignatureLength());
00792 else
00793 {
00794 m_signature.New(m_verifier.SignatureLength());
00795 memcpy(m_signature, inString, m_signature.size());
00796 }
00797
00798 if (m_flags & PUT_SIGNATURE)
00799 AttachedTransformation()->Put(inString, m_signature.size());
00800 }
00801 else
00802 {
00803 assert(!m_verifier.SignatureUpfront());
00804 }
00805 }
00806
00807 void SignatureVerificationFilter::NextPutMultiple(const byte *inString, size_t length)
00808 {
00809 m_messageAccumulator->Update(inString, length);
00810 if (m_flags & PUT_MESSAGE)
00811 AttachedTransformation()->Put(inString, length);
00812 }
00813
00814 void SignatureVerificationFilter::LastPut(const byte *inString, size_t length)
00815 {
00816 if (m_flags & SIGNATURE_AT_BEGIN)
00817 {
00818 assert(length == 0);
00819 m_verifier.InputSignature(*m_messageAccumulator, m_signature, m_signature.size());
00820 m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator);
00821 }
00822 else
00823 {
00824 m_verifier.InputSignature(*m_messageAccumulator, inString, length);
00825 m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator);
00826 if (m_flags & PUT_SIGNATURE)
00827 AttachedTransformation()->Put(inString, length);
00828 }
00829
00830 if (m_flags & PUT_RESULT)
00831 AttachedTransformation()->Put(m_verified);
00832
00833 if ((m_flags & THROW_EXCEPTION) && !m_verified)
00834 throw SignatureVerificationFailed();
00835 }
00836
00837
00838
00839 size_t Source::PumpAll2(bool blocking)
00840 {
00841 unsigned int messageCount = UINT_MAX;
00842 do {
00843 RETURN_IF_NONZERO(PumpMessages2(messageCount, blocking));
00844 } while(messageCount == UINT_MAX);
00845
00846 return 0;
00847 }
00848
00849 bool Store::GetNextMessage()
00850 {
00851 if (!m_messageEnd && !AnyRetrievable())
00852 {
00853 m_messageEnd=true;
00854 return true;
00855 }
00856 else
00857 return false;
00858 }
00859
00860 unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
00861 {
00862 if (m_messageEnd || count == 0)
00863 return 0;
00864 else
00865 {
00866 CopyTo(target, ULONG_MAX, channel);
00867 if (GetAutoSignalPropagation())
00868 target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
00869 return 1;
00870 }
00871 }
00872
00873 void StringStore::StoreInitialize(const NameValuePairs ¶meters)
00874 {
00875 ConstByteArrayParameter array;
00876 if (!parameters.GetValue(Name::InputBuffer(), array))
00877 throw InvalidArgument("StringStore: missing InputBuffer argument");
00878 m_store = array.begin();
00879 m_length = array.size();
00880 m_count = 0;
00881 }
00882
00883 size_t StringStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
00884 {
00885 lword position = 0;
00886 size_t blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking);
00887 m_count += (size_t)position;
00888 transferBytes = position;
00889 return blockedBytes;
00890 }
00891
00892 size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
00893 {
00894 size_t i = UnsignedMin(m_length, m_count+begin);
00895 size_t len = UnsignedMin(m_length-i, end-begin);
00896 size_t blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking);
00897 if (!blockedBytes)
00898 begin += len;
00899 return blockedBytes;
00900 }
00901
00902 void RandomNumberStore::StoreInitialize(const NameValuePairs ¶meters)
00903 {
00904 parameters.GetRequiredParameter("RandomNumberStore", "RandomNumberGeneratorPointer", m_rng);
00905 int length;
00906 parameters.GetRequiredIntParameter("RandomNumberStore", "RandomNumberStoreSize", length);
00907 m_length = length;
00908 }
00909
00910 size_t RandomNumberStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
00911 {
00912 if (!blocking)
00913 throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object");
00914
00915 lword transferMax = transferBytes;
00916 for (transferBytes = 0; transferBytes<transferMax && m_count < (unsigned int)m_length; ++transferBytes, ++m_count)
00917 target.ChannelPut(channel, m_rng->GenerateByte());
00918 return 0;
00919 }
00920
00921 size_t NullStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
00922 {
00923 static const byte nullBytes[128] = {0};
00924 while (begin < end)
00925 {
00926 size_t len = (size_t)STDMIN(end-begin, lword(128));
00927 size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
00928 if (blockedBytes)
00929 return blockedBytes;
00930 begin += len;
00931 }
00932 return 0;
00933 }
00934
00935 size_t NullStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
00936 {
00937 lword begin = 0;
00938 size_t blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking);
00939 transferBytes = begin;
00940 m_size -= begin;
00941 return blockedBytes;
00942 }
00943
00944 NAMESPACE_END
00945
00946 #endif