Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

asn.cpp

00001 // asn.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "asn.h"
00005 
00006 #include <iomanip>
00007 #include <time.h>
00008 
00009 NAMESPACE_BEGIN(CryptoPP)
00010 USING_NAMESPACE(std)
00011 
00013 unsigned int DERLengthEncode(BufferedTransformation &bt, unsigned int length)
00014 {
00015         unsigned int i=0;
00016         if (length <= 0x7f)
00017         {
00018                 bt.Put(byte(length));
00019                 i++;
00020         }
00021         else
00022         {
00023                 bt.Put(byte(BytePrecision(length) | 0x80));
00024                 i++;
00025                 for (int j=BytePrecision(length); j; --j)
00026                 {
00027                         bt.Put(byte(length >> (j-1)*8));
00028                         i++;
00029                 }
00030         }
00031         return i;
00032 }
00033 
00034 bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length)
00035 {
00036         byte b;
00037 
00038         if (!bt.Get(b))
00039                 BERDecodeError();
00040 
00041         if (!(b & 0x80))
00042                 length = b;
00043         else
00044         {
00045                 unsigned int lengthBytes = b & 0x7f;
00046 
00047                 if (lengthBytes == 0)
00048                         return false;   // indefinite length
00049 
00050                 length = 0;
00051                 while (lengthBytes--)
00052                 {
00053                         if (length >> (8*(sizeof(length)-1)))
00054                                 BERDecodeError();       // length about to overflow
00055 
00056                         if (!bt.Get(b))
00057                                 BERDecodeError();
00058 
00059                         length = (length << 8) | b;
00060                 }
00061         }
00062         return true;
00063 }
00064 
00065 void DEREncodeNull(BufferedTransformation &out)
00066 {
00067         out.Put(TAG_NULL);
00068         out.Put(0);
00069 }
00070 
00071 void BERDecodeNull(BufferedTransformation &in)
00072 {
00073         byte b;
00074         if (!in.Get(b) || b != TAG_NULL)
00075                 BERDecodeError();
00076         unsigned int length;
00077         if (!BERLengthDecode(in, length) || length != 0)
00078                 BERDecodeError();
00079 }
00080 
00082 unsigned int DEREncodeOctetString(BufferedTransformation &bt, const byte *str, unsigned int strLen)
00083 {
00084         bt.Put(OCTET_STRING);
00085         unsigned int lengthBytes = DERLengthEncode(bt, strLen);
00086         bt.Put(str, strLen);
00087         return 1+lengthBytes+strLen;
00088 }
00089 
00090 unsigned int DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str)
00091 {
00092         return DEREncodeOctetString(bt, str.ptr, str.size);
00093 }
00094 
00095 unsigned int BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str)
00096 {
00097         byte b;
00098         if (!bt.Get(b) || b != OCTET_STRING)
00099                 BERDecodeError();
00100 
00101         unsigned int bc;
00102         if (!BERLengthDecode(bt, bc))
00103                 BERDecodeError();
00104 
00105         str.Resize(bc);
00106         if (bc != bt.Get(str, bc))
00107                 BERDecodeError();
00108         return bc;
00109 }
00110 
00111 unsigned int BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str)
00112 {
00113         byte b;
00114         if (!bt.Get(b) || b != OCTET_STRING)
00115                 BERDecodeError();
00116 
00117         unsigned int bc;
00118         if (!BERLengthDecode(bt, bc))
00119                 BERDecodeError();
00120 
00121         bt.TransferTo(str, bc);
00122         return bc;
00123 }
00124 
00125 unsigned int DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag)
00126 {
00127         bt.Put(asnTag);
00128         unsigned int lengthBytes = DERLengthEncode(bt, str.size());
00129         bt.Put((const byte *)str.data(), str.size());
00130         return 1+lengthBytes+str.size();
00131 }
00132 
00133 unsigned int BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag)
00134 {
00135         byte b;
00136         if (!bt.Get(b) || b != asnTag)
00137                 BERDecodeError();
00138 
00139         unsigned int bc;
00140         if (!BERLengthDecode(bt, bc))
00141                 BERDecodeError();
00142 
00143         SecByteBlock temp(bc);
00144         if (bc != bt.Get(temp, bc))
00145                 BERDecodeError();
00146         str.assign((char *)temp.ptr, bc);
00147         return bc;
00148 }
00149 
00151 unsigned int DEREncodeBitString(BufferedTransformation &bt, const byte *str, unsigned int strLen, unsigned int unusedBits)
00152 {
00153         bt.Put(BIT_STRING);
00154         unsigned int lengthBytes = DERLengthEncode(bt, strLen+1);
00155         bt.Put((byte)unusedBits);
00156         bt.Put(str, strLen);
00157         return 1+lengthBytes+strLen;
00158 }
00159 
00160 unsigned int BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits)
00161 {
00162         byte b;
00163         if (!bt.Get(b) || b != BIT_STRING)
00164                 BERDecodeError();
00165 
00166         unsigned int bc;
00167         if (!BERLengthDecode(bt, bc))
00168                 BERDecodeError();
00169 
00170         byte unused;
00171         if (!bt.Get(unused))
00172                 BERDecodeError();
00173         unusedBits = unused;
00174         str.Resize(bc-1);
00175         if ((bc-1) != bt.Get(str, bc-1))
00176                 BERDecodeError();
00177         return bc-1;
00178 }
00179 
00180 void OID::EncodeValue(BufferedTransformation &bt, unsigned long v)
00181 {
00182         for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7)-7; i != 0; i-=7)
00183                 bt.Put(0x80 | ((v >> i) & 0x7f));
00184         bt.Put(v & 0x7f);
00185 }
00186 
00187 unsigned int OID::DecodeValue(BufferedTransformation &bt, unsigned long &v)
00188 {
00189         byte b;
00190         unsigned int i=0;
00191         v = 0;
00192         while (true)
00193         {
00194                 if (!bt.Get(b))
00195                         BERDecodeError();
00196                 i++;
00197                 v <<= 7;
00198                 v += b & 0x7f;
00199                 if (!(b & 0x80))
00200                         return i;
00201         }
00202 }
00203 
00204 void OID::DEREncode(BufferedTransformation &bt) const
00205 {
00206         assert(m_values.size() >= 2);
00207         ByteQueue temp;
00208         temp.Put(byte(m_values[0] * 40 + m_values[1]));
00209         for (unsigned int i=2; i<m_values.size(); i++)
00210                 EncodeValue(temp, m_values[i]);
00211         bt.Put(OBJECT_IDENTIFIER);
00212         DERLengthEncode(bt, temp.CurrentSize());
00213         temp.TransferTo(bt);
00214 }
00215 
00216 void OID::BERDecode(BufferedTransformation &bt)
00217 {
00218         byte b;
00219         if (!bt.Get(b) || b != OBJECT_IDENTIFIER)
00220                 BERDecodeError();
00221 
00222         unsigned int length;
00223         if (!BERLengthDecode(bt, length) || length < 1)
00224                 BERDecodeError();
00225 
00226         if (!bt.Get(b))
00227                 BERDecodeError();
00228         
00229         length--;
00230         m_values.resize(2);
00231         m_values[0] = b / 40;
00232         m_values[1] = b % 40;
00233 
00234         while (length > 0)
00235         {
00236                 unsigned long v;
00237                 unsigned int valueLen = DecodeValue(bt, v);
00238                 if (valueLen > length)
00239                         BERDecodeError();
00240                 m_values.push_back(v);
00241                 length -= valueLen;
00242         }
00243 }
00244 
00245 void OID::BERDecodeAndCheck(BufferedTransformation &bt) const
00246 {
00247         OID oid(bt);
00248         if (*this != oid)
00249                 BERDecodeError();
00250 }
00251 
00252 BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
00253         : m_inQueue(inQueue), m_finished(false)
00254 {
00255         byte b;
00256         if (!m_inQueue.Get(b) || b != asnTag)
00257                 BERDecodeError();
00258 
00259         m_definiteLength = BERLengthDecode(m_inQueue, m_length);
00260 }
00261 
00262 BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
00263         : m_inQueue(inQueue), m_finished(false)
00264 {
00265         byte b;
00266         if (!m_inQueue.Get(b) || b != asnTag)
00267                 BERDecodeError();
00268 
00269         m_definiteLength = BERLengthDecode(m_inQueue, m_length);
00270         if (!m_definiteLength && !(asnTag | CONSTRUCTED))
00271                 BERDecodeError();       // cannot be primitive have indefinite length
00272 }
00273 
00274 BERGeneralDecoder::~BERGeneralDecoder()
00275 {
00276         try     // avoid throwing in constructor
00277         {
00278                 if (!m_finished)
00279                         MessageEnd();
00280         }
00281         catch (...)
00282         {
00283         }
00284 }
00285 
00286 bool BERGeneralDecoder::EndReached() const
00287 {
00288         if (m_definiteLength)
00289                 return m_length == 0;
00290         else
00291         {       // check end-of-content octets
00292                 word16 i;
00293                 return (m_inQueue.PeekWord16(i)==2 && i==0);
00294         }
00295 }
00296 
00297 byte BERGeneralDecoder::PeekByte() const
00298 {
00299         byte b;
00300         if (!Peek(b))
00301                 BERDecodeError();
00302         return b;
00303 }
00304 
00305 void BERGeneralDecoder::CheckByte(byte check)
00306 {
00307         byte b;
00308         if (!Get(b) || b != check)
00309                 BERDecodeError();
00310 }
00311 
00312 void BERGeneralDecoder::MessageEnd(int)
00313 {
00314         m_finished = true;
00315         if (m_definiteLength)
00316         {
00317                 if (m_length != 0)
00318                         BERDecodeError();
00319         }
00320         else
00321         {       // remove end-of-content octets
00322                 word16 i;
00323                 if (m_inQueue.GetWord16(i) != 2 || i != 0)
00324                         BERDecodeError();
00325         }
00326 }
00327 
00328 unsigned long BERGeneralDecoder::TransferTo(BufferedTransformation &target, unsigned long transferMax)
00329 {
00330         return ReduceLength(m_inQueue.TransferTo(target, m_definiteLength ? STDMIN(transferMax, (unsigned long)m_length) : transferMax));
00331 }
00332 
00333 unsigned long BERGeneralDecoder::CopyTo(BufferedTransformation &target, unsigned long copyMax) const
00334 {
00335         return m_inQueue.CopyTo(target, m_definiteLength ? STDMIN(copyMax, (unsigned long)m_length) : copyMax);
00336 }
00337 
00338 unsigned int BERGeneralDecoder::ReduceLength(unsigned int delta)
00339 {
00340         if (m_definiteLength)
00341         {
00342                 if (m_length < delta)
00343                         BERDecodeError();
00344                 m_length -= delta;
00345         }
00346         return delta;
00347 }
00348 
00349 DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
00350         : m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
00351 {
00352 }
00353 
00354 DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
00355         : m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
00356 {
00357 }
00358 
00359 DERGeneralEncoder::~DERGeneralEncoder()
00360 {
00361         try     // avoid throwing in constructor
00362         {
00363                 if (!m_finished)
00364                         MessageEnd();
00365         }
00366         catch (...)
00367         {
00368         }
00369 }
00370 
00371 void DERGeneralEncoder::MessageEnd(int)
00372 {
00373         m_finished = true;
00374         unsigned int length = (unsigned int)CurrentSize();
00375         m_outQueue.Put(m_asnTag);
00376         DERLengthEncode(m_outQueue, length);
00377         TransferTo(m_outQueue);
00378 }
00379 
00380 NAMESPACE_END

Generated at Mon Jan 15 01:16:29 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000