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 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();
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
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
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 OID::EncodeValue(BufferedTransformation &bt, unsigned long v)
00199 {
00200 for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7)
00201 bt.Put((byte)(0x80 | ((v >> i) & 0x7f)));
00202 bt.Put((byte)(v & 0x7f));
00203 }
00204
00205 unsigned int OID::DecodeValue(BufferedTransformation &bt, unsigned long &v)
00206 {
00207 byte b;
00208 unsigned int i=0;
00209 v = 0;
00210 while (true)
00211 {
00212 if (!bt.Get(b))
00213 BERDecodeError();
00214 i++;
00215 v <<= 7;
00216 v += b & 0x7f;
00217 if (!(b & 0x80))
00218 return i;
00219 }
00220 }
00221
00222 void OID::DEREncode(BufferedTransformation &bt) const
00223 {
00224 assert(m_values.size() >= 2);
00225 ByteQueue temp;
00226 temp.Put(byte(m_values[0] * 40 + m_values[1]));
00227 for (unsigned int i=2; i<m_values.size(); i++)
00228 EncodeValue(temp, m_values[i]);
00229 bt.Put(OBJECT_IDENTIFIER);
00230 DERLengthEncode(bt, temp.CurrentSize());
00231 temp.TransferTo(bt);
00232 }
00233
00234 void OID::BERDecode(BufferedTransformation &bt)
00235 {
00236 byte b;
00237 if (!bt.Get(b) || b != OBJECT_IDENTIFIER)
00238 BERDecodeError();
00239
00240 unsigned int length;
00241 if (!BERLengthDecode(bt, length) || length < 1)
00242 BERDecodeError();
00243
00244 if (!bt.Get(b))
00245 BERDecodeError();
00246
00247 length--;
00248 m_values.resize(2);
00249 m_values[0] = b / 40;
00250 m_values[1] = b % 40;
00251
00252 while (length > 0)
00253 {
00254 unsigned long v;
00255 unsigned int valueLen = DecodeValue(bt, v);
00256 if (valueLen > length)
00257 BERDecodeError();
00258 m_values.push_back(v);
00259 length -= valueLen;
00260 }
00261 }
00262
00263 void OID::BERDecodeAndCheck(BufferedTransformation &bt) const
00264 {
00265 OID oid(bt);
00266 if (*this != oid)
00267 BERDecodeError();
00268 }
00269
00270 inline BufferedTransformation & EncodedObjectFilter::CurrentTarget()
00271 {
00272 if (m_flags & PUT_OBJECTS)
00273 return *AttachedTransformation();
00274 else
00275 return TheBitBucket();
00276 }
00277
00278 void EncodedObjectFilter::Put(const byte *inString, unsigned int length)
00279 {
00280 if (m_nCurrentObject == m_nObjects)
00281 {
00282 AttachedTransformation()->Put(inString, length);
00283 return;
00284 }
00285
00286 LazyPutter lazyPutter(m_queue, inString, length);
00287
00288 while (m_queue.AnyRetrievable())
00289 {
00290 switch (m_state)
00291 {
00292 case IDENTIFIER:
00293 if (!m_queue.Get(m_id))
00294 return;
00295 m_queue.TransferTo(CurrentTarget(), 1);
00296 m_state = LENGTH;
00297 case LENGTH:
00298 {
00299 byte b;
00300 if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0)
00301 {
00302 m_queue.TransferTo(CurrentTarget(), 1);
00303 m_level--;
00304 m_state = IDENTIFIER;
00305 break;
00306 }
00307 ByteQueue::Walker walker(m_queue);
00308 bool definiteLength;
00309 if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength))
00310 return;
00311 m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition());
00312 if (!((m_id & CONSTRUCTED) || definiteLength))
00313 BERDecodeError();
00314 if (!definiteLength)
00315 {
00316 if (!(m_id & CONSTRUCTED))
00317 BERDecodeError();
00318 m_level++;
00319 m_state = IDENTIFIER;
00320 break;
00321 }
00322 m_state = BODY;
00323 }
00324 case BODY:
00325 m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining);
00326
00327 if (m_lengthRemaining == 0)
00328 m_state = IDENTIFIER;
00329 }
00330
00331 if (m_state == IDENTIFIER && m_level == 0)
00332 {
00333
00334 ++m_nCurrentObject;
00335
00336 if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT)
00337 AttachedTransformation()->MessageEnd();
00338
00339 if (m_nCurrentObject == m_nObjects)
00340 {
00341 if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS)
00342 AttachedTransformation()->MessageEnd();
00343
00344 if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS)
00345 AttachedTransformation()->MessageSeriesEnd();
00346
00347 m_queue.TransferAllTo(*AttachedTransformation());
00348 return;
00349 }
00350 }
00351 }
00352 }
00353
00354 BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
00355 : m_inQueue(inQueue), m_finished(false)
00356 {
00357 byte b;
00358 if (!m_inQueue.Get(b) || b != asnTag)
00359 BERDecodeError();
00360
00361 m_definiteLength = BERLengthDecode(m_inQueue, m_length);
00362 }
00363
00364 BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
00365 : m_inQueue(inQueue), m_finished(false)
00366 {
00367 byte b;
00368 if (!m_inQueue.Get(b) || b != asnTag)
00369 BERDecodeError();
00370
00371 m_definiteLength = BERLengthDecode(m_inQueue, m_length);
00372 if (!m_definiteLength && !(asnTag & CONSTRUCTED))
00373 BERDecodeError();
00374 }
00375
00376 BERGeneralDecoder::~BERGeneralDecoder()
00377 {
00378 try
00379 {
00380 if (!m_finished)
00381 MessageEnd();
00382 }
00383 catch (...)
00384 {
00385 }
00386 }
00387
00388 bool BERGeneralDecoder::EndReached() const
00389 {
00390 if (m_definiteLength)
00391 return m_length == 0;
00392 else
00393 {
00394 word16 i;
00395 return (m_inQueue.PeekWord16(i)==2 && i==0);
00396 }
00397 }
00398
00399 byte BERGeneralDecoder::PeekByte() const
00400 {
00401 byte b;
00402 if (!Peek(b))
00403 BERDecodeError();
00404 return b;
00405 }
00406
00407 void BERGeneralDecoder::CheckByte(byte check)
00408 {
00409 byte b;
00410 if (!Get(b) || b != check)
00411 BERDecodeError();
00412 }
00413
00414 void BERGeneralDecoder::MessageEnd()
00415 {
00416 m_finished = true;
00417 if (m_definiteLength)
00418 {
00419 if (m_length != 0)
00420 BERDecodeError();
00421 }
00422 else
00423 {
00424 word16 i;
00425 if (m_inQueue.GetWord16(i) != 2 || i != 0)
00426 BERDecodeError();
00427 }
00428 }
00429
00430 unsigned int BERGeneralDecoder::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
00431 {
00432 if (m_definiteLength && transferBytes > m_length)
00433 transferBytes = m_length;
00434 unsigned int blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking);
00435 ReduceLength(transferBytes);
00436 return blockedBytes;
00437 }
00438
00439 unsigned int BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
00440 {
00441 if (m_definiteLength)
00442 end = STDMIN((unsigned long)m_length, end);
00443 return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking);
00444 }
00445
00446 unsigned int BERGeneralDecoder::ReduceLength(unsigned int delta)
00447 {
00448 if (m_definiteLength)
00449 {
00450 if (m_length < delta)
00451 BERDecodeError();
00452 m_length -= delta;
00453 }
00454 return delta;
00455 }
00456
00457 DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
00458 : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
00459 {
00460 }
00461
00462 DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
00463 : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag)
00464 {
00465 }
00466
00467 DERGeneralEncoder::~DERGeneralEncoder()
00468 {
00469 try
00470 {
00471 if (!m_finished)
00472 MessageEnd();
00473 }
00474 catch (...)
00475 {
00476 }
00477 }
00478
00479 void DERGeneralEncoder::MessageEnd()
00480 {
00481 m_finished = true;
00482 unsigned int length = (unsigned int)CurrentSize();
00483 m_outQueue.Put(m_asnTag);
00484 DERLengthEncode(m_outQueue, length);
00485 TransferTo(m_outQueue);
00486 }
00487
00488
00489
00490 void X509PublicKey::BERDecode(BufferedTransformation &bt)
00491 {
00492 BERSequenceDecoder subjectPublicKeyInfo(bt);
00493 BERSequenceDecoder algorithm(subjectPublicKeyInfo);
00494 GetAlgorithmID().BERDecodeAndCheck(algorithm);
00495 bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm);
00496 algorithm.MessageEnd();
00497
00498 BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
00499 subjectPublicKey.CheckByte(0);
00500 BERDecodeKey2(subjectPublicKey, parametersPresent, subjectPublicKey.RemainingLength());
00501 subjectPublicKey.MessageEnd();
00502 subjectPublicKeyInfo.MessageEnd();
00503 }
00504
00505 void X509PublicKey::DEREncode(BufferedTransformation &bt) const
00506 {
00507 DERSequenceEncoder subjectPublicKeyInfo(bt);
00508
00509 DERSequenceEncoder algorithm(subjectPublicKeyInfo);
00510 GetAlgorithmID().DEREncode(algorithm);
00511 DEREncodeAlgorithmParameters(algorithm);
00512 algorithm.MessageEnd();
00513
00514 DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
00515 subjectPublicKey.Put(0);
00516 DEREncodeKey(subjectPublicKey);
00517 subjectPublicKey.MessageEnd();
00518
00519 subjectPublicKeyInfo.MessageEnd();
00520 }
00521
00522 void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt)
00523 {
00524 BERSequenceDecoder privateKeyInfo(bt);
00525 word32 version;
00526 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0);
00527
00528 BERSequenceDecoder algorithm(privateKeyInfo);
00529 GetAlgorithmID().BERDecodeAndCheck(algorithm);
00530 bool parametersPresent = BERDecodeAlgorithmParameters(algorithm);
00531 algorithm.MessageEnd();
00532
00533 BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING);
00534 BERDecodeKey2(octetString, parametersPresent, privateKeyInfo.RemainingLength());
00535 octetString.MessageEnd();
00536
00537 BERDecodeOptionalAttributes(privateKeyInfo);
00538 privateKeyInfo.MessageEnd();
00539 }
00540
00541 void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const
00542 {
00543 DERSequenceEncoder privateKeyInfo(bt);
00544 DEREncodeUnsigned<word32>(privateKeyInfo, 0);
00545
00546 DERSequenceEncoder algorithm(privateKeyInfo);
00547 GetAlgorithmID().DEREncode(algorithm);
00548 DEREncodeAlgorithmParameters(algorithm);
00549 algorithm.MessageEnd();
00550
00551 DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING);
00552 DEREncodeKey(octetString);
00553 octetString.MessageEnd();
00554
00555 DEREncodeOptionalAttributes(privateKeyInfo);
00556 privateKeyInfo.MessageEnd();
00557 }
00558
00559 NAMESPACE_END
00560
00561 #endif