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

Generated on Thu Oct 28 03:02:10 2004 for Crypto++ by  doxygen 1.3.9.1