Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | 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 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 &parameters, 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 &parameters, 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 &parameters) 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); // m_blockSize = 1 should always override this function 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 &parameters, 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 &parameters) 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 // do padding 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 &parameters) 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 &parameters, 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 &parameters) 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 &parameters, 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); // TODO: handle recoverable signature scheme 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 // TODO: switch length type 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 &parameters) 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 &parameters) 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

Generated on Wed Jul 21 19:15:25 2004 for Crypto++ by doxygen 1.3.7-20040704