<!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++: asn.cpp 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>asn.cpp</h1><pre class="fragment"><div>00001 <span class="comment">// asn.cpp - written and placed in the public domain by Wei Dai</span> 00002 00003 <span class="preprocessor">#include "pch.h"</span> 00004 00005 <span class="preprocessor">#ifndef CRYPTOPP_IMPORTS</span> 00006 <span class="preprocessor"></span> 00007 <span class="preprocessor">#include "asn.h"</span> 00008 00009 <span class="preprocessor">#include <iomanip></span> 00010 <span class="preprocessor">#include <time.h></span> 00011 00012 NAMESPACE_BEGIN(CryptoPP) 00013 USING_NAMESPACE(std) 00014 <span class="comment"></span> 00015 <span class="comment">/// DER Length</span> 00016 <span class="comment"></span><span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> DERLengthEncode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00017 { 00018 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; 00019 <span class="keywordflow">if</span> (length <= 0x7f) 00020 { 00021 bt.Put(byte(length)); 00022 i++; 00023 } 00024 <span class="keywordflow">else</span> 00025 { 00026 bt.Put(byte(BytePrecision(length) | 0x80)); 00027 i++; 00028 <span class="keywordflow">for</span> (<span class="keywordtype">int</span> j=BytePrecision(length); j; --j) 00029 { 00030 bt.Put(byte(length >> (j-1)*8)); 00031 i++; 00032 } 00033 } 00034 <span class="keywordflow">return</span> i; 00035 } 00036 00037 <span class="keywordtype">bool</span> BERLengthDecode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &length, <span class="keywordtype">bool</span> &definiteLength) 00038 { 00039 byte b; 00040 00041 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b)) 00042 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00043 00044 <span class="keywordflow">if</span> (!(b & 0x80)) 00045 { 00046 definiteLength = <span class="keyword">true</span>; 00047 length = b; 00048 } 00049 <span class="keywordflow">else</span> 00050 { 00051 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> lengthBytes = b & 0x7f; 00052 00053 <span class="keywordflow">if</span> (lengthBytes == 0) 00054 { 00055 definiteLength = <span class="keyword">false</span>; 00056 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00057 } 00058 00059 definiteLength = <span class="keyword">true</span>; 00060 length = 0; 00061 <span class="keywordflow">while</span> (lengthBytes--) 00062 { 00063 <span class="keywordflow">if</span> (length >> (8*(<span class="keyword">sizeof</span>(length)-1))) 00064 BERDecodeError(); <span class="comment">// length about to overflow</span> 00065 00066 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b)) 00067 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00068 00069 length = (length << 8) | b; 00070 } 00071 } 00072 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00073 } 00074 00075 <span class="keywordtype">bool</span> BERLengthDecode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &length) 00076 { 00077 <span class="keywordtype">bool</span> definiteLength; 00078 <span class="keywordflow">if</span> (!BERLengthDecode(bt, length, definiteLength)) 00079 BERDecodeError(); 00080 <span class="keywordflow">return</span> definiteLength; 00081 } 00082 00083 <span class="keywordtype">void</span> DEREncodeNull(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &out) 00084 { 00085 out.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(TAG_NULL); 00086 out.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(0); 00087 } 00088 00089 <span class="keywordtype">void</span> BERDecodeNull(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &in) 00090 { 00091 byte b; 00092 <span class="keywordflow">if</span> (!in.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b) || b != TAG_NULL) 00093 BERDecodeError(); 00094 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length; 00095 <span class="keywordflow">if</span> (!BERLengthDecode(in, length) || length != 0) 00096 BERDecodeError(); 00097 } 00098 <span class="comment"></span> 00099 <span class="comment">/// ASN Strings</span> 00100 <span class="comment"></span><span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> DEREncodeOctetString(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keyword">const</span> byte *str, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> strLen) 00101 { 00102 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(OCTET_STRING); 00103 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> lengthBytes = DERLengthEncode(bt, strLen); 00104 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(str, strLen); 00105 <span class="keywordflow">return</span> 1+lengthBytes+strLen; 00106 } 00107 00108 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> DEREncodeOctetString(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keyword">const</span> <a class="code" href="class_sec_block.html">SecByteBlock</a> &str) 00109 { 00110 <span class="keywordflow">return</span> DEREncodeOctetString(bt, str.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), str.<a class="code" href="class_sec_block.html#_sec_block_with_hinta15">size</a>()); 00111 } 00112 00113 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BERDecodeOctetString(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <a class="code" href="class_sec_block.html">SecByteBlock</a> &str) 00114 { 00115 byte b; 00116 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b) || b != OCTET_STRING) 00117 BERDecodeError(); 00118 00119 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bc; 00120 <span class="keywordflow">if</span> (!BERLengthDecode(bt, bc)) 00121 BERDecodeError(); 00122 00123 str.<a class="code" href="class_sec_block.html#_sec_block_with_hinta25">resize</a>(bc); 00124 <span class="keywordflow">if</span> (bc != bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(str, bc)) 00125 BERDecodeError(); 00126 <span class="keywordflow">return</span> bc; 00127 } 00128 00129 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BERDecodeOctetString(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &str) 00130 { 00131 byte b; 00132 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b) || b != OCTET_STRING) 00133 BERDecodeError(); 00134 00135 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bc; 00136 <span class="keywordflow">if</span> (!BERLengthDecode(bt, bc)) 00137 BERDecodeError(); 00138 00139 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_10">TransferTo</a>(str, bc); 00140 <span class="keywordflow">return</span> bc; 00141 } 00142 00143 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> DEREncodeTextString(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keyword">const</span> std::string &str, byte asnTag) 00144 { 00145 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(asnTag); 00146 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> lengthBytes = DERLengthEncode(bt, str.size()); 00147 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>((<span class="keyword">const</span> byte *)str.data(), str.size()); 00148 <span class="keywordflow">return</span> 1+lengthBytes+str.size(); 00149 } 00150 00151 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BERDecodeTextString(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, std::string &str, byte asnTag) 00152 { 00153 byte b; 00154 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b) || b != asnTag) 00155 BERDecodeError(); 00156 00157 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bc; 00158 <span class="keywordflow">if</span> (!BERLengthDecode(bt, bc)) 00159 BERDecodeError(); 00160 00161 <a class="code" href="class_sec_block.html">SecByteBlock</a> temp(bc); 00162 <span class="keywordflow">if</span> (bc != bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(temp, bc)) 00163 BERDecodeError(); 00164 str.assign((<span class="keywordtype">char</span> *)temp.<a class="code" href="class_sec_block.html#_sec_block_with_hinta9">begin</a>(), bc); 00165 <span class="keywordflow">return</span> bc; 00166 } 00167 <span class="comment"></span> 00168 <span class="comment">/// ASN BitString</span> 00169 <span class="comment"></span><span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> DEREncodeBitString(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keyword">const</span> byte *str, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> strLen, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> unusedBits) 00170 { 00171 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(BIT_STRING); 00172 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> lengthBytes = DERLengthEncode(bt, strLen+1); 00173 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>((byte)unusedBits); 00174 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(str, strLen); 00175 <span class="keywordflow">return</span> 2+lengthBytes+strLen; 00176 } 00177 00178 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BERDecodeBitString(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <a class="code" href="class_sec_block.html">SecByteBlock</a> &str, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> &unusedBits) 00179 { 00180 byte b; 00181 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b) || b != BIT_STRING) 00182 BERDecodeError(); 00183 00184 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bc; 00185 <span class="keywordflow">if</span> (!BERLengthDecode(bt, bc)) 00186 BERDecodeError(); 00187 00188 byte unused; 00189 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(unused)) 00190 BERDecodeError(); 00191 unusedBits = unused; 00192 str.<a class="code" href="class_sec_block.html#_sec_block_with_hinta25">resize</a>(bc-1); 00193 <span class="keywordflow">if</span> ((bc-1) != bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(str, bc-1)) 00194 BERDecodeError(); 00195 <span class="keywordflow">return</span> bc-1; 00196 } 00197 00198 <span class="keywordtype">void</span> DERReencode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &source, <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &dest) 00199 { 00200 byte tag; 00201 source.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_4">Peek</a>(tag); 00202 <a class="code" href="class_b_e_r_general_decoder.html">BERGeneralDecoder</a> decoder(source, tag); 00203 <a class="code" href="class_d_e_r_general_encoder.html">DERGeneralEncoder</a> encoder(dest, tag); 00204 <span class="keywordflow">if</span> (decoder.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera2">IsDefiniteLength</a>()) 00205 decoder.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_10">TransferTo</a>(encoder, decoder.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera3">RemainingLength</a>()); 00206 <span class="keywordflow">else</span> 00207 { 00208 <span class="keywordflow">while</span> (!decoder.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera4">EndReached</a>()) 00209 DERReencode(decoder, encoder); 00210 } 00211 decoder.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>(); 00212 encoder.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>(); 00213 } 00214 00215 <span class="keywordtype">void</span> OID::EncodeValue(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> v) 00216 { 00217 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7) 00218 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>((byte)(0x80 | ((v >> i) & 0x7f))); 00219 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>((byte)(v & 0x7f)); 00220 } 00221 00222 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> OID::DecodeValue(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> &v) 00223 { 00224 byte b; 00225 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; 00226 v = 0; 00227 <span class="keywordflow">while</span> (<span class="keyword">true</span>) 00228 { 00229 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b)) 00230 BERDecodeError(); 00231 i++; 00232 v <<= 7; 00233 v += b & 0x7f; 00234 <span class="keywordflow">if</span> (!(b & 0x80)) 00235 <span class="keywordflow">return</span> i; 00236 } 00237 } 00238 00239 <span class="keywordtype">void</span> OID::DEREncode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt)<span class="keyword"> const</span> 00240 <span class="keyword"></span>{ 00241 assert(m_values.size() >= 2); 00242 <a class="code" href="class_byte_queue.html">ByteQueue</a> temp; 00243 temp.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(byte(m_values[0] * 40 + m_values[1])); 00244 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=2; i<m_values.size(); i++) 00245 EncodeValue(temp, m_values[i]); 00246 bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(OBJECT_IDENTIFIER); 00247 DERLengthEncode(bt, temp.<a class="code" href="class_byte_queue.html#_d_e_r_set_encodera15">CurrentSize</a>()); 00248 temp.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_10">TransferTo</a>(bt); 00249 } 00250 00251 <span class="keywordtype">void</span> OID::BERDecode(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt) 00252 { 00253 byte b; 00254 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b) || b != OBJECT_IDENTIFIER) 00255 BERDecodeError(); 00256 00257 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length; 00258 <span class="keywordflow">if</span> (!BERLengthDecode(bt, length) || length < 1) 00259 BERDecodeError(); 00260 00261 <span class="keywordflow">if</span> (!bt.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b)) 00262 BERDecodeError(); 00263 00264 length--; 00265 m_values.resize(2); 00266 m_values[0] = b / 40; 00267 m_values[1] = b % 40; 00268 00269 <span class="keywordflow">while</span> (length > 0) 00270 { 00271 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> v; 00272 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> valueLen = DecodeValue(bt, v); 00273 <span class="keywordflow">if</span> (valueLen > length) 00274 BERDecodeError(); 00275 m_values.push_back(v); 00276 length -= valueLen; 00277 } 00278 } 00279 00280 <span class="keywordtype">void</span> OID::BERDecodeAndCheck(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt)<span class="keyword"> const</span> 00281 <span class="keyword"></span>{ 00282 <a class="code" href="class_o_i_d.html">OID</a> oid(bt); 00283 <span class="keywordflow">if</span> (*<span class="keyword">this</span> != oid) 00284 BERDecodeError(); 00285 } 00286 00287 <span class="keyword">inline</span> <a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> & EncodedObjectFilter::CurrentTarget() 00288 { 00289 <span class="keywordflow">if</span> (m_flags & PUT_OBJECTS) 00290 <span class="keywordflow">return</span> *AttachedTransformation(); 00291 <span class="keywordflow">else</span> 00292 <span class="keywordflow">return</span> TheBitBucket(); 00293 } 00294 00295 <span class="keywordtype">void</span> <a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">EncodedObjectFilter::Put</a>(<span class="keyword">const</span> byte *inString, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length) 00296 { 00297 <span class="keywordflow">if</span> (m_nCurrentObject == m_nObjects) 00298 { 00299 AttachedTransformation()->Put(inString, length); 00300 <span class="keywordflow">return</span>; 00301 } 00302 00303 <a class="code" href="class_lazy_putter.html">LazyPutter</a> lazyPutter(m_queue, inString, length); 00304 00305 <span class="keywordflow">while</span> (m_queue.AnyRetrievable()) 00306 { 00307 <span class="keywordflow">switch</span> (m_state) 00308 { 00309 <span class="keywordflow">case</span> IDENTIFIER: 00310 <span class="keywordflow">if</span> (!m_queue.Get(m_id)) 00311 <span class="keywordflow">return</span>; 00312 m_queue.TransferTo(CurrentTarget(), 1); 00313 m_state = LENGTH; <span class="comment">// fall through</span> 00314 <span class="keywordflow">case</span> LENGTH: 00315 { 00316 byte b; 00317 <span class="keywordflow">if</span> (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0) 00318 { 00319 m_queue.TransferTo(CurrentTarget(), 1); 00320 m_level--; 00321 m_state = IDENTIFIER; 00322 <span class="keywordflow">break</span>; 00323 } 00324 ByteQueue::Walker walker(m_queue); 00325 <span class="keywordtype">bool</span> definiteLength; 00326 <span class="keywordflow">if</span> (!BERLengthDecode(walker, m_lengthRemaining, definiteLength)) 00327 <span class="keywordflow">return</span>; 00328 m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition()); 00329 <span class="keywordflow">if</span> (!((m_id & CONSTRUCTED) || definiteLength)) 00330 BERDecodeError(); 00331 <span class="keywordflow">if</span> (!definiteLength) 00332 { 00333 <span class="keywordflow">if</span> (!(m_id & CONSTRUCTED)) 00334 BERDecodeError(); 00335 m_level++; 00336 m_state = IDENTIFIER; 00337 <span class="keywordflow">break</span>; 00338 } 00339 m_state = BODY; <span class="comment">// fall through</span> 00340 } 00341 <span class="keywordflow">case</span> BODY: 00342 m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining); 00343 00344 <span class="keywordflow">if</span> (m_lengthRemaining == 0) 00345 m_state = IDENTIFIER; 00346 } 00347 00348 <span class="keywordflow">if</span> (m_state == IDENTIFIER && m_level == 0) 00349 { 00350 <span class="comment">// just finished processing a level 0 object</span> 00351 ++m_nCurrentObject; 00352 00353 <span class="keywordflow">if</span> (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT) 00354 AttachedTransformation()->MessageEnd(); 00355 00356 <span class="keywordflow">if</span> (m_nCurrentObject == m_nObjects) 00357 { 00358 <span class="keywordflow">if</span> (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS) 00359 AttachedTransformation()->MessageEnd(); 00360 00361 <span class="keywordflow">if</span> (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS) 00362 AttachedTransformation()->MessageSeriesEnd(); 00363 00364 m_queue.TransferAllTo(*AttachedTransformation()); 00365 <span class="keywordflow">return</span>; 00366 } 00367 } 00368 } 00369 } 00370 00371 BERGeneralDecoder::BERGeneralDecoder(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &inQueue, byte asnTag) 00372 : m_inQueue(inQueue), m_finished(false) 00373 { 00374 Init(asnTag); 00375 } 00376 00377 BERGeneralDecoder::BERGeneralDecoder(<a class="code" href="class_b_e_r_general_decoder.html">BERGeneralDecoder</a> &inQueue, byte asnTag) 00378 : m_inQueue(inQueue), m_finished(false) 00379 { 00380 Init(asnTag); 00381 } 00382 00383 <span class="keywordtype">void</span> BERGeneralDecoder::Init(byte asnTag) 00384 { 00385 byte b; 00386 <span class="keywordflow">if</span> (!m_inQueue.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b) || b != asnTag) 00387 BERDecodeError(); 00388 00389 m_definiteLength = BERLengthDecode(m_inQueue, m_length); 00390 <span class="keywordflow">if</span> (!m_definiteLength && !(asnTag & CONSTRUCTED)) 00391 BERDecodeError(); <span class="comment">// cannot be primitive and have indefinite length</span> 00392 } 00393 00394 BERGeneralDecoder::~BERGeneralDecoder() 00395 { 00396 <span class="keywordflow">try</span> <span class="comment">// avoid throwing in constructor</span> 00397 { 00398 <span class="keywordflow">if</span> (!m_finished) 00399 MessageEnd(); 00400 } 00401 <span class="keywordflow">catch</span> (...) 00402 { 00403 } 00404 } 00405 00406 <span class="keywordtype">bool</span> BERGeneralDecoder::EndReached()<span class="keyword"> const</span> 00407 <span class="keyword"></span>{ 00408 <span class="keywordflow">if</span> (m_definiteLength) 00409 <span class="keywordflow">return</span> m_length == 0; 00410 <span class="keywordflow">else</span> 00411 { <span class="comment">// check end-of-content octets</span> 00412 word16 i; 00413 <span class="keywordflow">return</span> (m_inQueue.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_8">PeekWord16</a>(i)==2 && i==0); 00414 } 00415 } 00416 00417 byte BERGeneralDecoder::PeekByte()<span class="keyword"> const</span> 00418 <span class="keyword"></span>{ 00419 byte b; 00420 <span class="keywordflow">if</span> (!<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_4">Peek</a>(b)) 00421 BERDecodeError(); 00422 <span class="keywordflow">return</span> b; 00423 } 00424 00425 <span class="keywordtype">void</span> BERGeneralDecoder::CheckByte(byte check) 00426 { 00427 byte b; 00428 <span class="keywordflow">if</span> (!<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_2">Get</a>(b) || b != check) 00429 BERDecodeError(); 00430 } 00431 00432 <span class="keywordtype">void</span> BERGeneralDecoder::MessageEnd() 00433 { 00434 m_finished = <span class="keyword">true</span>; 00435 <span class="keywordflow">if</span> (m_definiteLength) 00436 { 00437 <span class="keywordflow">if</span> (m_length != 0) 00438 BERDecodeError(); 00439 } 00440 <span class="keywordflow">else</span> 00441 { <span class="comment">// remove end-of-content octets</span> 00442 word16 i; 00443 <span class="keywordflow">if</span> (m_inQueue.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_6">GetWord16</a>(i) != 2 || i != 0) 00444 BERDecodeError(); 00445 } 00446 } 00447 00448 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BERGeneralDecoder::TransferTo2(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> &transferBytes, <span class="keyword">const</span> std::string &channel, <span class="keywordtype">bool</span> blocking) 00449 { 00450 <span class="keywordflow">if</span> (m_definiteLength && transferBytes > m_length) 00451 transferBytes = m_length; 00452 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> blockedBytes = m_inQueue.<a class="code" href="class_buffered_transformation.html#_storez11_0">TransferTo2</a>(target, transferBytes, channel, blocking); 00453 ReduceLength(transferBytes); 00454 <span class="keywordflow">return</span> blockedBytes; 00455 } 00456 00457 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BERGeneralDecoder::CopyRangeTo2(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &target, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> &begin, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> end, <span class="keyword">const</span> std::string &channel, <span class="keywordtype">bool</span> blocking)<span class="keyword"> const</span> 00458 <span class="keyword"></span>{ 00459 <span class="keywordflow">if</span> (m_definiteLength) 00460 end = STDMIN((<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)m_length, end); 00461 <span class="keywordflow">return</span> m_inQueue.<a class="code" href="class_buffered_transformation.html#_storez11_1">CopyRangeTo2</a>(target, begin, end, channel, blocking); 00462 } 00463 00464 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> BERGeneralDecoder::ReduceLength(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> delta) 00465 { 00466 <span class="keywordflow">if</span> (m_definiteLength) 00467 { 00468 <span class="keywordflow">if</span> (m_length < delta) 00469 BERDecodeError(); 00470 m_length -= delta; 00471 } 00472 <span class="keywordflow">return</span> delta; 00473 } 00474 00475 DERGeneralEncoder::DERGeneralEncoder(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &outQueue, byte asnTag) 00476 : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag) 00477 { 00478 } 00479 00480 DERGeneralEncoder::DERGeneralEncoder(<a class="code" href="class_d_e_r_general_encoder.html">DERGeneralEncoder</a> &outQueue, byte asnTag) 00481 : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag) 00482 { 00483 } 00484 00485 DERGeneralEncoder::~DERGeneralEncoder() 00486 { 00487 <span class="keywordflow">try</span> <span class="comment">// avoid throwing in constructor</span> 00488 { 00489 <span class="keywordflow">if</span> (!m_finished) 00490 MessageEnd(); 00491 } 00492 <span class="keywordflow">catch</span> (...) 00493 { 00494 } 00495 } 00496 00497 <span class="keywordtype">void</span> DERGeneralEncoder::MessageEnd() 00498 { 00499 m_finished = <span class="keyword">true</span>; 00500 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length = (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>)CurrentSize(); 00501 m_outQueue.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(m_asnTag); 00502 DERLengthEncode(m_outQueue, length); 00503 <a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_10">TransferTo</a>(m_outQueue); 00504 } 00505 00506 <span class="comment">// *************************************************************</span> 00507 <a name="l00508"></a><a class="code" href="class_x509_public_key.html#_x509_public_keya0">00508</a> <span class="keywordtype">void</span> <a class="code" href="class_x509_public_key.html#_x509_public_keya0">X509PublicKey::BERDecode</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt) 00509 { 00510 <a class="code" href="class_b_e_r_sequence_decoder.html">BERSequenceDecoder</a> subjectPublicKeyInfo(bt); 00511 <a class="code" href="class_b_e_r_sequence_decoder.html">BERSequenceDecoder</a> algorithm(subjectPublicKeyInfo); 00512 GetAlgorithmID().<a class="code" href="class_o_i_d.html#_o_i_da6">BERDecodeAndCheck</a>(algorithm); 00513 <span class="keywordtype">bool</span> parametersPresent = algorithm.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera4">EndReached</a>() ? <span class="keyword">false</span> : BERDecodeAlgorithmParameters(algorithm); 00514 algorithm.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>(); 00515 00516 <a class="code" href="class_b_e_r_general_decoder.html">BERGeneralDecoder</a> subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); 00517 subjectPublicKey.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera6">CheckByte</a>(0); <span class="comment">// unused bits</span> 00518 BERDecodeKey2(subjectPublicKey, parametersPresent, subjectPublicKey.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera3">RemainingLength</a>()); 00519 subjectPublicKey.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>(); 00520 subjectPublicKeyInfo.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>(); 00521 } 00522 <a name="l00523"></a><a class="code" href="class_x509_public_key.html#_x509_public_keya1">00523</a> <span class="keywordtype">void</span> <a class="code" href="class_x509_public_key.html#_x509_public_keya1">X509PublicKey::DEREncode</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt)<span class="keyword"> const</span> 00524 <span class="keyword"></span>{ 00525 <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> subjectPublicKeyInfo(bt); 00526 00527 <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> algorithm(subjectPublicKeyInfo); 00528 GetAlgorithmID().<a class="code" href="class_o_i_d.html#_o_i_da4">DEREncode</a>(algorithm); 00529 DEREncodeAlgorithmParameters(algorithm); 00530 algorithm.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>(); 00531 00532 <a class="code" href="class_d_e_r_general_encoder.html">DERGeneralEncoder</a> subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); 00533 subjectPublicKey.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz1_0">Put</a>(0); <span class="comment">// unused bits</span> 00534 DEREncodeKey(subjectPublicKey); 00535 subjectPublicKey.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>(); 00536 00537 subjectPublicKeyInfo.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>(); 00538 } 00539 <a name="l00540"></a><a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya0">00540</a> <span class="keywordtype">void</span> <a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya0">PKCS8PrivateKey::BERDecode</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt) 00541 { 00542 <a class="code" href="class_b_e_r_sequence_decoder.html">BERSequenceDecoder</a> privateKeyInfo(bt); 00543 word32 version; 00544 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0); <span class="comment">// check version</span> 00545 00546 <a class="code" href="class_b_e_r_sequence_decoder.html">BERSequenceDecoder</a> algorithm(privateKeyInfo); 00547 GetAlgorithmID().<a class="code" href="class_o_i_d.html#_o_i_da6">BERDecodeAndCheck</a>(algorithm); 00548 <span class="keywordtype">bool</span> parametersPresent = BERDecodeAlgorithmParameters(algorithm); 00549 algorithm.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>(); 00550 00551 <a class="code" href="class_b_e_r_general_decoder.html">BERGeneralDecoder</a> octetString(privateKeyInfo, OCTET_STRING); 00552 BERDecodeKey2(octetString, parametersPresent, privateKeyInfo.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera3">RemainingLength</a>()); 00553 octetString.<a class="code" href="class_b_e_r_general_decoder.html#_b_e_r_set_decodera9">MessageEnd</a>(); 00554 00555 <span class="keywordflow">if</span> (!privateKeyInfo.EndReached()) 00556 <a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya2">BERDecodeOptionalAttributes</a>(privateKeyInfo); 00557 privateKeyInfo.MessageEnd(); 00558 } 00559 <a name="l00560"></a><a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya1">00560</a> <span class="keywordtype">void</span> <a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya1">PKCS8PrivateKey::DEREncode</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt)<span class="keyword"> const</span> 00561 <span class="keyword"></span>{ 00562 <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> privateKeyInfo(bt); 00563 DEREncodeUnsigned<word32>(privateKeyInfo, 0); <span class="comment">// version</span> 00564 00565 <a class="code" href="class_d_e_r_sequence_encoder.html">DERSequenceEncoder</a> algorithm(privateKeyInfo); 00566 GetAlgorithmID().<a class="code" href="class_o_i_d.html#_o_i_da4">DEREncode</a>(algorithm); 00567 DEREncodeAlgorithmParameters(algorithm); 00568 algorithm.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>(); 00569 00570 <a class="code" href="class_d_e_r_general_encoder.html">DERGeneralEncoder</a> octetString(privateKeyInfo, OCTET_STRING); 00571 DEREncodeKey(octetString); 00572 octetString.<a class="code" href="class_d_e_r_general_encoder.html#_d_e_r_set_encodera2">MessageEnd</a>(); 00573 00574 <a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya3">DEREncodeOptionalAttributes</a>(privateKeyInfo); 00575 privateKeyInfo.MessageEnd(); 00576 } 00577 <a name="l00578"></a><a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya2">00578</a> <span class="keywordtype">void</span> <a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya2">PKCS8PrivateKey::BERDecodeOptionalAttributes</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt) 00579 { 00580 DERReencode(bt, m_optionalAttributes); 00581 } 00582 <a name="l00583"></a><a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya3">00583</a> <span class="keywordtype">void</span> <a class="code" href="class_p_k_c_s8_private_key.html#_p_k_c_s8_private_keya3">PKCS8PrivateKey::DEREncodeOptionalAttributes</a>(<a class="code" href="class_buffered_transformation.html">BufferedTransformation</a> &bt)<span class="keyword"> const</span> 00584 <span class="keyword"></span>{ 00585 m_optionalAttributes.<a class="code" href="class_buffered_transformation.html#_zlib_decompressorz7_12">CopyTo</a>(bt); 00586 } 00587 00588 NAMESPACE_END 00589 00590 <span class="preprocessor">#endif</span> </div></pre><hr size="1"><address style="align: right;"><small>Generated on Sun Nov 7 08:23:56 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>