<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>Crypto++: cryptlib.h Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.3.7 --> <div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical List</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="namespacemembers.html">Namespace Members</a> | <a class="qindex" href="functions.html">Class Members</a> | <a class="qindex" href="globals.html">File Members</a></div> <h1>cryptlib.h</h1><a href="cryptlib_8h.html">Go to the documentation of this file.</a><pre class="fragment"><div>00001 <span class="comment">// cryptlib.h - written and placed in the public domain by Wei Dai</span><span class="comment"></span> 00002 <span class="comment">/*! \file</span> 00003 <span class="comment"> This file contains the declarations for the abstract base</span> 00004 <span class="comment"> classes that provide a uniform interface to this library.</span> 00005 <span class="comment">*/</span> 00006 <span class="comment"></span> 00007 <span class="comment">/*! \mainpage <a href="http://www.cryptopp.com">Crypto++</a><sup><small>TM</small></sup> Library 5.2.1 Reference Manual</span> 00008 <span class="comment"><dl></span> 00009 <span class="comment"><dt>Abstract Base Classes<dd></span> 00010 <span class="comment"> cryptlib.h</span> 00011 <span class="comment"><dt>Symmetric Ciphers<dd></span> 00012 <span class="comment"> SymmetricCipherDocumentation</span> 00013 <span class="comment"><dt>Hash Functions<dd></span> 00014 <span class="comment"> HAVAL, MD2, MD4, MD5, PanamaHash, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, SHA, SHA256, SHA384, SHA512, Tiger, Whirlpool</span> 00015 <span class="comment"><dt>Non-Cryptographic Checksums<dd></span> 00016 <span class="comment"> CRC32, Adler32</span> 00017 <span class="comment"><dt>Message Authentication Codes<dd></span> 00018 <span class="comment"> #MD5MAC, XMACC, HMAC, CBC_MAC, DMAC, PanamaMAC, TTMAC</span> 00019 <span class="comment"><dt>Random Number Generators<dd></span> 00020 <span class="comment"> NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG</span> 00021 <span class="comment"><dt>Password-based Cryptography<dd></span> 00022 <span class="comment"> PasswordBasedKeyDerivationFunction</span> 00023 <span class="comment"><dt>Public Key Cryptosystems<dd></span> 00024 <span class="comment"> DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES</span> 00025 <span class="comment"><dt>Public Key Signature Schemes<dd></span> 00026 <span class="comment"> DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RabinSS, RWSS, ESIGN</span> 00027 <span class="comment"><dt>Key Agreement<dd></span> 00028 <span class="comment"> #DH, DH2, #MQV, ECDH, ECMQV, XTR_DH</span> 00029 <span class="comment"><dt>Algebraic Structures<dd></span> 00030 <span class="comment"> Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver,</span> 00031 <span class="comment"> ModularArithmetic, MontgomeryRepresentation, GFP2_ONB,</span> 00032 <span class="comment"> GF2NP, GF256, GF2_32, EC2N, ECP</span> 00033 <span class="comment"><dt>Secret Sharing and Information Dispersal<dd></span> 00034 <span class="comment"> SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery</span> 00035 <span class="comment"><dt>Compression<dd></span> 00036 <span class="comment"> Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor</span> 00037 <span class="comment"><dt>Input Source Classes<dd></span> 00038 <span class="comment"> StringSource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource</span> 00039 <span class="comment"><dt>Output Sink Classes<dd></span> 00040 <span class="comment"> StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink</span> 00041 <span class="comment"><dt>Filter Wrappers<dd></span> 00042 <span class="comment"> StreamTransformationFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter</span> 00043 <span class="comment"><dt>Binary to Text Encoders and Decoders<dd></span> 00044 <span class="comment"> HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base32Encoder, Base32Decoder</span> 00045 <span class="comment"><dt>Wrappers for OS features<dd></span> 00046 <span class="comment"> Timer, Socket, WindowsHandle, ThreadLocalStorage, ThreadUserTimer</span> 00047 <span class="comment"><dt>FIPS 140 related<dd></span> 00048 <span class="comment"> fips140.h</span> 00049 <span class="comment"></dl></span> 00050 <span class="comment"></span> 00051 <span class="comment">In the FIPS 140-2 validated DLL version of Crypto++, only the following implementation class are available.</span> 00052 <span class="comment"><dl></span> 00053 <span class="comment"><dt>Block Ciphers<dd></span> 00054 <span class="comment"> AES, DES_EDE2, DES_EDE3, SKIPJACK</span> 00055 <span class="comment"><dt>Cipher Modes (replace template parameter BC with one of the block ciphers above)<dd></span> 00056 <span class="comment"> ECB_Mode<BC>, CTR_Mode<BC>, CBC_Mode<BC>, CFB_Mode<BC>, OFB_Mode<BC></span> 00057 <span class="comment"><dt>Hash Functions<dd></span> 00058 <span class="comment"> SHA</span> 00059 <span class="comment"><dt>Public Key Signature Schemes<dd></span> 00060 <span class="comment"> RSASS<PKCS1v15, SHA>, DSA, ECDSA<ECP, SHA>, ECDSA<EC2N, SHA></span> 00061 <span class="comment"><dt>Message Authentication Codes<dd></span> 00062 <span class="comment"> HMAC<SHA>, CBC_MAC<DES_EDE2>, CBC_MAC<DES_EDE3></span> 00063 <span class="comment"><dt>Random Number Generators<dd></span> 00064 <span class="comment"> AutoSeededX917RNG<DES_EDE3></span> 00065 <span class="comment"><dt>Key Agreement<dd></span> 00066 <span class="comment"> #DH</span> 00067 <span class="comment"><dt>Public Key Cryptosystems<dd></span> 00068 <span class="comment"> RSAES<OAEP<SHA> ></span> 00069 <span class="comment"></dl></span> 00070 <span class="comment"></span> 00071 <span class="comment"><p>This reference manual is a work in progress. Some classes are still lacking detailed descriptions.</span> 00072 <span class="comment"><p>Click <a href="CryptoPPRef.zip">here</a> to download a zip archive containing this manual.</span> 00073 <span class="comment"><p>Thanks to Ryan Phillips for providing the Doxygen configuration file</span> 00074 <span class="comment">and getting me started with this manual.</span> 00075 <span class="comment">*/</span> 00076 00077 <span class="preprocessor">#ifndef CRYPTOPP_CRYPTLIB_H</span> 00078 <span class="preprocessor"></span><span class="preprocessor">#define CRYPTOPP_CRYPTLIB_H</span> 00079 <span class="preprocessor"></span> 00080 <span class="preprocessor">#include "config.h"</span> 00081 <span class="preprocessor">#include "stdcpp.h"</span> 00082 00083 NAMESPACE_BEGIN(CryptoPP) 00084 00085 <span class="comment">// forward declarations</span> 00086 class <a class="code" href="class_integer.html">Integer</a>; 00087 <span class="comment"></span> 00088 <span class="comment">//! used to specify a direction for a cipher to operate in (encrypt or decrypt)</span> <a name="l00089"></a><a class="code" href="cryptlib_8h.html#a11">00089</a> <span class="comment"></span>enum CipherDir {ENCRYPTION, DECRYPTION}; 00090 <span class="comment"></span> 00091 <span class="comment">//! used to represent infinite time</span> <a name="l00092"></a><a class="code" href="cryptlib_8h.html#a0">00092</a> <span class="comment"></span><span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <a class="code" href="cryptlib_8h.html#a0">INFINITE_TIME</a> = ULONG_MAX; 00093 00094 <span class="comment">// VC60 workaround: using enums as template parameters causes problems</span> 00095 <span class="keyword">template</span> <<span class="keyword">typename</span> ENUM_TYPE, <span class="keywordtype">int</span> VALUE> 00096 <span class="keyword">struct </span>EnumToType 00097 { 00098 <span class="keyword">static</span> ENUM_TYPE ToEnum() {<span class="keywordflow">return</span> (ENUM_TYPE)VALUE;} 00099 }; 00100 00101 <span class="keyword">enum</span> ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1}; 00102 <span class="keyword">typedef</span> EnumToType<ByteOrder, LITTLE_ENDIAN_ORDER> LittleEndian; 00103 <span class="keyword">typedef</span> EnumToType<ByteOrder, BIG_ENDIAN_ORDER> BigEndian; 00104 <span class="comment"></span> 00105 <span class="comment">//! base class for all exceptions thrown by Crypto++</span> <a name="l00106"></a><a class="code" href="class_exception.html">00106</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL Exception : <span class="keyword">public</span> std::exception 00107 { 00108 <span class="keyword">public</span>:<span class="comment"></span> 00109 <span class="comment"> //! error types</span> <a name="l00110"></a><a class="code" href="class_exception.html#_windows_pipe_1_1_errw7">00110</a> <span class="comment"></span> <span class="keyword">enum</span> ErrorType {<span class="comment"></span> 00111 <span class="comment"> //! a method is not implemented</span> 00112 <span class="comment"></span> NOT_IMPLEMENTED,<span class="comment"></span> 00113 <span class="comment"> //! invalid function argument</span> 00114 <span class="comment"></span> INVALID_ARGUMENT,<span class="comment"></span> 00115 <span class="comment"> //! BufferedTransformation received a Flush(true) signal but can't flush buffers</span> 00116 <span class="comment"></span> CANNOT_FLUSH,<span class="comment"></span> 00117 <span class="comment"> //! data integerity check (such as CRC or MAC) failed</span> 00118 <span class="comment"></span> DATA_INTEGRITY_CHECK_FAILED,<span class="comment"></span> 00119 <span class="comment"> //! received input data that doesn't conform to expected format</span> 00120 <span class="comment"></span> INVALID_DATA_FORMAT,<span class="comment"></span> 00121 <span class="comment"> //! error reading from input device or writing to output device</span> 00122 <span class="comment"></span> IO_ERROR,<span class="comment"></span> 00123 <span class="comment"> //! some error not belong to any of the above categories</span> 00124 <span class="comment"></span> OTHER_ERROR 00125 }; 00126 00127 <span class="keyword">explicit</span> Exception(ErrorType errorType, <span class="keyword">const</span> std::string &s) : m_errorType(errorType), m_what(s) {} 00128 <span class="keyword">virtual</span> ~Exception() throw() {} 00129 <span class="keyword">const</span> <span class="keywordtype">char</span> *what() const throw() {<span class="keywordflow">return</span> (m_what.c_str());} 00130 <span class="keyword">const</span> std::string &GetWhat()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_what;} 00131 <span class="keywordtype">void</span> SetWhat(<span class="keyword">const</span> std::string &s) {m_what = s;} 00132 ErrorType GetErrorType()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_errorType;} 00133 <span class="keywordtype">void</span> SetErrorType(ErrorType errorType) {m_errorType = errorType;} 00134 00135 <span class="keyword">private</span>: 00136 ErrorType m_errorType; 00137 std::string m_what; 00138 }; 00139 <span class="comment"></span> 00140 <span class="comment">//! exception thrown when an invalid argument is detected</span> <a name="l00141"></a><a class="code" href="class_invalid_argument.html">00141</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL InvalidArgument : <span class="keyword">public</span> Exception 00142 { 00143 <span class="keyword">public</span>: 00144 <span class="keyword">explicit</span> InvalidArgument(<span class="keyword">const</span> std::string &s) : Exception(INVALID_ARGUMENT, s) {} 00145 }; 00146 <span class="comment"></span> 00147 <span class="comment">//! exception thrown by decryption filters when trying to decrypt an invalid ciphertext</span> <a name="l00148"></a><a class="code" href="class_invalid_data_format.html">00148</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL InvalidDataFormat : <span class="keyword">public</span> Exception 00149 { 00150 <span class="keyword">public</span>: 00151 <span class="keyword">explicit</span> InvalidDataFormat(<span class="keyword">const</span> std::string &s) : Exception(INVALID_DATA_FORMAT, s) {} 00152 }; 00153 <span class="comment"></span> 00154 <span class="comment">//! exception thrown by decryption filters when trying to decrypt an invalid ciphertext</span> <a name="l00155"></a><a class="code" href="class_invalid_ciphertext.html">00155</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL InvalidCiphertext : <span class="keyword">public</span> InvalidDataFormat 00156 { 00157 <span class="keyword">public</span>: 00158 <span class="keyword">explicit</span> InvalidCiphertext(<span class="keyword">const</span> std::string &s) : InvalidDataFormat(s) {} 00159 }; 00160 <span class="comment"></span> 00161 <span class="comment">//! exception thrown by a class if a non-implemented method is called</span> <a name="l00162"></a><a class="code" href="class_not_implemented.html">00162</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL NotImplemented : <span class="keyword">public</span> Exception 00163 { 00164 <span class="keyword">public</span>: 00165 <span class="keyword">explicit</span> NotImplemented(<span class="keyword">const</span> std::string &s) : Exception(NOT_IMPLEMENTED, s) {} 00166 }; 00167 <span class="comment"></span> 00168 <span class="comment">//! exception thrown by a class when Flush(true) is called but it can't completely flush its buffers</span> <a name="l00169"></a><a class="code" href="class_cannot_flush.html">00169</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL CannotFlush : <span class="keyword">public</span> Exception 00170 { 00171 <span class="keyword">public</span>: 00172 <span class="keyword">explicit</span> CannotFlush(<span class="keyword">const</span> std::string &s) : Exception(CANNOT_FLUSH, s) {} 00173 }; 00174 <span class="comment"></span> 00175 <span class="comment">//! error reported by the operating system</span> <a name="l00176"></a><a class="code" href="class_o_s___error.html">00176</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL OS_Error : <span class="keyword">public</span> Exception 00177 { 00178 <span class="keyword">public</span>: 00179 OS_Error(ErrorType errorType, <span class="keyword">const</span> std::string &s, <span class="keyword">const</span> std::string& operation, <span class="keywordtype">int</span> errorCode) 00180 : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {} 00181 ~OS_Error() <span class="keywordflow">throw</span>() {} 00182 00183 <span class="comment">// the operating system API that reported the error</span> 00184 <span class="keyword">const</span> std::string & GetOperation()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_operation;} 00185 <span class="comment">// the error code return by the operating system</span> 00186 <span class="keywordtype">int</span> GetErrorCode()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_errorCode;} 00187 00188 <span class="keyword">protected</span>: 00189 std::string m_operation; 00190 <span class="keywordtype">int</span> m_errorCode; 00191 }; 00192 <span class="comment"></span> 00193 <span class="comment">//! used to return decoding results</span> <a name="l00194"></a><a class="code" href="struct_decoding_result.html">00194</a> <span class="comment"></span><span class="keyword">struct </span>CRYPTOPP_DLL DecodingResult 00195 { 00196 <span class="keyword">explicit</span> DecodingResult() : isValidCoding(<span class="keyword">false</span>), messageLength(0) {} 00197 <span class="keyword">explicit</span> DecodingResult(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len) : isValidCoding(<span class="keyword">true</span>), messageLength(len) {} 00198 00199 <span class="keywordtype">bool</span> operator==(<span class="keyword">const</span> DecodingResult &rhs)<span class="keyword"> const </span>{<span class="keywordflow">return</span> isValidCoding == rhs.<a class="code" href="struct_decoding_result.html#_decoding_resulto0">isValidCoding</a> && messageLength == rhs.<a class="code" href="struct_decoding_result.html#_decoding_resulto1">messageLength</a>;} 00200 <span class="keywordtype">bool</span> operator!=(<span class="keyword">const</span> DecodingResult &rhs)<span class="keyword"> const </span>{<span class="keywordflow">return</span> !operator==(rhs);} 00201 00202 <span class="keywordtype">bool</span> isValidCoding; 00203 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> messageLength; 00204 00205 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 00206 <span class="preprocessor"></span> operator unsigned int()<span class="keyword"> const </span>{<span class="keywordflow">return</span> isValidCoding ? messageLength : 0;} 00207 <span class="preprocessor">#endif</span> 00208 <span class="preprocessor"></span>}; 00209 <span class="comment"></span> 00210 <span class="comment">//! interface for retrieving values given their names</span> 00211 <span class="comment"></span><span class="comment">/*! \note This class is used to safely pass a variable number of arbitrarily typed arguments to functions</span> 00212 <span class="comment"> and to read values from keys and crypto parameters.</span> 00213 <span class="comment"> \note To obtain an object that implements NameValuePairs for the purpose of parameter</span> 00214 <span class="comment"> passing, use the MakeParameters() function.</span> 00215 <span class="comment"> \note To get a value from NameValuePairs, you need to know the name and the type of the value. </span> 00216 <span class="comment"> Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports.</span> 00217 <span class="comment"> Then look at the Name namespace documentation to see what the type of each value is, or</span> 00218 <span class="comment"> alternatively, call GetIntValue() with the value name, and if the type is not int, a</span> 00219 <span class="comment"> ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object.</span> 00220 <span class="comment">*/</span> <a name="l00221"></a><a class="code" href="class_name_value_pairs.html">00221</a> <span class="keyword">class </span>CRYPTOPP_NO_VTABLE NameValuePairs 00222 { 00223 <span class="keyword">public</span>: 00224 <span class="keyword">virtual</span> ~NameValuePairs() {} 00225 <span class="comment"></span> 00226 <span class="comment"> //! exception thrown when trying to retrieve a value using a different type than expected</span> <a name="l00227"></a><a class="code" href="class_name_value_pairs_1_1_value_type_mismatch.html">00227</a> <span class="comment"></span> <span class="keyword">class </span>CRYPTOPP_DLL ValueTypeMismatch : <span class="keyword">public</span> InvalidArgument 00228 { 00229 <span class="keyword">public</span>: 00230 ValueTypeMismatch(<span class="keyword">const</span> std::string &name, <span class="keyword">const</span> std::type_info &stored, <span class="keyword">const</span> std::type_info &retrieving) 00231 : InvalidArgument(<span class="stringliteral">"NameValuePairs: type mismatch for '"</span> + name + <span class="stringliteral">"', stored '"</span> + stored.name() + <span class="stringliteral">"', trying to retrieve '"</span> + retrieving.name() + <span class="stringliteral">"'"</span>) 00232 , m_stored(stored), m_retrieving(retrieving) {} 00233 00234 <span class="keyword">const</span> std::type_info & GetStoredTypeInfo()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_stored;} 00235 <span class="keyword">const</span> std::type_info & GetRetrievingTypeInfo()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_retrieving;} 00236 00237 <span class="keyword">private</span>: 00238 <span class="keyword">const</span> std::type_info &m_stored; 00239 <span class="keyword">const</span> std::type_info &m_retrieving; 00240 }; 00241 <span class="comment"></span> 00242 <span class="comment"> //! get a copy of this object or a subobject of it</span> 00243 <span class="comment"></span> <span class="keyword">template</span> <<span class="keyword">class</span> T> <a name="l00244"></a><a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha37">00244</a> <span class="keywordtype">bool</span> GetThisObject(T &object)<span class="keyword"> const</span> 00245 <span class="keyword"> </span>{ 00246 <span class="keywordflow">return</span> GetValue((std::string(<span class="stringliteral">"ThisObject:"</span>)+<span class="keyword">typeid</span>(T).name()).c_str(), object); 00247 } 00248 <span class="comment"></span> 00249 <span class="comment"> //! get a pointer to this object, as a pointer to T</span> 00250 <span class="comment"></span> <span class="keyword">template</span> <<span class="keyword">class</span> T> <a name="l00251"></a><a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha38">00251</a> <span class="keywordtype">bool</span> GetThisPointer(T *&p)<span class="keyword"> const</span> 00252 <span class="keyword"> </span>{ 00253 <span class="keywordflow">return</span> GetValue((std::string(<span class="stringliteral">"ThisPointer:"</span>)+<span class="keyword">typeid</span>(T).name()).c_str(), p); 00254 } 00255 <span class="comment"></span> 00256 <span class="comment"> //! get a named value, returns true if the name exists</span> 00257 <span class="comment"></span> <span class="keyword">template</span> <<span class="keyword">class</span> T> <a name="l00258"></a><a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha39">00258</a> <span class="keywordtype">bool</span> GetValue(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, T &value)<span class="keyword"> const</span> 00259 <span class="keyword"> </span>{ 00260 <span class="keywordflow">return</span> GetVoidValue(name, <span class="keyword">typeid</span>(T), &value); 00261 } 00262 <span class="comment"></span> 00263 <span class="comment"> //! get a named value, returns the default if the name doesn't exist</span> 00264 <span class="comment"></span> <span class="keyword">template</span> <<span class="keyword">class</span> T> <a name="l00265"></a><a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha40">00265</a> T GetValueWithDefault(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, T defaultValue)<span class="keyword"> const</span> 00266 <span class="keyword"> </span>{ 00267 GetValue(name, defaultValue); 00268 <span class="keywordflow">return</span> defaultValue; 00269 } 00270 <span class="comment"></span> 00271 <span class="comment"> //! get a list of value names that can be retrieved</span> <a name="l00272"></a><a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha41">00272</a> <span class="comment"></span> CRYPTOPP_DLL std::string GetValueNames()<span class="keyword"> const</span> 00273 <span class="keyword"> </span>{std::string result; GetValue(<span class="stringliteral">"ValueNames"</span>, result); <span class="keywordflow">return</span> result;} 00274 <span class="comment"></span> 00275 <span class="comment"> //! get a named value with type int</span> 00276 <span class="comment"></span><span class="comment"> /*! used to ensure we don't accidentally try to get an unsigned int</span> 00277 <span class="comment"> or some other type when we mean int (which is the most common case) */</span> <a name="l00278"></a><a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha42">00278</a> CRYPTOPP_DLL <span class="keywordtype">bool</span> GetIntValue(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keywordtype">int</span> &value)<span class="keyword"> const</span> 00279 <span class="keyword"> </span>{<span class="keywordflow">return</span> GetValue(name, value);} 00280 <span class="comment"></span> 00281 <span class="comment"> //! get a named value with type int, with default</span> <a name="l00282"></a><a class="code" href="class_name_value_pairs.html#_x_t_r___d_ha43">00282</a> <span class="comment"></span> CRYPTOPP_DLL <span class="keywordtype">int</span> GetIntValueWithDefault(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keywordtype">int</span> defaultValue)<span class="keyword"> const</span> 00283 <span class="keyword"> </span>{<span class="keywordflow">return</span> GetValueWithDefault(name, defaultValue);} 00284 <span class="comment"></span> 00285 <span class="comment"> //! used by derived classes to check for type mismatch</span> <a name="l00286"></a><a class="code" href="class_name_value_pairs.html#_x_t_r___d_he0">00286</a> <span class="comment"></span> CRYPTOPP_DLL <span class="keyword">static</span> <span class="keywordtype">void</span> ThrowIfTypeMismatch(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keyword">const</span> std::type_info &stored, <span class="keyword">const</span> std::type_info &retrieving) 00287 {<span class="keywordflow">if</span> (stored != retrieving) <span class="keywordflow">throw</span> ValueTypeMismatch(name, stored, retrieving);} 00288 00289 <span class="keyword">template</span> <<span class="keyword">class</span> T> 00290 <span class="keywordtype">void</span> GetRequiredParameter(<span class="keyword">const</span> <span class="keywordtype">char</span> *className, <span class="keyword">const</span> <span class="keywordtype">char</span> *name, T &value)<span class="keyword"> const</span> 00291 <span class="keyword"> </span>{ 00292 <span class="keywordflow">if</span> (!GetValue(name, value)) 00293 <span class="keywordflow">throw</span> InvalidArgument(std::string(className) + <span class="stringliteral">": missing required parameter '"</span> + name + <span class="stringliteral">"'"</span>); 00294 } 00295 00296 CRYPTOPP_DLL <span class="keywordtype">void</span> GetRequiredIntParameter(<span class="keyword">const</span> <span class="keywordtype">char</span> *className, <span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keywordtype">int</span> &value)<span class="keyword"> const</span> 00297 <span class="keyword"> </span>{ 00298 <span class="keywordflow">if</span> (!GetIntValue(name, value)) 00299 <span class="keywordflow">throw</span> InvalidArgument(std::string(className) + <span class="stringliteral">": missing required parameter '"</span> + name + <span class="stringliteral">"'"</span>); 00300 } 00301 <span class="comment"></span> 00302 <span class="comment"> //! to be implemented by derived classes, users should use one of the above functions instead</span> 00303 <span class="comment"></span> CRYPTOPP_DLL <span class="keyword">virtual</span> <span class="keywordtype">bool</span> GetVoidValue(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keyword">const</span> std::type_info &valueType, <span class="keywordtype">void</span> *pValue) <span class="keyword">const</span> =0; 00304 }; 00305 <span class="comment"></span> 00306 <span class="comment">//! namespace containing value name definitions</span> 00307 <span class="comment"></span><span class="comment">/*! value names, types and semantics:</span> 00308 <span class="comment"></span> 00309 <span class="comment"> ThisObject:ClassName (ClassName, copy of this object or a subobject)</span> 00310 <span class="comment"> ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject)</span> 00311 <span class="comment">*/</span> 00312 DOCUMENTED_NAMESPACE_BEGIN(Name) 00313 <span class="comment">// more names defined in argnames.h</span> 00314 DOCUMENTED_NAMESPACE_END 00315 <span class="comment"></span> 00316 <span class="comment">//! empty set of name-value pairs</span> <a name="l00317"></a><a class="code" href="class_null_name_value_pairs.html">00317</a> <span class="comment"></span>class CRYPTOPP_DLL <a class="code" href="class_null_name_value_pairs.html">NullNameValuePairs</a> : public NameValuePairs 00318 { 00319 <span class="keyword">public</span>: <a name="l00320"></a><a class="code" href="class_null_name_value_pairs.html#_null_name_value_pairsa0">00320</a> <span class="keywordtype">bool</span> GetVoidValue(<span class="keyword">const</span> <span class="keywordtype">char</span> *name, <span class="keyword">const</span> std::type_info &valueType, <span class="keywordtype">void</span> *pValue)<span class="keyword"> const </span>{<span class="keywordflow">return</span> <span class="keyword">false</span>;} 00321 }; 00322 <span class="comment"></span> 00323 <span class="comment">//! _</span> <a name="l00324"></a><a class="code" href="cryptlib_8h.html#a3">00324</a> <span class="comment"></span><span class="keyword">extern</span> CRYPTOPP_DLL <span class="keyword">const</span> <a class="code" href="class_null_name_value_pairs.html">NullNameValuePairs</a> g_nullNameValuePairs; 00325 00326 <span class="comment">// ********************************************************</span> 00327 <span class="comment"></span> 00328 <span class="comment">//! interface for cloning objects, this is not implemented by most classes yet</span> <a name="l00329"></a><a class="code" href="class_clonable.html">00329</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable 00330 { 00331 <span class="keyword">public</span>: 00332 <span class="keyword">virtual</span> ~Clonable() {}<span class="comment"></span> 00333 <span class="comment"> //! this is not implemented by most classes yet</span> <a name="l00334"></a><a class="code" href="class_clonable.html#_zlib_decompressora18">00334</a> <span class="comment"></span> <span class="keyword">virtual</span> Clonable* Clone()<span class="keyword"> const </span>{<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"Clone() is not implemented yet."</span>);} <span class="comment">// TODO: make this =0</span> 00335 }; 00336 <span class="comment"></span> 00337 <span class="comment">//! interface for all crypto algorithms</span> 00338 <span class="comment"></span> <a name="l00339"></a><a class="code" href="class_algorithm.html">00339</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Algorithm : <span class="keyword">public</span> Clonable 00340 { 00341 <span class="keyword">public</span>:<span class="comment"></span> 00342 <span class="comment"> /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true,</span> 00343 <span class="comment"> this constructor throws SelfTestFailure if the self test hasn't been run or fails. */</span> 00344 Algorithm(<span class="keywordtype">bool</span> checkSelfTestStatus = <span class="keyword">true</span>);<span class="comment"></span> 00345 <span class="comment"> //! returns name of this algorithm, not universally implemented yet</span> <a name="l00346"></a><a class="code" href="class_algorithm.html#_zlib_decompressora17">00346</a> <span class="comment"></span> <span class="keyword">virtual</span> std::string AlgorithmName()<span class="keyword"> const </span>{<span class="keywordflow">return</span> <span class="stringliteral">"unknown"</span>;} 00347 }; 00348 <span class="comment"></span> 00349 <span class="comment">//! keying interface for crypto algorithms that take byte strings as keys</span> 00350 <span class="comment"></span> <a name="l00351"></a><a class="code" href="class_simple_keying_interface.html">00351</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyingInterface 00352 { 00353 <span class="keyword">public</span>:<span class="comment"></span> 00354 <span class="comment"> //! returns smallest valid key length in bytes */</span> 00355 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MinKeyLength() <span class="keyword">const</span> =0;<span class="comment"></span> 00356 <span class="comment"> //! returns largest valid key length in bytes */</span> 00357 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MaxKeyLength() <span class="keyword">const</span> =0;<span class="comment"></span> 00358 <span class="comment"> //! returns default (recommended) key length in bytes */</span> 00359 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> DefaultKeyLength() <span class="keyword">const</span> =0; 00360 <span class="comment"></span> 00361 <span class="comment"> //! returns the smallest valid key length in bytes that is >= min(n, GetMaxKeyLength())</span> 00362 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetValidKeyLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n) <span class="keyword">const</span> =0; 00363 <span class="comment"></span> 00364 <span class="comment"> //! returns whether n is a valid key length</span> <a name="l00365"></a><a class="code" href="class_simple_keying_interface.html#_x_m_a_c_c___basea21">00365</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsValidKeyLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n)<span class="keyword"> const</span> 00366 <span class="keyword"> </span>{<span class="keywordflow">return</span> n == GetValidKeyLength(n);} 00367 <span class="comment"></span> 00368 <span class="comment"> //! set or reset the key of this object</span> 00369 <span class="comment"></span><span class="comment"> /*! \param params is used to specify Rounds, BlockSize, etc */</span> 00370 <span class="keyword">virtual</span> <span class="keywordtype">void</span> SetKey(<span class="keyword">const</span> byte *key, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keyword">const</span> NameValuePairs &params = g_nullNameValuePairs) =0; 00371 <span class="comment"></span> 00372 <span class="comment"> //! calls SetKey() with an NameValuePairs object that just specifies "Rounds"</span> 00373 <span class="comment"></span> <span class="keywordtype">void</span> SetKeyWithRounds(<span class="keyword">const</span> byte *key, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> rounds); 00374 <span class="comment"></span> 00375 <span class="comment"> //! calls SetKey() with an NameValuePairs object that just specifies "IV"</span> 00376 <span class="comment"></span> <span class="keywordtype">void</span> SetKeyWithIV(<span class="keyword">const</span> byte *key, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keyword">const</span> byte *iv); 00377 00378 <span class="keyword">enum</span> IV_Requirement {STRUCTURED_IV = 0, RANDOM_IV, UNPREDICTABLE_RANDOM_IV, INTERNALLY_GENERATED_IV, NOT_RESYNCHRONIZABLE};<span class="comment"></span> 00379 <span class="comment"> //! returns the minimal requirement for secure IVs</span> 00380 <span class="comment"></span> <span class="keyword">virtual</span> IV_Requirement IVRequirement() const =0; 00381 <span class="comment"></span> 00382 <span class="comment"> //! returns whether this object can be resynchronized (i.e. supports initialization vectors)</span> 00383 <span class="comment"></span><span class="comment"> /*! If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, an IV of all 0's will be assumed. */</span> <a name="l00384"></a><a class="code" href="class_simple_keying_interface.html#_x_m_a_c_c___basea26">00384</a> <span class="keywordtype">bool</span> IsResynchronizable()<span class="keyword"> const </span>{<span class="keywordflow">return</span> IVRequirement() < NOT_RESYNCHRONIZABLE;}<span class="comment"></span> 00385 <span class="comment"> //! returns whether this object can use random IVs (in addition to ones returned by GetNextIV)</span> <a name="l00386"></a><a class="code" href="class_simple_keying_interface.html#_x_m_a_c_c___basea27">00386</a> <span class="comment"></span> <span class="keywordtype">bool</span> CanUseRandomIVs()<span class="keyword"> const </span>{<span class="keywordflow">return</span> IVRequirement() <= UNPREDICTABLE_RANDOM_IV;}<span class="comment"></span> 00387 <span class="comment"> //! returns whether this object can use random but possibly predictable IVs (in addition to ones returned by GetNextIV)</span> <a name="l00388"></a><a class="code" href="class_simple_keying_interface.html#_x_m_a_c_c___basea28">00388</a> <span class="comment"></span> <span class="keywordtype">bool</span> CanUsePredictableIVs()<span class="keyword"> const </span>{<span class="keywordflow">return</span> IVRequirement() <= RANDOM_IV;}<span class="comment"></span> 00389 <span class="comment"> //! returns whether this object can use structured IVs, for example a counter (in addition to ones returned by GetNextIV)</span> <a name="l00390"></a><a class="code" href="class_simple_keying_interface.html#_x_m_a_c_c___basea29">00390</a> <span class="comment"></span> <span class="keywordtype">bool</span> CanUseStructuredIVs()<span class="keyword"> const </span>{<span class="keywordflow">return</span> IVRequirement() <= STRUCTURED_IV;} 00391 <span class="comment"></span> 00392 <span class="comment"> //! returns size of IVs used by this object</span> <a name="l00393"></a><a class="code" href="class_simple_keying_interface.html#_x_m_a_c_c___basea30">00393</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> IVSize()<span class="keyword"> const </span>{<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"SimpleKeyingInterface: this object doesn't support resynchronization"</span>);}<span class="comment"></span> 00394 <span class="comment"> //! resynchronize with an IV</span> <a name="l00395"></a><a class="code" href="class_simple_keying_interface.html#_x_m_a_c_c___basea31">00395</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Resynchronize(<span class="keyword">const</span> byte *IV) {<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"SimpleKeyingInterface: this object doesn't support resynchronization"</span>);}<span class="comment"></span> 00396 <span class="comment"> //! get a secure IV for the next message</span> 00397 <span class="comment"></span><span class="comment"> /*! This method should be called after you finish encrypting one message and are ready to start the next one.</span> 00398 <span class="comment"> After calling it, you must call SetKey() or Resynchronize() before using this object again. </span> 00399 <span class="comment"> This method is not implemented on decryption objects. */</span> <a name="l00400"></a><a class="code" href="class_simple_keying_interface.html#_x_m_a_c_c___basea32">00400</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> GetNextIV(byte *IV) {<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"SimpleKeyingInterface: this object doesn't support GetNextIV()"</span>);} 00401 00402 <span class="keyword">protected</span>: 00403 <span class="keywordtype">void</span> ThrowIfInvalidKeyLength(<span class="keyword">const</span> Algorithm &algorithm, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length); 00404 <span class="keywordtype">void</span> ThrowIfResynchronizable(); <span class="comment">// to be called when no IV is passed</span> 00405 <span class="keywordtype">void</span> ThrowIfInvalidIV(<span class="keyword">const</span> byte *iv); <span class="comment">// check for NULL IV if it can't be used</span> 00406 <span class="keyword">const</span> byte * GetIVAndThrowIfInvalid(<span class="keyword">const</span> NameValuePairs &params); 00407 00408 <span class="keyword">inline</span> <span class="keywordtype">void</span> AssertValidKeyLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length)<span class="keyword"> const</span> 00409 <span class="keyword"> </span>{ 00410 assert(IsValidKeyLength(length)); 00411 } 00412 }; 00413 <span class="comment"></span> 00414 <span class="comment">//! interface for the data processing part of block ciphers</span> 00415 <span class="comment"></span><span class="comment"></span> 00416 <span class="comment">/*! Classes derived from BlockTransformation are block ciphers</span> 00417 <span class="comment"> in ECB mode (for example the DES::Encryption class), which are stateless,</span> 00418 <span class="comment"> and they can make assumptions about the memory alignment of their inputs and outputs.</span> 00419 <span class="comment"> These classes should not be used directly, but only in combination with</span> 00420 <span class="comment"> a mode class (see CipherModeDocumentation in modes.h).</span> 00421 <span class="comment">*/</span> <a name="l00422"></a><a class="code" href="class_block_transformation.html">00422</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : <span class="keyword">public</span> Algorithm 00423 { 00424 <span class="keyword">public</span>:<span class="comment"></span> 00425 <span class="comment"> //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock</span> 00426 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> ProcessAndXorBlock(<span class="keyword">const</span> byte *inBlock, <span class="keyword">const</span> byte *xorBlock, byte *outBlock) <span class="keyword">const</span> =0; 00427 <span class="comment"></span> 00428 <span class="comment"> //! encrypt or decrypt one block</span> 00429 <span class="comment"></span><span class="comment"> /*! \pre size of inBlock and outBlock == BlockSize() */</span> <a name="l00430"></a><a class="code" href="class_block_transformation.html#_simple_keying_interface_impl_3_01_block_cipher_00_01_b_t_e_a___info_01_4a6">00430</a> <span class="keywordtype">void</span> ProcessBlock(<span class="keyword">const</span> byte *inBlock, byte *outBlock)<span class="keyword"> const</span> 00431 <span class="keyword"> </span>{ProcessAndXorBlock(inBlock, NULL, outBlock);} 00432 <span class="comment"></span> 00433 <span class="comment"> //! encrypt or decrypt one block in place</span> <a name="l00434"></a><a class="code" href="class_block_transformation.html#_simple_keying_interface_impl_3_01_block_cipher_00_01_b_t_e_a___info_01_4a7">00434</a> <span class="comment"></span> <span class="keywordtype">void</span> ProcessBlock(byte *inoutBlock)<span class="keyword"> const</span> 00435 <span class="keyword"> </span>{ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);} 00436 <span class="comment"></span> 00437 <span class="comment"> //! block size of the cipher in bytes</span> 00438 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BlockSize() const =0; 00439 <span class="comment"></span> 00440 <span class="comment"> //! block pointers must be divisible by this</span> <a name="l00441"></a><a class="code" href="class_block_transformation.html#_simple_keying_interface_impl_3_01_block_cipher_00_01_b_t_e_a___info_01_4a9">00441</a> <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BlockAlignment()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 4;} 00442 <span class="comment"></span> 00443 <span class="comment"> //! returns true if this is a permutation (i.e. there is an inverse transformation)</span> <a name="l00444"></a><a class="code" href="class_block_transformation.html#_simple_keying_interface_impl_3_01_block_cipher_00_01_b_t_e_a___info_01_4a10">00444</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsPermutation()<span class="keyword"> const </span>{<span class="keywordflow">return</span> <span class="keyword">true</span>;} 00445 <span class="comment"></span> 00446 <span class="comment"> //! returns true if this is an encryption object</span> 00447 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsForwardTransformation() const =0; 00448 <span class="comment"></span> 00449 <span class="comment"> //! return number of blocks that can be processed in parallel, for bit-slicing implementations</span> <a name="l00450"></a><a class="code" href="class_block_transformation.html#_simple_keying_interface_impl_3_01_block_cipher_00_01_b_t_e_a___info_01_4a12">00450</a> <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> OptimalNumberOfParallelBlocks()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 1;} 00451 <span class="comment"></span> 00452 <span class="comment"> //! encrypt or decrypt multiple blocks, for bit-slicing implementations</span> 00453 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> ProcessAndXorMultipleBlocks(<span class="keyword">const</span> byte *inBlocks, <span class="keyword">const</span> byte *xorBlocks, byte *outBlocks, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> numberOfBlocks) <span class="keyword">const</span>; 00454 }; 00455 <span class="comment"></span> 00456 <span class="comment">//! interface for the data processing part of stream ciphers</span> 00457 <span class="comment"></span> <a name="l00458"></a><a class="code" href="class_stream_transformation.html">00458</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : <span class="keyword">public</span> Algorithm 00459 { 00460 <span class="keyword">public</span>:<span class="comment"></span> 00461 <span class="comment"> //! return a reference to this object, </span> 00462 <span class="comment"></span><span class="comment"> /*! This function is useful for passing a temporary StreamTransformation object to a </span> 00463 <span class="comment"> function that takes a non-const reference. */</span> <a name="l00464"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a22">00464</a> StreamTransformation& Ref() {<span class="keywordflow">return</span> *<span class="keyword">this</span>;} 00465 <span class="comment"></span> 00466 <span class="comment"> //! returns block size, if input must be processed in blocks, otherwise 1</span> <a name="l00467"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a23">00467</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MandatoryBlockSize()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 1;} 00468 <span class="comment"></span> 00469 <span class="comment"> //! returns the input block size that is most efficient for this cipher</span> 00470 <span class="comment"></span><span class="comment"> /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */</span> <a name="l00471"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a24">00471</a> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> OptimalBlockSize()<span class="keyword"> const </span>{<span class="keywordflow">return</span> MandatoryBlockSize();}<span class="comment"></span> 00472 <span class="comment"> //! returns how much of the current block is used up</span> <a name="l00473"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a25">00473</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetOptimalBlockSizeUsed()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 0;} 00474 <span class="comment"></span> 00475 <span class="comment"> //! returns how input should be aligned for optimal performance</span> <a name="l00476"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a26">00476</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> OptimalDataAlignment()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 1;} 00477 <span class="comment"></span> 00478 <span class="comment"> //! encrypt or decrypt an array of bytes of specified length</span> 00479 <span class="comment"></span><span class="comment"> /*! \note either inString == outString, or they don't overlap */</span> 00480 <span class="keyword">virtual</span> <span class="keywordtype">void</span> ProcessData(byte *outString, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) =0; 00481 <span class="comment"></span> 00482 <span class="comment"> //! for ciphers where the last block of data is special, encrypt or decrypt the last block of data</span> 00483 <span class="comment"></span><span class="comment"> /*! For now the only use of this function is for CBC-CTS mode. */</span> 00484 <span class="keyword">virtual</span> <span class="keywordtype">void</span> ProcessLastBlock(byte *outString, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length);<span class="comment"></span> 00485 <span class="comment"> //! returns the minimum size of the last block, 0 indicating the last block is not special</span> <a name="l00486"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a28">00486</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MinLastBlockSize()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 0;} 00487 <span class="comment"></span> 00488 <span class="comment"> //! same as ProcessData(inoutString, inoutString, length)</span> <a name="l00489"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a29">00489</a> <span class="comment"></span> <span class="keyword">inline</span> <span class="keywordtype">void</span> ProcessString(byte *inoutString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00490 {ProcessData(inoutString, inoutString, length);}<span class="comment"></span> 00491 <span class="comment"> //! same as ProcessData(outString, inString, length)</span> <a name="l00492"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a30">00492</a> <span class="comment"></span> <span class="keyword">inline</span> <span class="keywordtype">void</span> ProcessString(byte *outString, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00493 {ProcessData(outString, inString, length);}<span class="comment"></span> 00494 <span class="comment"> //! implemented as {ProcessData(&input, &input, 1); return input;}</span> <a name="l00495"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a31">00495</a> <span class="comment"></span> <span class="keyword">inline</span> byte ProcessByte(byte input) 00496 {ProcessData(&input, &input, 1); <span class="keywordflow">return</span> input;} 00497 <span class="comment"></span> 00498 <span class="comment"> //! returns whether this cipher supports random access</span> 00499 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsRandomAccess() const =0;<span class="comment"></span> 00500 <span class="comment"> //! for random access ciphers, seek to an absolute position</span> <a name="l00501"></a><a class="code" href="class_stream_transformation.html#_symmetric_cipher_final_3_01_m_a_r_c4___base_01_4a32">00501</a> <span class="comment"></span> virtual <span class="keywordtype">void</span> Seek(lword n) 00502 { 00503 assert(!IsRandomAccess()); 00504 <span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"StreamTransformation: this object doesn't support random access"</span>); 00505 } 00506 <span class="comment"></span> 00507 <span class="comment"> //! returns whether this transformation is self-inverting (e.g. xor with a keystream)</span> 00508 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsSelfInverting() const =0;<span class="comment"></span> 00509 <span class="comment"> //! returns whether this is an encryption object</span> 00510 <span class="comment"></span> virtual <span class="keywordtype">bool</span> IsForwardTransformation() const =0; 00511 }; 00512 <span class="comment"></span> 00513 <span class="comment">//! interface for hash functions and data processing part of MACs</span> 00514 <span class="comment"></span><span class="comment"></span> 00515 <span class="comment">/*! HashTransformation objects are stateful. They are created in an initial state,</span> 00516 <span class="comment"> change state as Update() is called, and return to the initial</span> 00517 <span class="comment"> state when Final() is called. This interface allows a large message to</span> 00518 <span class="comment"> be hashed in pieces by calling Update() on each piece followed by</span> 00519 <span class="comment"> calling Final().</span> 00520 <span class="comment">*/</span> <a name="l00521"></a><a class="code" href="class_hash_transformation.html">00521</a> class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE <a class="code" href="class_hash_transformation.html">HashTransformation</a> : public Algorithm 00522 { 00523 <span class="keyword">public</span>:<span class="comment"></span> 00524 <span class="comment"> //! process more input</span> 00525 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Update(<span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) =0; 00526 <span class="comment"></span> 00527 <span class="comment"> //! request space to write input into</span> <a name="l00528"></a><a class="code" href="class_hash_transformation.html#_two_bases_3_01_message_authentication_code_00_01_variable_key_length_3_0132_00_010_00_01_u_i_n_t___m_a_x_01_4_01_4a1">00528</a> <span class="comment"></span> <span class="keyword">virtual</span> byte * CreateUpdateSpace(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &size) {size=0; <span class="keywordflow">return</span> NULL;} 00529 <span class="comment"></span> 00530 <span class="comment"> //! compute hash for current message, then restart for a new message</span> 00531 <span class="comment"></span><span class="comment"> /*! \pre size of digest == DigestSize(). */</span> <a name="l00532"></a><a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea7">00532</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Final(byte *digest) 00533 {TruncatedFinal(digest, DigestSize());} 00534 <span class="comment"></span> 00535 <span class="comment"> //! discard the current state, and restart with a new message</span> <a name="l00536"></a><a class="code" href="class_hash_transformation.html#_two_bases_3_01_message_authentication_code_00_01_variable_key_length_3_0132_00_010_00_01_u_i_n_t___m_a_x_01_4_01_4a3">00536</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Restart() 00537 {TruncatedFinal(NULL, 0);} 00538 <span class="comment"></span> 00539 <span class="comment"> //! size of the hash returned by Final()</span> 00540 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> DigestSize() const =0; 00541 <span class="comment"></span> 00542 <span class="comment"> //! block size of underlying compression function, or 0 if not block based</span> <a name="l00543"></a><a class="code" href="class_hash_transformation.html#_two_bases_3_01_message_authentication_code_00_01_variable_key_length_3_0132_00_010_00_01_u_i_n_t___m_a_x_01_4_01_4a5">00543</a> <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BlockSize()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 0;} 00544 <span class="comment"></span> 00545 <span class="comment"> //! input to Update() should have length a multiple of this for optimal speed</span> <a name="l00546"></a><a class="code" href="class_hash_transformation.html#_two_bases_3_01_message_authentication_code_00_01_variable_key_length_3_0132_00_010_00_01_u_i_n_t___m_a_x_01_4_01_4a6">00546</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> OptimalBlockSize()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 1;} 00547 <span class="comment"></span> 00548 <span class="comment"> //! returns how input should be aligned for optimal performance</span> <a name="l00549"></a><a class="code" href="class_hash_transformation.html#_two_bases_3_01_message_authentication_code_00_01_variable_key_length_3_0132_00_010_00_01_u_i_n_t___m_a_x_01_4_01_4a7">00549</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> OptimalDataAlignment()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 1;} 00550 <span class="comment"></span> 00551 <span class="comment"> //! use this if your input is in one piece and you don't want to call Update() and Final() separately</span> <a name="l00552"></a><a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea9">00552</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> CalculateDigest(byte *digest, <span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00553 {Update(input, length); Final(digest);} 00554 <span class="comment"></span> 00555 <span class="comment"> //! verify that digest is a valid digest for the current message, then reinitialize the object</span> 00556 <span class="comment"></span><span class="comment"> /*! Default implementation is to call Final() and do a bitwise comparison</span> 00557 <span class="comment"> between its output and digest. */</span> <a name="l00558"></a><a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea10">00558</a> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Verify(<span class="keyword">const</span> byte *digest) 00559 {<span class="keywordflow">return</span> TruncatedVerify(digest, DigestSize());} 00560 <span class="comment"></span> 00561 <span class="comment"> //! use this if your input is in one piece and you don't want to call Update() and Verify() separately</span> <a name="l00562"></a><a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea11">00562</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> VerifyDigest(<span class="keyword">const</span> byte *digest, <span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00563 {Update(input, length); <span class="keywordflow">return</span> Verify(digest);} 00564 <span class="comment"></span> 00565 <span class="comment"> //! truncated version of Final()</span> 00566 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> TruncatedFinal(byte *digest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> digestSize) =0; 00567 <span class="comment"></span> 00568 <span class="comment"> //! truncated version of CalculateDigest()</span> <a name="l00569"></a><a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea12">00569</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> CalculateTruncatedDigest(byte *digest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> digestSize, <span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00570 {Update(input, length); TruncatedFinal(digest, digestSize);} 00571 <span class="comment"></span> 00572 <span class="comment"> //! truncated version of Verify()</span> 00573 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> TruncatedVerify(<span class="keyword">const</span> byte *digest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> digestLength); 00574 <span class="comment"></span> 00575 <span class="comment"> //! truncated version of VerifyDigest()</span> <a name="l00576"></a><a class="code" href="class_hash_transformation.html#_x_m_a_c_c___basea14">00576</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> VerifyTruncatedDigest(<span class="keyword">const</span> byte *digest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> digestLength, <span class="keyword">const</span> byte *input, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00577 {Update(input, length); <span class="keywordflow">return</span> TruncatedVerify(digest, digestLength);} 00578 00579 <span class="keyword">protected</span>: 00580 <span class="keywordtype">void</span> ThrowIfInvalidTruncatedSize(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) <span class="keyword">const</span>; 00581 }; 00582 00583 <span class="keyword">typedef</span> <a class="code" href="class_hash_transformation.html">HashTransformation</a> <a class="code" href="class_hash_transformation.html">HashFunction</a>; 00584 00585 <span class="keyword">template</span> <<span class="keyword">class</span> T> 00586 <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyedTransformation : <span class="keyword">public</span> T, <span class="keyword">public</span> SimpleKeyingInterface 00587 { 00588 <span class="keyword">public</span>: 00589 <span class="keywordtype">void</span> ThrowIfInvalidKeyLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00590 {SimpleKeyingInterface::ThrowIfInvalidKeyLength(*<span class="keyword">this</span>, length);} 00591 }; 00592 00593 <span class="preprocessor">#ifdef CRYPTOPP_DOXYGEN_PROCESSING</span> 00594 <span class="preprocessor"></span><span class="comment">//! interface for one direction (encryption or decryption) of a block cipher</span> 00595 <span class="comment"></span><span class="comment">/*! \note These objects usually should not be used directly. See BlockTransformation for more details. */</span> <a name="l00596"></a><a class="code" href="class_block_cipher.html">00596</a> <span class="keyword">class </span><a class="code" href="class_block_cipher.html">BlockCipher</a> : <span class="keyword">public</span> BlockTransformation, <span class="keyword">public</span> SimpleKeyingInterface {};<span class="comment"></span> 00597 <span class="comment">//! interface for one direction (encryption or decryption) of a stream cipher or cipher mode</span> <a name="l00598"></a><a class="code" href="class_symmetric_cipher.html">00598</a> <span class="comment"></span><span class="keyword">class </span><a class="code" href="class_symmetric_cipher.html">SymmetricCipher</a> : <span class="keyword">public</span> StreamTransformation, <span class="keyword">public</span> SimpleKeyingInterface {};<span class="comment"></span> 00599 <span class="comment">//! interface for message authentication codes</span> <a name="l00600"></a><a class="code" href="class_message_authentication_code.html">00600</a> <span class="comment"></span><span class="keyword">class </span><a class="code" href="class_message_authentication_code.html">MessageAuthenticationCode</a> : <span class="keyword">public</span> <a class="code" href="class_hash_transformation.html">HashTransformation</a>, <span class="keyword">public</span> SimpleKeyingInterface {}; 00601 <span class="preprocessor">#else</span> 00602 <span class="preprocessor"></span><span class="keyword">typedef</span> SimpleKeyedTransformation<BlockTransformation> <a class="code" href="class_block_cipher.html">BlockCipher</a>; 00603 <span class="keyword">typedef</span> SimpleKeyedTransformation<StreamTransformation> <a class="code" href="class_symmetric_cipher.html">SymmetricCipher</a>; 00604 <span class="keyword">typedef</span> SimpleKeyedTransformation<HashTransformation> <a class="code" href="class_message_authentication_code.html">MessageAuthenticationCode</a>; 00605 <span class="preprocessor">#endif</span> 00606 <span class="preprocessor"></span> 00607 CRYPTOPP_DLL_TEMPLATE_CLASS SimpleKeyedTransformation<BlockTransformation>; 00608 CRYPTOPP_DLL_TEMPLATE_CLASS SimpleKeyedTransformation<StreamTransformation>; 00609 CRYPTOPP_DLL_TEMPLATE_CLASS SimpleKeyedTransformation<HashTransformation>; 00610 00611 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 00612 <span class="preprocessor"></span><span class="keyword">typedef</span> <a class="code" href="class_symmetric_cipher.html">SymmetricCipher</a> StreamCipher; 00613 <span class="preprocessor">#endif</span> 00614 <span class="preprocessor"></span><span class="comment"></span> 00615 <span class="comment">//! interface for random number generators</span> 00616 <span class="comment"></span><span class="comment">/*! All return values are uniformly distributed over the range specified.</span> 00617 <span class="comment">*/</span> <a name="l00618"></a><a class="code" href="class_random_number_generator.html">00618</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : <span class="keyword">public</span> Algorithm 00619 { 00620 <span class="keyword">public</span>:<span class="comment"></span> 00621 <span class="comment"> //! generate new random byte and return it</span> 00622 <span class="comment"></span> <span class="keyword">virtual</span> byte GenerateByte() =0; 00623 <span class="comment"></span> 00624 <span class="comment"> //! generate new random bit and return it</span> 00625 <span class="comment"></span><span class="comment"> /*! Default implementation is to call GenerateByte() and return its parity. */</span> 00626 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GenerateBit(); 00627 <span class="comment"></span> 00628 <span class="comment"> //! generate a random 32 bit word in the range min to max, inclusive</span> 00629 <span class="comment"></span> <span class="keyword">virtual</span> word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL); 00630 <span class="comment"></span> 00631 <span class="comment"> //! generate random array of bytes</span> 00632 <span class="comment"></span><span class="comment"> /*! Default implementation is to call GenerateByte() size times. */</span> 00633 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GenerateBlock(byte *output, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size); 00634 <span class="comment"></span> 00635 <span class="comment"> //! generate and discard n bytes</span> 00636 <span class="comment"></span><span class="comment"> /*! Default implementation is to call GenerateByte() n times. */</span> 00637 <span class="keyword">virtual</span> <span class="keywordtype">void</span> DiscardBytes(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n); 00638 <span class="comment"></span> 00639 <span class="comment"> //! randomly shuffle the specified array, resulting permutation is uniformly distributed</span> <a name="l00640"></a><a class="code" href="class_random_number_generator.html#_x917_r_n_ga6">00640</a> <span class="comment"></span> <span class="keyword">template</span> <<span class="keyword">class</span> IT> <span class="keywordtype">void</span> Shuffle(IT begin, IT end) 00641 { 00642 <span class="keywordflow">for</span> (; begin != end; ++begin) 00643 std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1)); 00644 } 00645 00646 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 00647 <span class="preprocessor"></span> byte GetByte() {<span class="keywordflow">return</span> GenerateByte();} 00648 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetBit() {<span class="keywordflow">return</span> GenerateBit();} 00649 word32 GetLong(word32 a=0, word32 b=0xffffffffL) {<span class="keywordflow">return</span> GenerateWord32(a, b);} 00650 word16 GetShort(word16 a=0, word16 b=0xffff) {<span class="keywordflow">return</span> (word16)GenerateWord32(a, b);} 00651 <span class="keywordtype">void</span> GetBlock(byte *output, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> size) {GenerateBlock(output, size);} 00652 <span class="preprocessor">#endif</span> 00653 <span class="preprocessor"></span>}; 00654 <span class="comment"></span> 00655 <span class="comment">//! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it</span> 00656 <span class="comment"></span>CRYPTOPP_DLL RandomNumberGenerator & NullRNG(); 00657 00658 <span class="keyword">class </span><a class="code" href="class_wait_object_container.html">WaitObjectContainer</a>; 00659 <span class="comment"></span> 00660 <span class="comment">//! interface for objects that you can wait for</span> 00661 <span class="comment"></span> <a name="l00662"></a><a class="code" href="class_waitable.html">00662</a> <span class="keyword">class </span>CRYPTOPP_NO_VTABLE Waitable 00663 { 00664 <span class="keyword">public</span>:<span class="comment"></span> 00665 <span class="comment"> //! maximum number of wait objects that this object can return</span> 00666 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetMaxWaitObjectCount() <span class="keyword">const</span> =0;<span class="comment"></span> 00667 <span class="comment"> //! put wait objects into container</span> 00668 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> GetWaitObjects(<a class="code" href="class_wait_object_container.html">WaitObjectContainer</a> &container) =0;<span class="comment"></span> 00669 <span class="comment"> //! wait on this object</span> 00670 <span class="comment"></span><span class="comment"> /*! same as creating an empty container, calling GetWaitObjects(), and calling Wait() on the container */</span> 00671 <span class="keywordtype">bool</span> Wait(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> milliseconds); 00672 }; 00673 <span class="comment"></span> 00674 <span class="comment">//! interface for buffered transformations</span> 00675 <span class="comment"></span><span class="comment"></span> 00676 <span class="comment">/*! BufferedTransformation is a generalization of BlockTransformation,</span> 00677 <span class="comment"> StreamTransformation, and HashTransformation.</span> 00678 <span class="comment"></span> 00679 <span class="comment"> A buffered transformation is an object that takes a stream of bytes</span> 00680 <span class="comment"> as input (this may be done in stages), does some computation on them, and</span> 00681 <span class="comment"> then places the result into an internal buffer for later retrieval. Any</span> 00682 <span class="comment"> partial result already in the output buffer is not modified by further</span> 00683 <span class="comment"> input.</span> 00684 <span class="comment"></span> 00685 <span class="comment"> If a method takes a "blocking" parameter, and you</span> 00686 <span class="comment"> pass "false" for it, the method will return before all input has been processed if</span> 00687 <span class="comment"> the input cannot be processed without waiting (for network buffers to become available, for example).</span> 00688 <span class="comment"> In this case the method will return true</span> 00689 <span class="comment"> or a non-zero integer value. When this happens you must continue to call the method with the same</span> 00690 <span class="comment"> parameters until it returns false or zero, before calling any other method on it or</span> 00691 <span class="comment"> attached BufferedTransformation. The integer return value in this case is approximately</span> 00692 <span class="comment"> the number of bytes left to be processed, and can be used to implement a progress bar.</span> 00693 <span class="comment"></span> 00694 <span class="comment"> For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached</span> 00695 <span class="comment"> BufferedTransformation objects, with propagation decremented at each step until it reaches 0.</span> 00696 <span class="comment"> -1 means unlimited propagation.</span> 00697 <span class="comment"></span> 00698 <span class="comment"> \nosubgrouping</span> 00699 <span class="comment">*/</span> <a name="l00700"></a><a class="code" href="class_buffered_transformation.html">00700</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : <span class="keyword">public</span> Algorithm, <span class="keyword">public</span> Waitable 00701 { 00702 <span class="keyword">public</span>: 00703 <span class="comment">// placed up here for CW8</span> 00704 <span class="keyword">static</span> <span class="keyword">const</span> std::string NULL_CHANNEL; <span class="comment">// the empty string ""</span> 00705 00706 BufferedTransformation() : Algorithm(<span class="keyword">false</span>) {} 00707 <span class="comment"></span> 00708 <span class="comment"> //! return a reference to this object</span> 00709 <span class="comment"></span><span class="comment"> /*! This function is useful for passing a temporary BufferedTransformation object to a </span> 00710 <span class="comment"> function that takes a non-const reference. */</span> <a name="l00711"></a><a class="code" href="class_buffered_transformation.html#_zlib_decompressora16">00711</a> BufferedTransformation& Ref() {<span class="keywordflow">return</span> *<span class="keyword">this</span>;} 00712 <span class="comment"></span> 00713 <span class="comment"> //! \name INPUT</span> 00714 <span class="comment"></span><span class="comment"> //@{</span> 00715 <span class="comment"></span><span class="comment"> //! input a byte for processing</span> <a name="l00716"></a><a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">00716</a> <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Put(byte inByte, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00717 {<span class="keywordflow">return</span> Put(&inByte, 1, blocking);}<span class="comment"></span> 00718 <span class="comment"> //! input multiple bytes</span> <a name="l00719"></a><a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_1">00719</a> <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Put(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00720 {<span class="keywordflow">return</span> Put2(inString, length, 0, blocking);} 00721 <span class="comment"></span> 00722 <span class="comment"> //! input a 16-bit word</span> 00723 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>);<span class="comment"></span> 00724 <span class="comment"> //! input a 32-bit word</span> 00725 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>); 00726 <span class="comment"></span> 00727 <span class="comment"> //! request space which can be written into by the caller, and then used as input to Put()</span> 00728 <span class="comment"></span><span class="comment"> /*! \param size is requested size (as a hint) for input, and size of the returned space for output */</span><span class="comment"></span> 00729 <span class="comment"> /*! \note The purpose of this method is to help avoid doing extra memory allocations. */</span> <a name="l00730"></a><a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_4">00730</a> <span class="keyword">virtual</span> byte * CreatePutSpace(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &size) {size=0; <span class="keywordflow">return</span> NULL;} 00731 00732 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> CanModifyInput()<span class="keyword"> const </span>{<span class="keywordflow">return</span> <span class="keyword">false</span>;} 00733 <span class="comment"></span> 00734 <span class="comment"> //! input multiple bytes that may be modified by callee</span> <a name="l00735"></a><a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_6">00735</a> <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> PutModifiable(byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00736 {<span class="keywordflow">return</span> PutModifiable2(inString, length, 0, blocking);} 00737 00738 <span class="keywordtype">bool</span> MessageEnd(<span class="keywordtype">int</span> propagation=-1, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00739 {<span class="keywordflow">return</span> !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} 00740 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> PutMessageEnd(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> propagation=-1, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00741 {<span class="keywordflow">return</span> Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);} 00742 <span class="comment"></span> 00743 <span class="comment"> //! input multiple bytes for blocking or non-blocking processing</span> 00744 <span class="comment"></span><span class="comment"> /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */</span> 00745 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Put2(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> messageEnd, <span class="keywordtype">bool</span> blocking) =0;<span class="comment"></span> 00746 <span class="comment"> //! input multiple bytes that may be modified by callee for blocking or non-blocking processing</span> 00747 <span class="comment"></span><span class="comment"> /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */</span> <a name="l00748"></a><a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_9">00748</a> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> PutModifiable2(byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> messageEnd, <span class="keywordtype">bool</span> blocking) 00749 {<span class="keywordflow">return</span> Put2(inString, length, messageEnd, blocking);} 00750 <span class="comment"></span> 00751 <span class="comment"> //! thrown by objects that have not implemented nonblocking input processing</span> <a name="l00752"></a><a class="code" href="struct_buffered_transformation_1_1_blocking_input_only.html">00752</a> <span class="comment"></span> <span class="keyword">struct </span><a class="code" href="struct_buffered_transformation_1_1_blocking_input_only.html">BlockingInputOnly</a> : <span class="keyword">public</span> NotImplemented 00753 {<a class="code" href="struct_buffered_transformation_1_1_blocking_input_only.html">BlockingInputOnly</a>(<span class="keyword">const</span> std::string &s) : NotImplemented(s + <span class="stringliteral">": Nonblocking input is not implemented by this object."</span>) {}};<span class="comment"></span> 00754 <span class="comment"> //@}</span> 00755 <span class="comment"></span><span class="comment"></span> 00756 <span class="comment"> //! \name WAITING</span> 00757 <span class="comment"></span><span class="comment"> //@{</span> 00758 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetMaxWaitObjectCount() const; 00759 <span class="keywordtype">void</span> GetWaitObjects(<a class="code" href="class_wait_object_container.html">WaitObjectContainer</a> &container);<span class="comment"></span> 00760 <span class="comment"> //@}</span> 00761 <span class="comment"></span><span class="comment"></span> 00762 <span class="comment"> //! \name SIGNALS</span> 00763 <span class="comment"></span><span class="comment"> //@{</span> 00764 <span class="comment"></span> virtual <span class="keywordtype">void</span> IsolatedInitialize(const NameValuePairs &parameters) {<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"BufferedTransformation: this object can't be reinitialized"</span>);} 00765 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsolatedFlush(<span class="keywordtype">bool</span> hardFlush, <span class="keywordtype">bool</span> blocking) =0; 00766 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsolatedMessageSeriesEnd(<span class="keywordtype">bool</span> blocking) {<span class="keywordflow">return</span> <span class="keyword">false</span>;} 00767 <span class="comment"></span> 00768 <span class="comment"> //! initialize or reinitialize this object</span> 00769 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Initialize(<span class="keyword">const</span> NameValuePairs &parameters=g_nullNameValuePairs, <span class="keywordtype">int</span> propagation=-1);<span class="comment"></span> 00770 <span class="comment"> //! flush buffered input and/or output</span> 00771 <span class="comment"></span><span class="comment"> /*! \param hardFlush is used to indicate whether all data should be flushed</span> 00772 <span class="comment"> \note Hard flushes must be used with care. It means try to process and output everything, even if</span> 00773 <span class="comment"> there may not be enough data to complete the action. For example, hard flushing a HexDecoder would</span> 00774 <span class="comment"> cause an error if you do it after inputing an odd number of hex encoded characters.</span> 00775 <span class="comment"> For some types of filters, for example ZlibDecompressor, hard flushes can only</span> 00776 <span class="comment"> be done at "synchronization points". These synchronization points are positions in the data</span> 00777 <span class="comment"> stream that are created by hard flushes on the corresponding reverse filters, in this</span> 00778 <span class="comment"> example ZlibCompressor. This is useful when zlib compressed data is moved across a</span> 00779 <span class="comment"> network in packets and compression state is preserved across packets, as in the ssh2 protocol.</span> 00780 <span class="comment"> */</span> 00781 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Flush(<span class="keywordtype">bool</span> hardFlush, <span class="keywordtype">int</span> propagation=-1, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>);<span class="comment"></span> 00782 <span class="comment"> //! mark end of a series of messages</span> 00783 <span class="comment"></span><span class="comment"> /*! There should be a MessageEnd immediately before MessageSeriesEnd. */</span> 00784 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> MessageSeriesEnd(<span class="keywordtype">int</span> propagation=-1, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>); 00785 <span class="comment"></span> 00786 <span class="comment"> //! set propagation of automatically generated and transferred signals</span> 00787 <span class="comment"></span><span class="comment"> /*! propagation == 0 means do not automaticly generate signals */</span> <a name="l00788"></a><a class="code" href="class_buffered_transformation.html#_zlib_compressorz5_1">00788</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> SetAutoSignalPropagation(<span class="keywordtype">int</span> propagation) {} 00789 <span class="comment"></span> 00790 <span class="comment"> //!</span> 00791 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">int</span> GetAutoSignalPropagation()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 0;} 00792 <span class="keyword">public</span>: 00793 00794 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 00795 <span class="preprocessor"></span> <span class="keywordtype">void</span> Close() {MessageEnd();} 00796 <span class="preprocessor">#endif</span> 00797 <span class="preprocessor"></span><span class="comment"> //@}</span> 00798 <span class="comment"></span><span class="comment"></span> 00799 <span class="comment"> //! \name RETRIEVAL OF ONE MESSAGE</span> 00800 <span class="comment"></span><span class="comment"> //@{</span> 00801 <span class="comment"></span><span class="comment"> //! returns number of bytes that is currently ready for retrieval</span> 00802 <span class="comment"></span><span class="comment"> /*! All retrieval functions return the actual number of bytes</span> 00803 <span class="comment"> retrieved, which is the lesser of the request number and</span> 00804 <span class="comment"> MaxRetrievable(). */</span> 00805 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> MaxRetrievable() const; 00806 <span class="comment"></span> 00807 <span class="comment"> //! returns whether any bytes are currently ready for retrieval</span> 00808 <span class="comment"></span> virtual <span class="keywordtype">bool</span> AnyRetrievable() const; 00809 <span class="comment"></span> 00810 <span class="comment"> //! try to retrieve a single byte</span> 00811 <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Get(byte &outByte);<span class="comment"></span> 00812 <span class="comment"> //! try to retrieve multiple bytes</span> 00813 <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Get(byte *outString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> getMax); 00814 <span class="comment"></span> 00815 <span class="comment"> //! peek at the next byte without removing it from the output buffer</span> 00816 <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Peek(byte &outByte) const;<span class="comment"></span> 00817 <span class="comment"> //! peek at multiple bytes without removing them from the output buffer</span> 00818 <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Peek(byte *outString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> peekMax) const; 00819 <span class="comment"></span> 00820 <span class="comment"> //! try to retrieve a 16-bit word</span> 00821 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER);<span class="comment"></span> 00822 <span class="comment"> //! try to retrieve a 32-bit word</span> 00823 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); 00824 <span class="comment"></span> 00825 <span class="comment"> //! try to peek at a 16-bit word</span> 00826 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER);<span class="comment"></span> 00827 <span class="comment"> //! try to peek at a 32-bit word</span> 00828 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); 00829 <span class="comment"></span> 00830 <span class="comment"> //! move transferMax bytes of the buffered output to target as input</span> <a name="l00831"></a><a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_10">00831</a> <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> TransferTo(BufferedTransformation &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> transferMax=ULONG_MAX, const std::string &channel=NULL_CHANNEL) 00832 {TransferTo2(target, transferMax, channel); <span class="keywordflow">return</span> transferMax;} 00833 <span class="comment"></span> 00834 <span class="comment"> //! discard skipMax bytes from the output buffer</span> 00835 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> Skip(<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> skipMax=ULONG_MAX); 00836 <span class="comment"></span> 00837 <span class="comment"> //! copy copyMax bytes of the buffered output to target as input</span> <a name="l00838"></a><a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_12">00838</a> <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> CopyTo(BufferedTransformation &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> copyMax=ULONG_MAX, <span class="keyword">const</span> std::string &channel=NULL_CHANNEL)<span class="keyword"> const</span> 00839 <span class="keyword"> </span>{<span class="keywordflow">return</span> CopyRangeTo(target, 0, copyMax, channel);} 00840 <span class="comment"></span> 00841 <span class="comment"> //! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input</span> <a name="l00842"></a><a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_13">00842</a> <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> CopyRangeTo(BufferedTransformation &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> position, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> copyMax=ULONG_MAX, <span class="keyword">const</span> std::string &channel=NULL_CHANNEL)<span class="keyword"> const</span> 00843 <span class="keyword"> </span>{<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> i = position; CopyRangeTo2(target, i, i+copyMax, channel); <span class="keywordflow">return</span> i-position;} 00844 00845 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 00846 <span class="preprocessor"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> MaxRetrieveable()<span class="keyword"> const </span>{<span class="keywordflow">return</span> MaxRetrievable();} 00847 <span class="preprocessor">#endif</span> 00848 <span class="preprocessor"></span><span class="comment"> //@}</span> 00849 <span class="comment"></span><span class="comment"></span> 00850 <span class="comment"> //! \name RETRIEVAL OF MULTIPLE MESSAGES</span> 00851 <span class="comment"></span><span class="comment"> //@{</span> 00852 <span class="comment"></span><span class="comment"> //!</span> 00853 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> TotalBytesRetrievable() const;<span class="comment"></span> 00854 <span class="comment"> //! number of times MessageEnd() has been received minus messages retrieved or skipped</span> 00855 <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> NumberOfMessages() const;<span class="comment"></span> 00856 <span class="comment"> //! returns true if NumberOfMessages() > 0</span> 00857 <span class="comment"></span> virtual <span class="keywordtype">bool</span> AnyMessages() const;<span class="comment"></span> 00858 <span class="comment"> //! start retrieving the next message</span> 00859 <span class="comment"></span><span class="comment"> /*!</span> 00860 <span class="comment"> Returns false if no more messages exist or this message </span> 00861 <span class="comment"> is not completely retrieved.</span> 00862 <span class="comment"> */</span> 00863 virtual <span class="keywordtype">bool</span> GetNextMessage();<span class="comment"></span> 00864 <span class="comment"> //! skip count number of messages</span> 00865 <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SkipMessages(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> count=UINT_MAX);<span class="comment"></span> 00866 <span class="comment"> //!</span> 00867 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> TransferMessagesTo(BufferedTransformation &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> count=UINT_MAX, const std::string &channel=NULL_CHANNEL) 00868 {TransferMessagesTo2(target, count, channel); <span class="keywordflow">return</span> count;}<span class="comment"></span> 00869 <span class="comment"> //!</span> 00870 <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CopyMessagesTo(BufferedTransformation &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> count=UINT_MAX, <span class="keyword">const</span> std::string &channel=NULL_CHANNEL) <span class="keyword">const</span>; 00871 <span class="comment"></span> 00872 <span class="comment"> //!</span> 00873 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> SkipAll();<span class="comment"></span> 00874 <span class="comment"> //!</span> 00875 <span class="comment"></span> <span class="keywordtype">void</span> TransferAllTo(BufferedTransformation &target, <span class="keyword">const</span> std::string &channel=NULL_CHANNEL) 00876 {TransferAllTo2(target, channel);}<span class="comment"></span> 00877 <span class="comment"> //!</span> 00878 <span class="comment"></span> <span class="keywordtype">void</span> CopyAllTo(BufferedTransformation &target, <span class="keyword">const</span> std::string &channel=NULL_CHANNEL) <span class="keyword">const</span>; 00879 00880 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> GetNextMessageSeries() {<span class="keywordflow">return</span> <span class="keyword">false</span>;} 00881 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> NumberOfMessagesInThisSeries()<span class="keyword"> const </span>{<span class="keywordflow">return</span> NumberOfMessages();} 00882 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> NumberOfMessageSeries()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 0;}<span class="comment"></span> 00883 <span class="comment"> //@}</span> 00884 <span class="comment"></span><span class="comment"></span> 00885 <span class="comment"> //! \name NON-BLOCKING TRANSFER OF OUTPUT</span> 00886 <span class="comment"></span><span class="comment"> //@{</span> 00887 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> TransferTo2(BufferedTransformation &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> &byteCount, <span class="keyword">const</span> std::string &channel=NULL_CHANNEL, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) =0; 00888 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CopyRangeTo2(BufferedTransformation &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> &begin, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> end=ULONG_MAX, <span class="keyword">const</span> std::string &channel=NULL_CHANNEL, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) <span class="keyword">const</span> =0; 00889 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> TransferMessagesTo2(BufferedTransformation &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &messageCount, <span class="keyword">const</span> std::string &channel=NULL_CHANNEL, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>); 00890 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> TransferAllTo2(BufferedTransformation &target, <span class="keyword">const</span> std::string &channel=NULL_CHANNEL, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>);<span class="comment"></span> 00891 <span class="comment"> //@}</span> 00892 <span class="comment"></span><span class="comment"></span> 00893 <span class="comment"> //! \name CHANNELS</span> 00894 <span class="comment"></span><span class="comment"> //@{</span> 00895 <span class="comment"></span> <span class="keyword">struct </span>NoChannelSupport : <span class="keyword">public</span> NotImplemented 00896 {NoChannelSupport() : NotImplemented("BufferedTransformation: this object doesn't support multiple channels") {}}; 00897 00898 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelPut(<span class="keyword">const</span> std::string &channel, byte inByte, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00899 {<span class="keywordflow">return</span> ChannelPut(channel, &inByte, 1, blocking);} 00900 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelPut(<span class="keyword">const</span> std::string &channel, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00901 {<span class="keywordflow">return</span> ChannelPut2(channel, inString, length, 0, blocking);} 00902 00903 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelPutModifiable(<span class="keyword">const</span> std::string &channel, byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00904 {<span class="keywordflow">return</span> ChannelPutModifiable2(channel, inString, length, 0, blocking);} 00905 00906 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelPutWord16(<span class="keyword">const</span> std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>); 00907 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelPutWord32(<span class="keyword">const</span> std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>); 00908 00909 <span class="keywordtype">bool</span> ChannelMessageEnd(<span class="keyword">const</span> std::string &channel, <span class="keywordtype">int</span> propagation=-1, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00910 {<span class="keywordflow">return</span> !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} 00911 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelPutMessageEnd(<span class="keyword">const</span> std::string &channel, <span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> propagation=-1, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>) 00912 {<span class="keywordflow">return</span> ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);} 00913 00914 <span class="keyword">virtual</span> byte * ChannelCreatePutSpace(<span class="keyword">const</span> std::string &channel, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &size); 00915 00916 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelPut2(<span class="keyword">const</span> std::string &channel, <span class="keyword">const</span> byte *begin, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> messageEnd, <span class="keywordtype">bool</span> blocking); 00917 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ChannelPutModifiable2(<span class="keyword">const</span> std::string &channel, byte *begin, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length, <span class="keywordtype">int</span> messageEnd, <span class="keywordtype">bool</span> blocking); 00918 00919 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> ChannelFlush(<span class="keyword">const</span> std::string &channel, <span class="keywordtype">bool</span> hardFlush, <span class="keywordtype">int</span> propagation=-1, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>); 00920 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> ChannelMessageSeriesEnd(<span class="keyword">const</span> std::string &channel, <span class="keywordtype">int</span> propagation=-1, <span class="keywordtype">bool</span> blocking=<span class="keyword">true</span>); 00921 00922 <span class="keyword">virtual</span> <span class="keywordtype">void</span> SetRetrievalChannel(<span class="keyword">const</span> std::string &channel);<span class="comment"></span> 00923 <span class="comment"> //@}</span> 00924 <span class="comment"></span><span class="comment"></span> 00925 <span class="comment"> //! \name ATTACHMENT</span> 00926 <span class="comment"></span><span class="comment"> /*! Some BufferedTransformation objects (e.g. Filter objects)</span> 00927 <span class="comment"> allow other BufferedTransformation objects to be attached. When</span> 00928 <span class="comment"> this is done, the first object instead of buffering its output,</span> 00929 <span class="comment"> sents that output to the attached object as input. The entire</span> 00930 <span class="comment"> attachment chain is deleted when the anchor object is destructed.</span> 00931 <span class="comment"> */</span><span class="comment"></span> 00932 <span class="comment"> //@{</span> 00933 <span class="comment"></span><span class="comment"> //! returns whether this object allows attachment</span> <a name="l00934"></a><a class="code" href="class_buffered_transformation.html#_windows_pipe_sinkz15_0">00934</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Attachable() {<span class="keywordflow">return</span> <span class="keyword">false</span>;}<span class="comment"></span> 00935 <span class="comment"> //! returns the object immediately attached to this object or NULL for no attachment</span> <a name="l00936"></a><a class="code" href="class_buffered_transformation.html#_windows_pipe_sinkz15_1">00936</a> <span class="comment"></span> <span class="keyword">virtual</span> BufferedTransformation *AttachedTransformation() {assert(!Attachable()); <span class="keywordflow">return</span> 0;}<span class="comment"></span> 00937 <span class="comment"> //!</span> 00938 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keyword">const</span> BufferedTransformation *AttachedTransformation()<span class="keyword"> const</span> 00939 <span class="keyword"> </span>{<span class="keywordflow">return</span> const_cast<BufferedTransformation *>(<span class="keyword">this</span>)-><a class="code" href="class_buffered_transformation.html#_windows_pipe_sinkz15_1">AttachedTransformation</a>();}<span class="comment"></span> 00940 <span class="comment"> //! delete the current attachment chain and replace it with newAttachment</span> <a name="l00941"></a><a class="code" href="class_buffered_transformation.html#_windows_pipe_sinkz15_3">00941</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Detach(BufferedTransformation *newAttachment = 0) 00942 {assert(!Attachable()); <span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"BufferedTransformation: this object is not attachable"</span>);}<span class="comment"></span> 00943 <span class="comment"> //! add newAttachment to the end of attachment chain</span> 00944 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Attach(BufferedTransformation *newAttachment);<span class="comment"></span> 00945 <span class="comment"> //@}</span> 00946 <span class="comment"></span> 00947 <span class="keyword">protected</span>: 00948 <span class="keyword">static</span> <span class="keywordtype">int</span> DecrementPropagation(<span class="keywordtype">int</span> propagation) 00949 {<span class="keywordflow">return</span> propagation != 0 ? propagation - 1 : 0;} 00950 }; 00951 <span class="comment"></span> 00952 <span class="comment">//! returns a reference to a BufferedTransformation object that discards all input</span> 00953 <span class="comment"></span>BufferedTransformation & TheBitBucket(); 00954 <span class="comment"></span> 00955 <span class="comment">//! interface for crypto material, such as public and private keys, and crypto parameters</span> 00956 <span class="comment"></span> <a name="l00957"></a><a class="code" href="class_crypto_material.html">00957</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoMaterial : <span class="keyword">public</span> NameValuePairs 00958 { 00959 <span class="keyword">public</span>:<span class="comment"></span> 00960 <span class="comment"> //! exception thrown when invalid crypto material is detected</span> <a name="l00961"></a><a class="code" href="class_crypto_material_1_1_invalid_material.html">00961</a> <span class="comment"></span> <span class="keyword">class </span>CRYPTOPP_DLL InvalidMaterial : <span class="keyword">public</span> InvalidDataFormat 00962 { 00963 <span class="keyword">public</span>: 00964 <span class="keyword">explicit</span> InvalidMaterial(<span class="keyword">const</span> std::string &s) : InvalidDataFormat(s) {} 00965 }; 00966 <span class="comment"></span> 00967 <span class="comment"> //! assign values from source to this object</span> 00968 <span class="comment"></span><span class="comment"> /*! \note This function can be used to create a public key from a private key. */</span> 00969 <span class="keyword">virtual</span> <span class="keywordtype">void</span> AssignFrom(<span class="keyword">const</span> NameValuePairs &source) =0; 00970 <span class="comment"></span> 00971 <span class="comment"> //! check this object for errors</span> 00972 <span class="comment"></span><span class="comment"> /*! \param level denotes the level of thoroughness:</span> 00973 <span class="comment"> 0 - using this object won't cause a crash or exception (rng is ignored)</span> 00974 <span class="comment"> 1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such)</span> 00975 <span class="comment"> 2 - make sure this object will function correctly, and do reasonable security checks</span> 00976 <span class="comment"> 3 - do checks that may take a long time</span> 00977 <span class="comment"> \return true if the tests pass */</span> 00978 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Validate(RandomNumberGenerator &rng, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> level) <span class="keyword">const</span> =0; 00979 <span class="comment"></span> 00980 <span class="comment"> //! throws InvalidMaterial if this object fails Validate() test</span> <a name="l00981"></a><a class="code" href="class_crypto_material.html#_x_t_r___d_ha29">00981</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> ThrowIfInvalid(RandomNumberGenerator &rng, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> level)<span class="keyword"> const</span> 00982 <span class="keyword"> </span>{<span class="keywordflow">if</span> (!Validate(rng, level)) <span class="keywordflow">throw</span> InvalidMaterial(<span class="stringliteral">"CryptoMaterial: this object contains invalid values"</span>);} 00983 00984 <span class="comment">// virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false);</span> 00985 <span class="comment"></span> 00986 <span class="comment"> //! save key into a BufferedTransformation</span> <a name="l00987"></a><a class="code" href="class_crypto_material.html#_x_t_r___d_ha30">00987</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Save(BufferedTransformation &bt)<span class="keyword"> const</span> 00988 <span class="keyword"> </span>{<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"CryptoMaterial: this object does not support saving"</span>);} 00989 <span class="comment"></span> 00990 <span class="comment"> //! load key from a BufferedTransformation</span> 00991 <span class="comment"></span><span class="comment"> /*! \throws KeyingErr if decode fails</span> 00992 <span class="comment"> \note Generally does not check that the key is valid.</span> 00993 <span class="comment"> Call ValidateKey() or ThrowIfInvalidKey() to check that. */</span> <a name="l00994"></a><a class="code" href="class_crypto_material.html#_x_t_r___d_ha31">00994</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Load(BufferedTransformation &bt) 00995 {<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"CryptoMaterial: this object does not support loading"</span>);} 00996 <span class="comment"></span> 00997 <span class="comment"> //! \return whether this object supports precomputation</span> <a name="l00998"></a><a class="code" href="class_crypto_material.html#_x_t_r___d_ha32">00998</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> SupportsPrecomputation()<span class="keyword"> const </span>{<span class="keywordflow">return</span> <span class="keyword">false</span>;}<span class="comment"></span> 00999 <span class="comment"> //! do precomputation</span> 01000 <span class="comment"></span><span class="comment"> /*! The exact semantics of Precompute() is varies, but</span> 01001 <span class="comment"> typically it means calculate a table of n objects</span> 01002 <span class="comment"> that can be used later to speed up computation. */</span> <a name="l01003"></a><a class="code" href="class_crypto_material.html#_x_t_r___d_ha33">01003</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> Precompute(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> n) 01004 {assert(!SupportsPrecomputation()); <span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"CryptoMaterial: this object does not support precomputation"</span>);}<span class="comment"></span> 01005 <span class="comment"> //! retrieve previously saved precomputation</span> <a name="l01006"></a><a class="code" href="class_crypto_material.html#_x_t_r___d_ha34">01006</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> LoadPrecomputation(BufferedTransformation &storedPrecomputation) 01007 {assert(!SupportsPrecomputation()); <span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"CryptoMaterial: this object does not support precomputation"</span>);}<span class="comment"></span> 01008 <span class="comment"> //! save precomputation for later use</span> <a name="l01009"></a><a class="code" href="class_crypto_material.html#_x_t_r___d_ha35">01009</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> SavePrecomputation(BufferedTransformation &storedPrecomputation)<span class="keyword"> const</span> 01010 <span class="keyword"> </span>{assert(!SupportsPrecomputation()); <span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"CryptoMaterial: this object does not support precomputation"</span>);} 01011 01012 <span class="comment">// for internal library use</span> 01013 <span class="keywordtype">void</span> DoQuickSanityCheck()<span class="keyword"> const </span>{ThrowIfInvalid(NullRNG(), 0);} 01014 }; 01015 <span class="comment"></span> 01016 <span class="comment">//! interface for generatable crypto material, such as private keys and crypto parameters</span> 01017 <span class="comment"></span> <a name="l01018"></a><a class="code" href="class_generatable_crypto_material.html">01018</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : <span class="keyword">virtual</span> <span class="keyword">public</span> CryptoMaterial 01019 { 01020 <span class="keyword">public</span>:<span class="comment"></span> 01021 <span class="comment"> //! generate a random key or crypto parameters</span> 01022 <span class="comment"></span><span class="comment"> /*! \throws KeyingErr if algorithm parameters are invalid, or if a key can't be generated</span> 01023 <span class="comment"> (e.g., if this is a public key object) */</span> <a name="l01024"></a><a class="code" href="class_generatable_crypto_material.html#_x_t_r___d_ha27">01024</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> GenerateRandom(RandomNumberGenerator &rng, <span class="keyword">const</span> NameValuePairs &params = g_nullNameValuePairs) 01025 {<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"GeneratableCryptoMaterial: this object does not support key/parameter generation"</span>);} 01026 <span class="comment"></span> 01027 <span class="comment"> //! calls the above function with a NameValuePairs object that just specifies "KeySize"</span> 01028 <span class="comment"></span> <span class="keywordtype">void</span> GenerateRandomWithKeySize(RandomNumberGenerator &rng, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> keySize); 01029 }; 01030 <span class="comment"></span> 01031 <span class="comment">//! interface for public keys</span> 01032 <span class="comment"></span> <a name="l01033"></a><a class="code" href="class_public_key.html">01033</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKey : <span class="keyword">virtual</span> <span class="keyword">public</span> CryptoMaterial 01034 { 01035 }; 01036 <span class="comment"></span> 01037 <span class="comment">//! interface for private keys</span> 01038 <span class="comment"></span> <a name="l01039"></a><a class="code" href="class_private_key.html">01039</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKey : <span class="keyword">public</span> GeneratableCryptoMaterial 01040 { 01041 }; 01042 <span class="comment"></span> 01043 <span class="comment">//! interface for crypto prameters</span> 01044 <span class="comment"></span> <a name="l01045"></a><a class="code" href="class_crypto_parameters.html">01045</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoParameters : <span class="keyword">public</span> GeneratableCryptoMaterial 01046 { 01047 }; 01048 <span class="comment"></span> 01049 <span class="comment">//! interface for asymmetric algorithms</span> 01050 <span class="comment"></span> <a name="l01051"></a><a class="code" href="class_asymmetric_algorithm.html">01051</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : <span class="keyword">public</span> Algorithm 01052 { 01053 <span class="keyword">public</span>:<span class="comment"></span> 01054 <span class="comment"> //! returns a reference to the crypto material used by this object</span> 01055 <span class="comment"></span> <span class="keyword">virtual</span> CryptoMaterial & AccessMaterial() =0;<span class="comment"></span> 01056 <span class="comment"> //! returns a const reference to the crypto material used by this object</span> 01057 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keyword">const</span> CryptoMaterial & GetMaterial() <span class="keyword">const</span> =0; 01058 <span class="comment"></span> 01059 <span class="comment"> //! for backwards compatibility, calls AccessMaterial().Load(bt)</span> <a name="l01060"></a><a class="code" href="class_asymmetric_algorithm.html#_x_t_r___d_ha24">01060</a> <span class="comment"></span> <span class="keywordtype">void</span> BERDecode(BufferedTransformation &bt) 01061 {AccessMaterial().<a class="code" href="class_crypto_material.html#_x_t_r___d_ha31">Load</a>(bt);}<span class="comment"></span> 01062 <span class="comment"> //! for backwards compatibility, calls GetMaterial().Save(bt)</span> <a name="l01063"></a><a class="code" href="class_asymmetric_algorithm.html#_two_bases_3_01_t_f___verifier_base_00_01_public_key_copier_3_01_s_c_h_e_m_e___o_p_t_i_o_n_s_1_1_keys_01_4_01_4a21">01063</a> <span class="comment"></span> <span class="keywordtype">void</span> DEREncode(BufferedTransformation &bt)<span class="keyword"> const</span> 01064 <span class="keyword"> </span>{GetMaterial().<a class="code" href="class_crypto_material.html#_x_t_r___d_ha30">Save</a>(bt);} 01065 }; 01066 <span class="comment"></span> 01067 <span class="comment">//! interface for asymmetric algorithms using public keys</span> 01068 <span class="comment"></span> <a name="l01069"></a><a class="code" href="class_public_key_algorithm.html">01069</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : <span class="keyword">public</span> AsymmetricAlgorithm 01070 { 01071 <span class="keyword">public</span>: 01072 <span class="comment">// VC60 workaround: no co-variant return type</span> <a name="l01073"></a><a class="code" href="class_public_key_algorithm.html#_two_bases_3_01_t_f___verifier_base_00_01_public_key_copier_3_01_s_c_h_e_m_e___o_p_t_i_o_n_s_1_1_keys_01_4_01_4a16">01073</a> CryptoMaterial & AccessMaterial() {<span class="keywordflow">return</span> AccessPublicKey();} <a name="l01074"></a><a class="code" href="class_public_key_algorithm.html#_two_bases_3_01_t_f___verifier_base_00_01_public_key_copier_3_01_s_c_h_e_m_e___o_p_t_i_o_n_s_1_1_keys_01_4_01_4a17">01074</a> <span class="keyword">const</span> CryptoMaterial & GetMaterial()<span class="keyword"> const </span>{<span class="keywordflow">return</span> GetPublicKey();} 01075 01076 <span class="keyword">virtual</span> PublicKey & AccessPublicKey() =0; 01077 <span class="keyword">virtual</span> <span class="keyword">const</span> PublicKey & GetPublicKey()<span class="keyword"> const </span>{<span class="keywordflow">return</span> const_cast<PublicKeyAlgorithm *>(<span class="keyword">this</span>)->AccessPublicKey();} 01078 }; 01079 <span class="comment"></span> 01080 <span class="comment">//! interface for asymmetric algorithms using private keys</span> 01081 <span class="comment"></span> <a name="l01082"></a><a class="code" href="class_private_key_algorithm.html">01082</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : <span class="keyword">public</span> AsymmetricAlgorithm 01083 { 01084 <span class="keyword">public</span>: <a name="l01085"></a><a class="code" href="class_private_key_algorithm.html#_two_bases_3_01_t_f___signer_base_00_01_private_key_copier_3_01_s_c_h_e_m_e___o_p_t_i_o_n_s_1_1_keys_01_4_01_4a14">01085</a> CryptoMaterial & AccessMaterial() {<span class="keywordflow">return</span> AccessPrivateKey();} <a name="l01086"></a><a class="code" href="class_private_key_algorithm.html#_two_bases_3_01_t_f___signer_base_00_01_private_key_copier_3_01_s_c_h_e_m_e___o_p_t_i_o_n_s_1_1_keys_01_4_01_4a15">01086</a> <span class="keyword">const</span> CryptoMaterial & GetMaterial()<span class="keyword"> const </span>{<span class="keywordflow">return</span> GetPrivateKey();} 01087 01088 <span class="keyword">virtual</span> PrivateKey & AccessPrivateKey() =0; 01089 <span class="keyword">virtual</span> <span class="keyword">const</span> PrivateKey & GetPrivateKey()<span class="keyword"> const </span>{<span class="keywordflow">return</span> const_cast<PrivateKeyAlgorithm *>(<span class="keyword">this</span>)->AccessPrivateKey();} 01090 }; 01091 <span class="comment"></span> 01092 <span class="comment">//! interface for key agreement algorithms</span> 01093 <span class="comment"></span> <a name="l01094"></a><a class="code" href="class_key_agreement_algorithm.html">01094</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE KeyAgreementAlgorithm : <span class="keyword">public</span> AsymmetricAlgorithm 01095 { 01096 <span class="keyword">public</span>: <a name="l01097"></a><a class="code" href="class_key_agreement_algorithm.html#_x_t_r___d_ha21">01097</a> CryptoMaterial & AccessMaterial() {<span class="keywordflow">return</span> AccessCryptoParameters();} <a name="l01098"></a><a class="code" href="class_key_agreement_algorithm.html#_x_t_r___d_ha22">01098</a> <span class="keyword">const</span> CryptoMaterial & GetMaterial()<span class="keyword"> const </span>{<span class="keywordflow">return</span> GetCryptoParameters();} 01099 01100 <span class="keyword">virtual</span> CryptoParameters & AccessCryptoParameters() =0; 01101 <span class="keyword">virtual</span> <span class="keyword">const</span> CryptoParameters & GetCryptoParameters()<span class="keyword"> const </span>{<span class="keywordflow">return</span> const_cast<KeyAgreementAlgorithm *>(<span class="keyword">this</span>)->AccessCryptoParameters();} 01102 }; 01103 <span class="comment"></span> 01104 <span class="comment">//! interface for public-key encryptors and decryptors</span> 01105 <span class="comment"></span><span class="comment"></span> 01106 <span class="comment">/*! This class provides an interface common to encryptors and decryptors</span> 01107 <span class="comment"> for querying their plaintext and ciphertext lengths.</span> 01108 <span class="comment">*/</span> <a name="l01109"></a><a class="code" href="class_p_k___crypto_system.html">01109</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_CryptoSystem 01110 { 01111 <span class="keyword">public</span>: 01112 <span class="keyword">virtual</span> ~PK_CryptoSystem() {} 01113 <span class="comment"></span> 01114 <span class="comment"> //! maximum length of plaintext for a given ciphertext length</span> 01115 <span class="comment"></span><span class="comment"> /*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */</span> 01116 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MaxPlaintextLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ciphertextLength) <span class="keyword">const</span> =0; 01117 <span class="comment"></span> 01118 <span class="comment"> //! calculate length of ciphertext given length of plaintext</span> 01119 <span class="comment"></span><span class="comment"> /*! \note This function returns 0 if plaintextLength is not valid (too long). */</span> 01120 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CiphertextLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> plaintextLength) <span class="keyword">const</span> =0; 01121 <span class="comment"></span> 01122 <span class="comment"> //! this object supports the use of the parameter with the given name</span> 01123 <span class="comment"></span><span class="comment"> /*! some possible parameter names: EncodingParameters, KeyDerivationParameters */</span> 01124 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> ParameterSupported(<span class="keyword">const</span> <span class="keywordtype">char</span> *name) <span class="keyword">const</span> =0; 01125 <span class="comment"></span> 01126 <span class="comment"> //! return fixed ciphertext length, if one exists, otherwise return 0</span> 01127 <span class="comment"></span><span class="comment"> /*! \note "Fixed" here means length of ciphertext does not depend on length of plaintext.</span> 01128 <span class="comment"> It usually does depend on the key length. */</span> <a name="l01129"></a><a class="code" href="class_p_k___crypto_system.html#_p_k___encryptora5">01129</a> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> FixedCiphertextLength()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 0;} 01130 <span class="comment"></span> 01131 <span class="comment"> //! return maximum plaintext length given the fixed ciphertext length, if one exists, otherwise return 0</span> <a name="l01132"></a><a class="code" href="class_p_k___crypto_system.html#_p_k___encryptora6">01132</a> <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> FixedMaxPlaintextLength()<span class="keyword"> const </span>{<span class="keywordflow">return</span> 0;} 01133 01134 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 01135 <span class="preprocessor"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MaxPlainTextLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> cipherTextLength)<span class="keyword"> const </span>{<span class="keywordflow">return</span> MaxPlaintextLength(cipherTextLength);} 01136 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> CipherTextLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> plainTextLength)<span class="keyword"> const </span>{<span class="keywordflow">return</span> CiphertextLength(plainTextLength);} 01137 <span class="preprocessor">#endif</span> 01138 <span class="preprocessor"></span>}; 01139 <span class="comment"></span> 01140 <span class="comment">//! interface for public-key encryptors</span> <a name="l01141"></a><a class="code" href="class_p_k___encryptor.html">01141</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : <span class="keyword">virtual</span> <span class="keyword">public</span> PK_CryptoSystem, <span class="keyword">public</span> PublicKeyAlgorithm 01142 { 01143 <span class="keyword">public</span>:<span class="comment"></span> 01144 <span class="comment"> //! exception thrown when trying to encrypt plaintext of invalid length</span> <a name="l01145"></a><a class="code" href="class_p_k___encryptor_1_1_invalid_plaintext_length.html">01145</a> <span class="comment"></span> <span class="keyword">class </span>CRYPTOPP_DLL InvalidPlaintextLength : <span class="keyword">public</span> Exception 01146 { 01147 <span class="keyword">public</span>: 01148 InvalidPlaintextLength() : Exception(OTHER_ERROR, <span class="stringliteral">"PK_Encryptor: invalid plaintext length"</span>) {} 01149 }; 01150 <span class="comment"></span> 01151 <span class="comment"> //! encrypt a byte string</span> 01152 <span class="comment"></span><span class="comment"> /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long)</span> 01153 <span class="comment"> \pre size of ciphertext == CiphertextLength(plaintextLength)</span> 01154 <span class="comment"> */</span> 01155 <span class="keyword">virtual</span> <span class="keywordtype">void</span> Encrypt(RandomNumberGenerator &rng, 01156 <span class="keyword">const</span> byte *plaintext, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> plaintextLength, 01157 byte *ciphertext, <span class="keyword">const</span> NameValuePairs &parameters = g_nullNameValuePairs) <span class="keyword">const</span> =0; 01158 <span class="comment"></span> 01159 <span class="comment"> //! create a new encryption filter</span> 01160 <span class="comment"></span><span class="comment"> /*! \note The caller is responsible for deleting the returned pointer.</span> 01161 <span class="comment"> \note Encoding parameters should be passed in the "EP" channel.</span> 01162 <span class="comment"> */</span> 01163 <span class="keyword">virtual</span> BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, 01164 BufferedTransformation *attachment=NULL, <span class="keyword">const</span> NameValuePairs &parameters = g_nullNameValuePairs) <span class="keyword">const</span>; 01165 }; 01166 <span class="comment"></span> 01167 <span class="comment">//! interface for public-key decryptors</span> 01168 <span class="comment"></span> <a name="l01169"></a><a class="code" href="class_p_k___decryptor.html">01169</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : <span class="keyword">virtual</span> <span class="keyword">public</span> PK_CryptoSystem, <span class="keyword">public</span> PrivateKeyAlgorithm 01170 { 01171 <span class="keyword">public</span>:<span class="comment"></span> 01172 <span class="comment"> //! decrypt a byte string, and return the length of plaintext</span> 01173 <span class="comment"></span><span class="comment"> /*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes.</span> 01174 <span class="comment"> \return the actual length of the plaintext, indication that decryption failed.</span> 01175 <span class="comment"> */</span> 01176 <span class="keyword">virtual</span> DecodingResult Decrypt(RandomNumberGenerator &rng, 01177 <span class="keyword">const</span> byte *ciphertext, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> ciphertextLength, 01178 byte *plaintext, <span class="keyword">const</span> NameValuePairs &parameters = g_nullNameValuePairs) <span class="keyword">const</span> =0; 01179 <span class="comment"></span> 01180 <span class="comment"> //! create a new decryption filter</span> 01181 <span class="comment"></span><span class="comment"> /*! \note caller is responsible for deleting the returned pointer</span> 01182 <span class="comment"> */</span> 01183 <span class="keyword">virtual</span> BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, 01184 BufferedTransformation *attachment=NULL, <span class="keyword">const</span> NameValuePairs &parameters = g_nullNameValuePairs) <span class="keyword">const</span>; 01185 <span class="comment"></span> 01186 <span class="comment"> //! decrypt a fixed size ciphertext</span> <a name="l01187"></a><a class="code" href="class_p_k___decryptor.html#_two_bases_3_01_t_f___decryptor_base_00_01_private_key_copier_3_01_s_c_h_e_m_e___o_p_t_i_o_n_s_1_1_keys_01_4_01_4a7">01187</a> <span class="comment"></span> DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, <span class="keyword">const</span> byte *ciphertext, byte *plaintext, <span class="keyword">const</span> NameValuePairs &parameters = g_nullNameValuePairs)<span class="keyword"> const</span> 01188 <span class="keyword"> </span>{<span class="keywordflow">return</span> Decrypt(rng, ciphertext, FixedCiphertextLength(), plaintext, parameters);} 01189 }; 01190 01191 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 01192 <span class="preprocessor"></span><span class="keyword">typedef</span> PK_CryptoSystem PK_FixedLengthCryptoSystem; 01193 <span class="keyword">typedef</span> PK_Encryptor PK_FixedLengthEncryptor; 01194 <span class="keyword">typedef</span> PK_Decryptor PK_FixedLengthDecryptor; 01195 <span class="preprocessor">#endif</span> 01196 <span class="preprocessor"></span><span class="comment"></span> 01197 <span class="comment">//! interface for public-key signers and verifiers</span> 01198 <span class="comment"></span><span class="comment"></span> 01199 <span class="comment">/*! This class provides an interface common to signers and verifiers</span> 01200 <span class="comment"> for querying scheme properties.</span> 01201 <span class="comment">*/</span> <a name="l01202"></a><a class="code" href="class_p_k___signature_scheme.html">01202</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme 01203 { 01204 <span class="keyword">public</span>:<span class="comment"></span> 01205 <span class="comment"> //! invalid key exception, may be thrown by any function in this class if the private or public key has a length that can't be used</span> <a name="l01206"></a><a class="code" href="class_p_k___signature_scheme_1_1_invalid_key_length.html">01206</a> <span class="comment"></span> <span class="keyword">class </span>CRYPTOPP_DLL InvalidKeyLength : <span class="keyword">public</span> Exception 01207 { 01208 <span class="keyword">public</span>: 01209 InvalidKeyLength(<span class="keyword">const</span> std::string &message) : Exception(OTHER_ERROR, message) {} 01210 }; 01211 <span class="comment"></span> 01212 <span class="comment"> //! key too short exception, may be thrown by any function in this class if the private or public key is too short to sign or verify anything</span> <a name="l01213"></a><a class="code" href="class_p_k___signature_scheme_1_1_key_too_short.html">01213</a> <span class="comment"></span> <span class="keyword">class </span>CRYPTOPP_DLL KeyTooShort : <span class="keyword">public</span> InvalidKeyLength 01214 { 01215 <span class="keyword">public</span>: 01216 KeyTooShort() : InvalidKeyLength(<span class="stringliteral">"PK_Signer: key too short for this signature scheme"</span>) {} 01217 }; 01218 01219 <span class="keyword">virtual</span> ~PK_SignatureScheme() {} 01220 <span class="comment"></span> 01221 <span class="comment"> //! signature length if it only depends on the key, otherwise 0</span> 01222 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SignatureLength() const =0; 01223 <span class="comment"></span> 01224 <span class="comment"> //! maximum signature length produced for a given length of recoverable message part</span> <a name="l01225"></a><a class="code" href="class_p_k___signature_scheme.html#_two_bases_3_01_t_f___verifier_base_00_01_public_key_copier_3_01_s_c_h_e_m_e___o_p_t_i_o_n_s_1_1_keys_01_4_01_4a14">01225</a> <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MaxSignatureLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> recoverablePartLength = 0)<span class="keyword"> const </span>{<span class="keywordflow">return</span> SignatureLength();} 01226 <span class="comment"></span> 01227 <span class="comment"> //! length of longest message that can be recovered, or 0 if this signature scheme does not support message recovery</span> 01228 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MaxRecoverableLength() const =0; 01229 <span class="comment"></span> 01230 <span class="comment"> //! length of longest message that can be recovered from a signature of given length, or 0 if this signature scheme does not support message recovery</span> 01231 <span class="comment"></span> virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> MaxRecoverableLengthFromSignatureLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> signatureLength) const =0; 01232 <span class="comment"></span> 01233 <span class="comment"> //! requires a random number generator to sign</span> 01234 <span class="comment"></span><span class="comment"> /*! if this returns false, NullRNG() can be passed to functions that take RandomNumberGenerator & */</span> 01235 virtual <span class="keywordtype">bool</span> IsProbabilistic() const =0; 01236 <span class="comment"></span> 01237 <span class="comment"> //! whether or not a non-recoverable message part can be signed</span> 01238 <span class="comment"></span> virtual <span class="keywordtype">bool</span> AllowNonrecoverablePart() const =0; 01239 <span class="comment"></span> 01240 <span class="comment"> //! if this function returns true, during verification you must input the signature before the message, otherwise you can input it at anytime */</span> <a name="l01241"></a><a class="code" href="class_p_k___signature_scheme.html#_two_bases_3_01_t_f___verifier_base_00_01_public_key_copier_3_01_s_c_h_e_m_e___o_p_t_i_o_n_s_1_1_keys_01_4_01_4a15">01241</a> <span class="comment"></span> virtual <span class="keywordtype">bool</span> SignatureUpfront()<span class="keyword"> const </span>{<span class="keywordflow">return</span> <span class="keyword">false</span>;} 01242 <span class="comment"></span> 01243 <span class="comment"> //! whether you must input the recoverable part before the non-recoverable part during signing</span> 01244 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> RecoverablePartFirst() const =0; 01245 }; 01246 <span class="comment"></span> 01247 <span class="comment">//! interface for accumulating messages to be signed or verified</span> 01248 <span class="comment"></span><span class="comment">/*! Only Update() should be called</span> 01249 <span class="comment"> on this class. No other functions inherited from HashTransformation should be called.</span> 01250 <span class="comment">*/</span> <a name="l01251"></a><a class="code" href="class_p_k___message_accumulator.html">01251</a> class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE <a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> : public <a class="code" href="class_hash_transformation.html">HashTransformation</a> 01252 { 01253 <span class="keyword">public</span>:<span class="comment"></span> 01254 <span class="comment"> //! should not be called on PK_MessageAccumulator</span> <a name="l01255"></a><a class="code" href="class_p_k___message_accumulator.html#_p_k___message_accumulator_basea3">01255</a> <span class="comment"></span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> DigestSize()<span class="keyword"> const</span> 01256 <span class="keyword"> </span>{<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"PK_MessageAccumulator: DigestSize() should not be called"</span>);}<span class="comment"></span> 01257 <span class="comment"> //! should not be called on PK_MessageAccumulator</span> <a name="l01258"></a><a class="code" href="class_p_k___message_accumulator.html#_p_k___message_accumulator_basea4">01258</a> <span class="comment"></span> <span class="keywordtype">void</span> TruncatedFinal(byte *digest, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> digestSize) 01259 {<span class="keywordflow">throw</span> NotImplemented(<span class="stringliteral">"PK_MessageAccumulator: TruncatedFinal() should not be called"</span>);} 01260 }; 01261 <span class="comment"></span> 01262 <span class="comment">//! interface for public-key signers</span> 01263 <span class="comment"></span> <a name="l01264"></a><a class="code" href="class_p_k___signer.html">01264</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Signer : <span class="keyword">public</span> PK_SignatureScheme, <span class="keyword">public</span> PrivateKeyAlgorithm 01265 { 01266 <span class="keyword">public</span>:<span class="comment"></span> 01267 <span class="comment"> //! create a new HashTransformation to accumulate the message to be signed</span> 01268 <span class="comment"></span> <span class="keyword">virtual</span> <a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> * NewSignatureAccumulator(RandomNumberGenerator &rng) <span class="keyword">const</span> =0; 01269 01270 <span class="keyword">virtual</span> <span class="keywordtype">void</span> InputRecoverableMessage(<a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> &messageAccumulator, <span class="keyword">const</span> byte *recoverableMessage, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> recoverableMessageLength) <span class="keyword">const</span> =0; 01271 <span class="comment"></span> 01272 <span class="comment"> //! sign and delete messageAccumulator (even in case of exception thrown)</span> 01273 <span class="comment"></span><span class="comment"> /*! \pre size of signature == MaxSignatureLength()</span> 01274 <span class="comment"> \return actual signature length</span> 01275 <span class="comment"> */</span> 01276 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> Sign(RandomNumberGenerator &rng, <a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> *messageAccumulator, byte *signature) <span class="keyword">const</span>; 01277 <span class="comment"></span> 01278 <span class="comment"> //! sign and restart messageAccumulator</span> 01279 <span class="comment"></span><span class="comment"> /*! \pre size of signature == MaxSignatureLength()</span> 01280 <span class="comment"> \return actual signature length</span> 01281 <span class="comment"> */</span> 01282 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SignAndRestart(RandomNumberGenerator &rng, <a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> &messageAccumulator, byte *signature, <span class="keywordtype">bool</span> restart=<span class="keyword">true</span>) <span class="keyword">const</span> =0; 01283 <span class="comment"></span> 01284 <span class="comment"> //! sign a message</span> 01285 <span class="comment"></span><span class="comment"> /*! \pre size of signature == MaxSignatureLength()</span> 01286 <span class="comment"> \return actual signature length</span> 01287 <span class="comment"> */</span> 01288 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SignMessage(RandomNumberGenerator &rng, <span class="keyword">const</span> byte *message, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> messageLen, byte *signature) <span class="keyword">const</span>; 01289 <span class="comment"></span> 01290 <span class="comment"> //! sign a recoverable message</span> 01291 <span class="comment"></span><span class="comment"> /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength)</span> 01292 <span class="comment"> \return actual signature length</span> 01293 <span class="comment"> */</span> 01294 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> SignMessageWithRecovery(RandomNumberGenerator &rng, <span class="keyword">const</span> byte *recoverableMessage, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> recoverableMessageLength, 01295 <span class="keyword">const</span> byte *nonrecoverableMessage, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nonrecoverableMessageLength, byte *signature) <span class="keyword">const</span>; 01296 }; 01297 <span class="comment"></span> 01298 <span class="comment">//! interface for public-key signature verifiers</span> 01299 <span class="comment"></span><span class="comment">/*! The Recover* functions throw NotImplemented if the signature scheme does not support</span> 01300 <span class="comment"> message recovery.</span> 01301 <span class="comment"> The Verify* functions throw InvalidDataFormat if the scheme does support message</span> 01302 <span class="comment"> recovery and the signature contains a non-empty recoverable message part. The</span> 01303 <span class="comment"> Recovery* functions should be used in that case.</span> 01304 <span class="comment">*/</span> <a name="l01305"></a><a class="code" href="class_p_k___verifier.html">01305</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Verifier : <span class="keyword">public</span> PK_SignatureScheme, <span class="keyword">public</span> PublicKeyAlgorithm 01306 { 01307 <span class="keyword">public</span>:<span class="comment"></span> 01308 <span class="comment"> //! create a new HashTransformation to accumulate the message to be verified</span> 01309 <span class="comment"></span> <span class="keyword">virtual</span> <a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> * NewVerificationAccumulator() <span class="keyword">const</span> =0; 01310 <span class="comment"></span> 01311 <span class="comment"> //! input signature into a message accumulator</span> 01312 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> InputSignature(<a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> &messageAccumulator, <span class="keyword">const</span> byte *signature, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> signatureLength) <span class="keyword">const</span> =0; 01313 <span class="comment"></span> 01314 <span class="comment"> //! check whether messageAccumulator contains a valid signature and message, and delete messageAccumulator (even in case of exception thrown)</span> 01315 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Verify(<a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> *messageAccumulator) <span class="keyword">const</span>; 01316 <span class="comment"></span> 01317 <span class="comment"> //! check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator</span> 01318 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> VerifyAndRestart(<a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> &messageAccumulator) <span class="keyword">const</span> =0; 01319 <span class="comment"></span> 01320 <span class="comment"> //! check whether input signature is a valid signature for input message</span> 01321 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> VerifyMessage(<span class="keyword">const</span> byte *message, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> messageLen, 01322 <span class="keyword">const</span> byte *signature, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> signatureLength) <span class="keyword">const</span>; 01323 <span class="comment"></span> 01324 <span class="comment"> //! recover a message from its signature</span> 01325 <span class="comment"></span><span class="comment"> /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)</span> 01326 <span class="comment"> */</span> 01327 <span class="keyword">virtual</span> DecodingResult Recover(byte *recoveredMessage, <a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> *messageAccumulator) <span class="keyword">const</span>; 01328 <span class="comment"></span> 01329 <span class="comment"> //! recover a message from its signature</span> 01330 <span class="comment"></span><span class="comment"> /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)</span> 01331 <span class="comment"> */</span> 01332 <span class="keyword">virtual</span> DecodingResult RecoverAndRestart(byte *recoveredMessage, <a class="code" href="class_p_k___message_accumulator.html">PK_MessageAccumulator</a> &messageAccumulator) <span class="keyword">const</span> =0; 01333 <span class="comment"></span> 01334 <span class="comment"> //! recover a message from its signature</span> 01335 <span class="comment"></span><span class="comment"> /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength)</span> 01336 <span class="comment"> */</span> 01337 <span class="keyword">virtual</span> DecodingResult RecoverMessage(byte *recoveredMessage, 01338 <span class="keyword">const</span> byte *nonrecoverableMessage, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nonrecoverableMessageLength, 01339 <span class="keyword">const</span> byte *signature, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> signatureLength) <span class="keyword">const</span>; 01340 }; 01341 <span class="comment"></span> 01342 <span class="comment">//! interface for domains of simple key agreement protocols</span> 01343 <span class="comment"></span><span class="comment"></span> 01344 <span class="comment">/*! A key agreement domain is a set of parameters that must be shared</span> 01345 <span class="comment"> by two parties in a key agreement protocol, along with the algorithms</span> 01346 <span class="comment"> for generating key pairs and deriving agreed values.</span> 01347 <span class="comment">*/</span> <a name="l01348"></a><a class="code" href="class_simple_key_agreement_domain.html">01348</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyAgreementDomain : <span class="keyword">public</span> KeyAgreementAlgorithm 01349 { 01350 <span class="keyword">public</span>:<span class="comment"></span> 01351 <span class="comment"> //! return length of agreed value produced</span> 01352 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> AgreedValueLength() <span class="keyword">const</span> =0;<span class="comment"></span> 01353 <span class="comment"> //! return length of private keys in this domain</span> 01354 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> PrivateKeyLength() <span class="keyword">const</span> =0;<span class="comment"></span> 01355 <span class="comment"> //! return length of public keys in this domain</span> 01356 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> PublicKeyLength() <span class="keyword">const</span> =0;<span class="comment"></span> 01357 <span class="comment"> //! generate private key</span> 01358 <span class="comment"></span><span class="comment"> /*! \pre size of privateKey == PrivateKeyLength() */</span> 01359 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) <span class="keyword">const</span> =0;<span class="comment"></span> 01360 <span class="comment"> //! generate public key</span> 01361 <span class="comment"></span><span class="comment"> /*! \pre size of publicKey == PublicKeyLength() */</span> 01362 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GeneratePublicKey(RandomNumberGenerator &rng, <span class="keyword">const</span> byte *privateKey, byte *publicKey) <span class="keyword">const</span> =0;<span class="comment"></span> 01363 <span class="comment"> //! generate private/public key pair</span> 01364 <span class="comment"></span><span class="comment"> /*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */</span> 01365 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) <span class="keyword">const</span>;<span class="comment"></span> 01366 <span class="comment"> //! derive agreed value from your private key and couterparty's public key, return false in case of failure</span> 01367 <span class="comment"></span><span class="comment"> /*! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time.</span> 01368 <span class="comment"> \pre size of agreedValue == AgreedValueLength()</span> 01369 <span class="comment"> \pre length of privateKey == PrivateKeyLength()</span> 01370 <span class="comment"> \pre length of otherPublicKey == PublicKeyLength()</span> 01371 <span class="comment"> */</span> 01372 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Agree(byte *agreedValue, <span class="keyword">const</span> byte *privateKey, <span class="keyword">const</span> byte *otherPublicKey, <span class="keywordtype">bool</span> validateOtherPublicKey=<span class="keyword">true</span>) <span class="keyword">const</span> =0; 01373 01374 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 01375 <span class="preprocessor"></span> <span class="keywordtype">bool</span> ValidateDomainParameters(RandomNumberGenerator &rng)<span class="keyword"> const</span> 01376 <span class="keyword"> </span>{<span class="keywordflow">return</span> GetCryptoParameters().Validate(rng, 2);} 01377 <span class="preprocessor">#endif</span> 01378 <span class="preprocessor"></span>}; 01379 <span class="comment"></span> 01380 <span class="comment">//! interface for domains of authenticated key agreement protocols</span> 01381 <span class="comment"></span><span class="comment"></span> 01382 <span class="comment">/*! In an authenticated key agreement protocol, each party has two</span> 01383 <span class="comment"> key pairs. The long-lived key pair is called the static key pair,</span> 01384 <span class="comment"> and the short-lived key pair is called the ephemeral key pair.</span> 01385 <span class="comment">*/</span> <a name="l01386"></a><a class="code" href="class_authenticated_key_agreement_domain.html">01386</a> <span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedKeyAgreementDomain : <span class="keyword">public</span> KeyAgreementAlgorithm 01387 { 01388 <span class="keyword">public</span>:<span class="comment"></span> 01389 <span class="comment"> //! return length of agreed value produced</span> 01390 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> AgreedValueLength() <span class="keyword">const</span> =0; 01391 <span class="comment"></span> 01392 <span class="comment"> //! return length of static private keys in this domain</span> 01393 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> StaticPrivateKeyLength() <span class="keyword">const</span> =0;<span class="comment"></span> 01394 <span class="comment"> //! return length of static public keys in this domain</span> 01395 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> StaticPublicKeyLength() <span class="keyword">const</span> =0;<span class="comment"></span> 01396 <span class="comment"> //! generate static private key</span> 01397 <span class="comment"></span><span class="comment"> /*! \pre size of privateKey == PrivateStaticKeyLength() */</span> 01398 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) <span class="keyword">const</span> =0;<span class="comment"></span> 01399 <span class="comment"> //! generate static public key</span> 01400 <span class="comment"></span><span class="comment"> /*! \pre size of publicKey == PublicStaticKeyLength() */</span> 01401 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GenerateStaticPublicKey(RandomNumberGenerator &rng, <span class="keyword">const</span> byte *privateKey, byte *publicKey) <span class="keyword">const</span> =0;<span class="comment"></span> 01402 <span class="comment"> //! generate private/public key pair</span> 01403 <span class="comment"></span><span class="comment"> /*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */</span> 01404 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) <span class="keyword">const</span>; 01405 <span class="comment"></span> 01406 <span class="comment"> //! return length of ephemeral private keys in this domain</span> 01407 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> EphemeralPrivateKeyLength() <span class="keyword">const</span> =0;<span class="comment"></span> 01408 <span class="comment"> //! return length of ephemeral public keys in this domain</span> 01409 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> EphemeralPublicKeyLength() <span class="keyword">const</span> =0;<span class="comment"></span> 01410 <span class="comment"> //! generate ephemeral private key</span> 01411 <span class="comment"></span><span class="comment"> /*! \pre size of privateKey == PrivateEphemeralKeyLength() */</span> 01412 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) <span class="keyword">const</span> =0;<span class="comment"></span> 01413 <span class="comment"> //! generate ephemeral public key</span> 01414 <span class="comment"></span><span class="comment"> /*! \pre size of publicKey == PublicEphemeralKeyLength() */</span> 01415 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GenerateEphemeralPublicKey(RandomNumberGenerator &rng, <span class="keyword">const</span> byte *privateKey, byte *publicKey) <span class="keyword">const</span> =0;<span class="comment"></span> 01416 <span class="comment"> //! generate private/public key pair</span> 01417 <span class="comment"></span><span class="comment"> /*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */</span> 01418 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) <span class="keyword">const</span>; 01419 <span class="comment"></span> 01420 <span class="comment"> //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure</span> 01421 <span class="comment"></span><span class="comment"> /*! \note The ephemeral public key will always be validated.</span> 01422 <span class="comment"> If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.</span> 01423 <span class="comment"> \pre size of agreedValue == AgreedValueLength()</span> 01424 <span class="comment"> \pre length of staticPrivateKey == StaticPrivateKeyLength()</span> 01425 <span class="comment"> \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()</span> 01426 <span class="comment"> \pre length of staticOtherPublicKey == StaticPublicKeyLength()</span> 01427 <span class="comment"> \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()</span> 01428 <span class="comment"> */</span> 01429 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> Agree(byte *agreedValue, 01430 <span class="keyword">const</span> byte *staticPrivateKey, <span class="keyword">const</span> byte *ephemeralPrivateKey, 01431 <span class="keyword">const</span> byte *staticOtherPublicKey, <span class="keyword">const</span> byte *ephemeralOtherPublicKey, 01432 <span class="keywordtype">bool</span> validateStaticOtherPublicKey=<span class="keyword">true</span>) <span class="keyword">const</span> =0; 01433 01434 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 01435 <span class="preprocessor"></span> <span class="keywordtype">bool</span> ValidateDomainParameters(RandomNumberGenerator &rng)<span class="keyword"> const</span> 01436 <span class="keyword"> </span>{<span class="keywordflow">return</span> GetCryptoParameters().Validate(rng, 2);} 01437 <span class="preprocessor">#endif</span> 01438 <span class="preprocessor"></span>}; 01439 01440 <span class="comment">// interface for password authenticated key agreement protocols, not implemented yet</span> 01441 <span class="preprocessor">#if 0</span> 01442 <span class="preprocessor"></span><span class="comment">//! interface for protocol sessions</span> 01443 <span class="comment"></span><span class="comment">/*! The methods should be called in the following order:</span> 01444 <span class="comment"></span> 01445 <span class="comment"> InitializeSession(rng, parameters); // or call initialize method in derived class</span> 01446 <span class="comment"> while (true)</span> 01447 <span class="comment"> {</span> 01448 <span class="comment"> if (OutgoingMessageAvailable())</span> 01449 <span class="comment"> {</span> 01450 <span class="comment"> length = GetOutgoingMessageLength();</span> 01451 <span class="comment"> GetOutgoingMessage(message);</span> 01452 <span class="comment"> ; // send outgoing message</span> 01453 <span class="comment"> }</span> 01454 <span class="comment"></span> 01455 <span class="comment"> if (LastMessageProcessed())</span> 01456 <span class="comment"> break;</span> 01457 <span class="comment"></span> 01458 <span class="comment"> ; // receive incoming message</span> 01459 <span class="comment"> ProcessIncomingMessage(message);</span> 01460 <span class="comment"> }</span> 01461 <span class="comment"> ; // call methods in derived class to obtain result of protocol session</span> 01462 <span class="comment">*/</span> 01463 <span class="keyword">class </span>ProtocolSession 01464 { 01465 <span class="keyword">public</span>:<span class="comment"></span> 01466 <span class="comment"> //! exception thrown when an invalid protocol message is processed</span> 01467 <span class="comment"></span> <span class="keyword">class </span>ProtocolError : <span class="keyword">public</span> Exception 01468 { 01469 <span class="keyword">public</span>: 01470 ProtocolError(ErrorType errorType, <span class="keyword">const</span> std::string &s) : Exception(errorType, s) {} 01471 }; 01472 <span class="comment"></span> 01473 <span class="comment"> //! exception thrown when a function is called unexpectedly</span> 01474 <span class="comment"></span><span class="comment"> /*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */</span> 01475 <span class="keyword">class </span>UnexpectedMethodCall : <span class="keyword">public</span> Exception 01476 { 01477 <span class="keyword">public</span>: 01478 UnexpectedMethodCall(<span class="keyword">const</span> std::string &s) : Exception(OTHER_ERROR, s) {} 01479 }; 01480 01481 ProtocolSession() : m_rng(NULL), m_throwOnProtocolError(true), m_validState(false) {} 01482 <span class="keyword">virtual</span> ~ProtocolSession() {} 01483 01484 <span class="keyword">virtual</span> <span class="keywordtype">void</span> InitializeSession(RandomNumberGenerator &rng, <span class="keyword">const</span> NameValuePairs &parameters) =0; 01485 01486 <span class="keywordtype">bool</span> GetThrowOnProtocolError()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_throwOnProtocolError;} 01487 <span class="keywordtype">void</span> SetThrowOnProtocolError(<span class="keywordtype">bool</span> throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;} 01488 01489 <span class="keywordtype">bool</span> HasValidState()<span class="keyword"> const </span>{<span class="keywordflow">return</span> m_validState;} 01490 01491 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> OutgoingMessageAvailable() const =0; 01492 virtual <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetOutgoingMessageLength() const =0; 01493 virtual <span class="keywordtype">void</span> GetOutgoingMessage(byte *message) =0; 01494 01495 virtual <span class="keywordtype">bool</span> LastMessageProcessed() const =0; 01496 virtual <span class="keywordtype">void</span> ProcessIncomingMessage(const byte *message, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> messageLength) =0; 01497 01498 protected: 01499 <span class="keywordtype">void</span> HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const; 01500 <span class="keywordtype">void</span> CheckAndHandleInvalidState() const; 01501 <span class="keywordtype">void</span> SetValidState(<span class="keywordtype">bool</span> valid) {m_validState = valid;} 01502 01503 RandomNumberGenerator *m_rng; 01504 01505 <span class="keyword">private</span>: 01506 <span class="keywordtype">bool</span> m_throwOnProtocolError, m_validState; 01507 }; 01508 01509 <span class="keyword">class </span>KeyAgreementSession : <span class="keyword">public</span> ProtocolSession 01510 { 01511 <span class="keyword">public</span>: 01512 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetAgreedValueLength() const =0; 01513 virtual <span class="keywordtype">void</span> GetAgreedValue(byte *agreedValue) const =0; 01514 }; 01515 01516 class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession 01517 { 01518 <span class="keyword">public</span>: 01519 <span class="keywordtype">void</span> InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng, 01520 <span class="keyword">const</span> byte *myId, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> myIdLength, 01521 <span class="keyword">const</span> byte *counterPartyId, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> counterPartyIdLength, 01522 <span class="keyword">const</span> byte *passwordOrVerifier, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> passwordOrVerifierLength); 01523 }; 01524 01525 <span class="keyword">class </span>PasswordAuthenticatedKeyAgreementDomain : <span class="keyword">public</span> KeyAgreementAlgorithm 01526 { 01527 <span class="keyword">public</span>:<span class="comment"></span> 01528 <span class="comment"> //! return whether the domain parameters stored in this object are valid</span> 01529 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> ValidateDomainParameters(RandomNumberGenerator &rng)<span class="keyword"> const</span> 01530 <span class="keyword"> </span>{<span class="keywordflow">return</span> GetCryptoParameters().Validate(rng, 2);} 01531 01532 <span class="keyword">virtual</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> GetPasswordVerifierLength(<span class="keyword">const</span> byte *password, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> passwordLength) <span class="keyword">const</span> =0; 01533 <span class="keyword">virtual</span> <span class="keywordtype">void</span> GeneratePasswordVerifier(RandomNumberGenerator &rng, <span class="keyword">const</span> byte *userId, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> userIdLength, <span class="keyword">const</span> byte *password, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> passwordLength, byte *verifier) <span class="keyword">const</span> =0; 01534 01535 <span class="keyword">enum</span> RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8}; 01536 01537 <span class="keyword">virtual</span> <span class="keywordtype">bool</span> IsValidRole(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> role) =0; 01538 <span class="keyword">virtual</span> PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> role) <span class="keyword">const</span> =0; 01539 }; 01540 <span class="preprocessor">#endif</span> 01541 <span class="preprocessor"></span><span class="comment"></span> 01542 <span class="comment">//! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation</span> <a name="l01543"></a><a class="code" href="class_b_e_r_decode_err.html">01543</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL BERDecodeErr : <span class="keyword">public</span> InvalidArgument 01544 { 01545 <span class="keyword">public</span>: 01546 BERDecodeErr() : InvalidArgument(<span class="stringliteral">"BER decode error"</span>) {} 01547 BERDecodeErr(<span class="keyword">const</span> std::string &s) : InvalidArgument(s) {} 01548 }; 01549 <span class="comment"></span> 01550 <span class="comment">//! interface for encoding and decoding ASN1 objects</span> <a name="l01551"></a><a class="code" href="class_a_s_n1_object.html">01551</a> <span class="comment"></span><span class="keyword">class </span>CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object 01552 { 01553 <span class="keyword">public</span>: 01554 <span class="keyword">virtual</span> ~ASN1Object() {}<span class="comment"></span> 01555 <span class="comment"> //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules)</span> 01556 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> BERDecode(BufferedTransformation &bt) =0;<span class="comment"></span> 01557 <span class="comment"> //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules)</span> 01558 <span class="comment"></span> <span class="keyword">virtual</span> <span class="keywordtype">void</span> DEREncode(BufferedTransformation &bt) <span class="keyword">const</span> =0;<span class="comment"></span> 01559 <span class="comment"> //! encode this object into a BufferedTransformation, using BER</span> 01560 <span class="comment"></span><span class="comment"> /*! this may be useful if DEREncode() would be too inefficient */</span> <a name="l01561"></a><a class="code" href="class_a_s_n1_object.html#_x509_public_keya10">01561</a> <span class="keyword">virtual</span> <span class="keywordtype">void</span> BEREncode(BufferedTransformation &bt)<span class="keyword"> const </span>{DEREncode(bt);} 01562 }; 01563 01564 <span class="preprocessor">#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY</span> 01565 <span class="preprocessor"></span><span class="keyword">typedef</span> PK_SignatureScheme PK_SignatureSystem; 01566 <span class="keyword">typedef</span> SimpleKeyAgreementDomain PK_SimpleKeyAgreementDomain; 01567 <span class="keyword">typedef</span> AuthenticatedKeyAgreementDomain PK_AuthenticatedKeyAgreementDomain; 01568 <span class="preprocessor">#endif</span> 01569 <span class="preprocessor"></span> 01570 NAMESPACE_END 01571 01572 <span class="preprocessor">#endif</span> </div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:57 2004 for Crypto++ by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 ></a> 1.3.7 </small></address> </body> </html>