Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

filters.cpp

00001 // filters.cpp - written and placed in the public domain by Wei Dai 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 &parameters, 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 &parameters, 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 &parameters) 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); // m_blockSize = 1 should always override this function 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 &parameters, 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 &parameters) 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 // do padding 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 &parameters) 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 &parameters, 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 &parameters) 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 &parameters, 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); // TODO: handle recoverable signature scheme 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 // TODO: switch length type 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 &parameters) 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

Generated on Wed Jul 28 08:07:07 2004 for Crypto++ by doxygen 1.3.7