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

Generated on Mon Apr 19 18:12:28 2004 for Crypto++ by doxygen 1.3.6-20040222