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 unsigned int Filter::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
00052 {
00053 return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking);
00054 }
00055
00056 unsigned int Filter::TransferTo2(BufferedTransformation &target, unsigned long &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 unsigned int Filter::OutputModifiable(int outputSite, byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel)
00103 {
00104 if (messageEnd)
00105 messageEnd--;
00106 unsigned int result = AttachedTransformation()->PutModifiable2(inString, length, messageEnd, blocking);
00107 m_continueAt = result ? outputSite : 0;
00108 return result;
00109 }
00110
00111 unsigned int Filter::Output(int outputSite, const byte *inString, unsigned int length, int messageEnd, bool blocking, const std::string &channel)
00112 {
00113 if (messageEnd)
00114 messageEnd--;
00115 unsigned int 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 unsigned int MeterFilter::Put2(const byte *begin, unsigned int 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 unsigned int MeterFilter::PutModifiable2(byte *begin, unsigned int 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(unsigned int blockSize, unsigned int 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(unsigned int &numberOfBytes)
00220 {
00221 numberOfBytes = STDMIN(numberOfBytes, STDMIN((unsigned int)(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 unsigned int FilterWithBufferedInput::BlockQueue::GetAll(byte *outString)
00231 {
00232 unsigned int size = m_size;
00233 unsigned int 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, unsigned int length)
00242 {
00243 assert(m_size + length <= m_buffer.size());
00244 byte *end = (m_size < (unsigned int)(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size();
00245 unsigned int len = STDMIN(length, (unsigned int)(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(unsigned int firstSize, unsigned int blockSize, unsigned int 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 unsigned int FilterWithBufferedInput::PutMaybeModifiable(byte *inString, unsigned int length, int messageEnd, bool blocking, bool modifiable)
00289 {
00290 if (!blocking)
00291 throw BlockingInputOnly("FilterWithBufferedInput");
00292
00293 if (length != 0)
00294 {
00295 unsigned int newLength = m_queue.CurrentSize() + length;
00296
00297 if (!m_firstInputDone && newLength >= m_firstSize)
00298 {
00299 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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 unsigned int 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, unsigned int 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, unsigned int firstSize, unsigned int 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, unsigned int len)
00446 {
00447 if (m_filter.get())
00448 m_filter->Put(s, len);
00449 }
00450
00451 void ProxyFilter::NextPutModifiable(byte *s, unsigned int len)
00452 {
00453 if (m_filter.get())
00454 m_filter->PutModifiable(s, len);
00455 }
00456
00457
00458
00459 unsigned int ArraySink::Put2(const byte *begin, unsigned int 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(unsigned int &size)
00467 {
00468 size = 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 unsigned int ArrayXorSink::Put2(const byte *begin, unsigned int 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 unsigned int 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 = STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));
00527 }
00528
00529 void StreamTransformationFilter::NextPutMultiple(const byte *inString, unsigned int length)
00530 {
00531 if (!length)
00532 return;
00533
00534 unsigned int s = m_cipher.MandatoryBlockSize();
00535
00536 do
00537 {
00538 unsigned int 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, unsigned int length)
00557 {
00558 m_cipher.ProcessString(inString, length);
00559 AttachedTransformation()->PutModifiable(inString, length);
00560 }
00561
00562 void StreamTransformationFilter::LastPut(const byte *inString, unsigned int 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 unsigned int 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 unsigned int blockSize = STDMAX(minLastBlockSize, 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 = 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_hashModule.Restart();
00660 }
00661
00662 unsigned int HashFilter::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00663 {
00664 FILTER_BEGIN;
00665 m_hashModule.Update(inString, length);
00666 if (m_putMessage)
00667 FILTER_OUTPUT(1, inString, length, 0);
00668 if (messageEnd)
00669 {
00670 {
00671 unsigned int size, digestSize = m_hashModule.DigestSize();
00672 m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, digestSize, digestSize, size = digestSize);
00673 m_hashModule.Final(m_space);
00674 }
00675 FILTER_OUTPUT(2, m_space, m_hashModule.DigestSize(), messageEnd);
00676 }
00677 FILTER_END_NO_MESSAGE_END;
00678 }
00679
00680
00681
00682 HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags)
00683 : FilterWithBufferedInput(attachment)
00684 , m_hashModule(hm)
00685 {
00686 IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags));
00687 }
00688
00689 void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
00690 {
00691 m_flags = parameters.GetValueWithDefault(Name::HashVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
00692 m_hashModule.Restart();
00693 unsigned int size = m_hashModule.DigestSize();
00694 m_verified = false;
00695 firstSize = m_flags & HASH_AT_BEGIN ? size : 0;
00696 blockSize = 1;
00697 lastSize = m_flags & HASH_AT_BEGIN ? 0 : size;
00698 }
00699
00700 void HashVerificationFilter::FirstPut(const byte *inString)
00701 {
00702 if (m_flags & HASH_AT_BEGIN)
00703 {
00704 m_expectedHash.New(m_hashModule.DigestSize());
00705 memcpy(m_expectedHash, inString, m_expectedHash.size());
00706 if (m_flags & PUT_HASH)
00707 AttachedTransformation()->Put(inString, m_expectedHash.size());
00708 }
00709 }
00710
00711 void HashVerificationFilter::NextPutMultiple(const byte *inString, unsigned int length)
00712 {
00713 m_hashModule.Update(inString, length);
00714 if (m_flags & PUT_MESSAGE)
00715 AttachedTransformation()->Put(inString, length);
00716 }
00717
00718 void HashVerificationFilter::LastPut(const byte *inString, unsigned int length)
00719 {
00720 if (m_flags & HASH_AT_BEGIN)
00721 {
00722 assert(length == 0);
00723 m_verified = m_hashModule.Verify(m_expectedHash);
00724 }
00725 else
00726 {
00727 m_verified = (length==m_hashModule.DigestSize() && m_hashModule.Verify(inString));
00728 if (m_flags & PUT_HASH)
00729 AttachedTransformation()->Put(inString, length);
00730 }
00731
00732 if (m_flags & PUT_RESULT)
00733 AttachedTransformation()->Put(m_verified);
00734
00735 if ((m_flags & THROW_EXCEPTION) && !m_verified)
00736 throw HashVerificationFailed();
00737 }
00738
00739
00740
00741 void SignerFilter::IsolatedInitialize(const NameValuePairs ¶meters)
00742 {
00743 m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
00744 m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng));
00745 }
00746
00747 unsigned int SignerFilter::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00748 {
00749 FILTER_BEGIN;
00750 m_messageAccumulator->Update(inString, length);
00751 if (m_putMessage)
00752 FILTER_OUTPUT(1, inString, length, 0);
00753 if (messageEnd)
00754 {
00755 m_buf.New(m_signer.SignatureLength());
00756 m_signer.Sign(m_rng, m_messageAccumulator.release(), m_buf);
00757 FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd);
00758 m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng));
00759 }
00760 FILTER_END_NO_MESSAGE_END;
00761 }
00762
00763 SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment, word32 flags)
00764 : FilterWithBufferedInput(attachment)
00765 , m_verifier(verifier)
00766 {
00767 IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags));
00768 }
00769
00770 void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, unsigned int &firstSize, unsigned int &blockSize, unsigned int &lastSize)
00771 {
00772 m_flags = parameters.GetValueWithDefault(Name::SignatureVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
00773 m_messageAccumulator.reset(m_verifier.NewVerificationAccumulator());
00774 unsigned int size = m_verifier.SignatureLength();
00775 assert(size != 0);
00776 m_verified = false;
00777 firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0;
00778 blockSize = 1;
00779 lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size;
00780 }
00781
00782 void SignatureVerificationFilter::FirstPut(const byte *inString)
00783 {
00784 if (m_flags & SIGNATURE_AT_BEGIN)
00785 {
00786 if (m_verifier.SignatureUpfront())
00787 m_verifier.InputSignature(*m_messageAccumulator, inString, m_verifier.SignatureLength());
00788 else
00789 {
00790 m_signature.New(m_verifier.SignatureLength());
00791 memcpy(m_signature, inString, m_signature.size());
00792 }
00793
00794 if (m_flags & PUT_SIGNATURE)
00795 AttachedTransformation()->Put(inString, m_signature.size());
00796 }
00797 else
00798 {
00799 assert(!m_verifier.SignatureUpfront());
00800 }
00801 }
00802
00803 void SignatureVerificationFilter::NextPutMultiple(const byte *inString, unsigned int length)
00804 {
00805 m_messageAccumulator->Update(inString, length);
00806 if (m_flags & PUT_MESSAGE)
00807 AttachedTransformation()->Put(inString, length);
00808 }
00809
00810 void SignatureVerificationFilter::LastPut(const byte *inString, unsigned int length)
00811 {
00812 if (m_flags & SIGNATURE_AT_BEGIN)
00813 {
00814 assert(length == 0);
00815 m_verifier.InputSignature(*m_messageAccumulator, m_signature, m_signature.size());
00816 m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator);
00817 }
00818 else
00819 {
00820 m_verifier.InputSignature(*m_messageAccumulator, inString, length);
00821 m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator);
00822 if (m_flags & PUT_SIGNATURE)
00823 AttachedTransformation()->Put(inString, length);
00824 }
00825
00826 if (m_flags & PUT_RESULT)
00827 AttachedTransformation()->Put(m_verified);
00828
00829 if ((m_flags & THROW_EXCEPTION) && !m_verified)
00830 throw SignatureVerificationFailed();
00831 }
00832
00833
00834
00835 unsigned int Source::PumpAll2(bool blocking)
00836 {
00837
00838 unsigned long i = UINT_MAX;
00839 RETURN_IF_NONZERO(Pump2(i, blocking));
00840 unsigned int j = UINT_MAX;
00841 return PumpMessages2(j, blocking);
00842 }
00843
00844 bool Store::GetNextMessage()
00845 {
00846 if (!m_messageEnd && !AnyRetrievable())
00847 {
00848 m_messageEnd=true;
00849 return true;
00850 }
00851 else
00852 return false;
00853 }
00854
00855 unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
00856 {
00857 if (m_messageEnd || count == 0)
00858 return 0;
00859 else
00860 {
00861 CopyTo(target, ULONG_MAX, channel);
00862 if (GetAutoSignalPropagation())
00863 target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
00864 return 1;
00865 }
00866 }
00867
00868 void StringStore::StoreInitialize(const NameValuePairs ¶meters)
00869 {
00870 ConstByteArrayParameter array;
00871 if (!parameters.GetValue(Name::InputBuffer(), array))
00872 throw InvalidArgument("StringStore: missing InputBuffer argument");
00873 m_store = array.begin();
00874 m_length = array.size();
00875 m_count = 0;
00876 }
00877
00878 unsigned int StringStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
00879 {
00880 unsigned long position = 0;
00881 unsigned int blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking);
00882 m_count += position;
00883 transferBytes = position;
00884 return blockedBytes;
00885 }
00886
00887 unsigned int StringStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
00888 {
00889 unsigned int i = (unsigned int)STDMIN((unsigned long)m_count+begin, (unsigned long)m_length);
00890 unsigned int len = (unsigned int)STDMIN((unsigned long)m_length-i, end-begin);
00891 unsigned int blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking);
00892 if (!blockedBytes)
00893 begin += len;
00894 return blockedBytes;
00895 }
00896
00897 void RandomNumberStore::StoreInitialize(const NameValuePairs ¶meters)
00898 {
00899 parameters.GetRequiredParameter("RandomNumberStore", "RandomNumberGeneratorPointer", m_rng);
00900 parameters.GetRequiredIntParameter("RandomNumberStore", "RandomNumberStoreSize", m_length);
00901 }
00902
00903 unsigned int RandomNumberStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
00904 {
00905 if (!blocking)
00906 throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object");
00907
00908 unsigned long transferMax = transferBytes;
00909 for (transferBytes = 0; transferBytes<transferMax && m_count < (unsigned long)m_length; ++transferBytes, ++m_count)
00910 target.ChannelPut(channel, m_rng->GenerateByte());
00911 return 0;
00912 }
00913
00914 unsigned int NullStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
00915 {
00916 static const byte nullBytes[128] = {0};
00917 while (begin < end)
00918 {
00919 unsigned int len = STDMIN(end-begin, 128UL);
00920 unsigned int blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
00921 if (blockedBytes)
00922 return blockedBytes;
00923 begin += len;
00924 }
00925 return 0;
00926 }
00927
00928 unsigned int NullStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
00929 {
00930 unsigned long begin = 0;
00931 unsigned int blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking);
00932 transferBytes = begin;
00933 m_size -= begin;
00934 return blockedBytes;
00935 }
00936
00937 NAMESPACE_END
00938
00939 #endif