Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | 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