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