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