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