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