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